packages feed

cleveland 0.2.1 → 0.3.0

raw patch · 46 files changed

+1382/−593 lines, 46 filesdep +dependent-mapdep +somedep −bytestringdep −nameddep −safe-exceptionsPVP ok

version bump matches the API change (PVP)

Dependencies added: dependent-map, some

Dependencies removed: bytestring, named, safe-exceptions

API changes (from Hackage documentation)

- Test.Cleveland: data MorleyClientEnv' (m :: Type -> Type)
- Test.Cleveland: type MorleyClientEnv = MorleyClientEnv' MorleyClientM
- Test.Cleveland.Internal.Abstract: FailedInBranch :: ScenarioBranchName -> SomeException -> FailedInBranch
- Test.Cleveland.Internal.Abstract: ScenarioBranchName :: [Text] -> ScenarioBranchName
- Test.Cleveland.Internal.Abstract: [cmiRegisterDelegate] :: ClevelandMiscImpl m -> HasCallStack => ImplicitAddress -> m ()
- Test.Cleveland.Internal.Abstract: [unTestBranch] :: ScenarioBranchName -> [Text]
- Test.Cleveland.Internal.Abstract: data FailedInBranch
- Test.Cleveland.Internal.Abstract: instance (TypeError ...) => GHC.Base.Monad Test.Cleveland.Internal.Abstract.ClevelandOpsBatch
- Test.Cleveland.Internal.Abstract: instance Formatting.Buildable.Buildable Test.Cleveland.Internal.Abstract.FailedInBranch
- Test.Cleveland.Internal.Abstract: instance Formatting.Buildable.Buildable Test.Cleveland.Internal.Abstract.ScenarioBranchName
- Test.Cleveland.Internal.Abstract: instance GHC.Classes.Eq Test.Cleveland.Internal.Abstract.ScenarioBranchName
- Test.Cleveland.Internal.Abstract: instance GHC.Exception.Type.Exception Test.Cleveland.Internal.Abstract.FailedInBranch
- Test.Cleveland.Internal.Abstract: instance GHC.Show.Show Test.Cleveland.Internal.Abstract.FailedInBranch
- Test.Cleveland.Internal.Abstract: instance GHC.Show.Show Test.Cleveland.Internal.Abstract.ScenarioBranchName
- Test.Cleveland.Internal.Abstract: newtype ScenarioBranchName
- Test.Cleveland.Internal.Actions.Originate: HasBalance :: HasBalance
- Test.Cleveland.Internal.Actions.Originate: NoBalance :: HasBalance
- Test.Cleveland.Internal.Actions.Originate: data HasBalance
- Test.Cleveland.Internal.Actions.Originate: instance (Test.Cleveland.Internal.Actions.Originate.ContractClass ct, (TypeError ...)) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal large (x -> r)
- Test.Cleveland.Internal.Actions.Originate: instance (Test.Cleveland.Internal.Actions.Originate.ModifyOriginationData (Test.Cleveland.Internal.Actions.Originate.ContractOriginateData ct), Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct 'Test.Cleveland.Internal.Actions.Originate.HasBalance isLarge r, Test.Cleveland.Internal.Actions.Originate.CheckDupBalance bal, bal GHC.Types.~ 'Test.Cleveland.Internal.Actions.Originate.NoBalance) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal isLarge (Morley.Tezos.Core.Mutez -> r)
- Test.Cleveland.Internal.Actions.Originate: instance (Test.Cleveland.Internal.Actions.Originate.ModifyOriginationData (Test.Cleveland.Internal.Actions.Originate.ContractOriginateData ct), Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal 'Test.Cleveland.Internal.Abstract.IsLarge r, Test.Cleveland.Internal.Actions.Originate.CheckDupLarge isLarge, isLarge GHC.Types.~ 'Test.Cleveland.Internal.Abstract.NotLarge) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal isLarge (Test.Cleveland.Internal.Actions.Originate.Large -> r)
- Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.OFConstraint ct large (Control.Monad.Trans.Reader.ReaderT cap base a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal large (Control.Monad.Trans.Reader.ReaderT cap base a)
- Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.OFConstraint ct large (Test.Cleveland.Internal.Abstract.ClevelandOpsBatch a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal large (Test.Cleveland.Internal.Abstract.ClevelandOpsBatch a)
- Test.Cleveland.Internal.Actions.Originate: instance forall k (m :: k -> *). (forall ct (bal :: Test.Cleveland.Internal.Actions.Originate.HasBalance) (large :: Test.Cleveland.Internal.Abstract.LargeOrigination) (a :: k). Test.Cleveland.Internal.Actions.Originate.OFConstraint ct large (m a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct bal large (m a)) => Test.Cleveland.Internal.Actions.Originate.MonadOriginate m
- Test.Cleveland.Internal.Actions.Originate: type OFConstraint ct large r = (ContractClass ct, Originator (ContractOriginateData ct large) r)
- Test.Cleveland.Internal.Actions.Transfer: instance (TypeError ...) => Test.Cleveland.Internal.Actions.Transfer.TransferFunc mode emit am (x -> r)
- Test.Cleveland.Internal.Exceptions: [WithCallStack] :: CallStack -> SomeException -> WithCallStack
- Test.Cleveland.Internal.Exceptions: catchWithCallStack :: forall e a m. (Exception e, MonadCatch m) => m a -> (Maybe CallStack -> e -> m a) -> m a
- Test.Cleveland.Internal.Exceptions: data WithCallStack
- Test.Cleveland.Internal.Exceptions: instance Formatting.Buildable.Buildable Test.Cleveland.Internal.Exceptions.WithCallStack
- Test.Cleveland.Internal.Exceptions: instance GHC.Exception.Type.Exception Test.Cleveland.Internal.Exceptions.WithCallStack
- Test.Cleveland.Internal.Exceptions: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.WithCallStack
- Test.Cleveland.Internal.Exceptions: throwWithCallStack :: forall e a m. (MonadThrow m, Exception e) => CallStack -> e -> m a
- Test.Cleveland.Internal.Exceptions: tryWithCallStack :: forall e a m. (MonadCatch m, Exception e) => m a -> m (Either (Maybe CallStack, e) a)
- Test.Cleveland.Internal.Pure: emptyScenarioBranch :: ScenarioBranchName
- Test.Cleveland.Internal.Pure: failedInsideBranch :: Text -> SomeException -> FailedInBranch
- Test.Cleveland.Lorentz: chNiceParameterEvi :: forall param st vd. ContractHandle param st vd -> Dict (ParameterScope $ ToT st)
- Test.Cleveland.Lorentz: chNiceStorageEvi :: forall param st vd. ContractHandle param st vd -> Dict (StorageScope $ ToT st)
- Test.Cleveland.Lorentz.Types: chNiceParameterEvi :: forall param st vd. ContractHandle param st vd -> Dict (ParameterScope $ ToT st)
- Test.Cleveland.Lorentz.Types: chNiceStorageEvi :: forall param st vd. ContractHandle param st vd -> Dict (StorageScope $ ToT st)
+ Test.Cleveland: [neVerbosity] :: NetworkEnv -> Word
+ Test.Cleveland: callView :: forall name arg ret cp st vd m caps. (MonadCleveland caps m, HasView vd name arg ret, NiceParameter arg, NiceViewable ret, NiceStorage ret, NiceParameter cp, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret)) => ContractHandle cp st vd -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland: data MorleyClientEnv
+ Test.Cleveland: setDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddress -> Maybe KeyHash -> m ()
+ Test.Cleveland: unsafeCallView :: forall ret arg name addr m caps. (MonadCleveland caps m, NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret), ToContractAddress addr) => addr -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland.Internal.Abstract: [neVerbosity] :: NetworkEnv -> Word
+ Test.Cleveland.Internal.Abstract: [odDelegate] :: OriginateData param st vd (large :: LargeOrigination) -> Maybe KeyHash
+ Test.Cleveland.Internal.Abstract: [todDelegate] :: TypedOriginateData cp st vd (large :: LargeOrigination) -> Maybe KeyHash
+ Test.Cleveland.Internal.Abstract: [uodDelegate] :: UntypedOriginateData (large :: LargeOrigination) -> Maybe KeyHash
+ Test.Cleveland.Internal.Abstract: instance (Data.Constraint.Bottom, (TypeError ...)) => GHC.Base.Monad Test.Cleveland.Internal.Abstract.ClevelandOpsBatch
+ Test.Cleveland.Internal.Abstract: instance Lorentz.Address.ToAddress Test.Cleveland.Internal.Abstract.AddressAndAlias
+ Test.Cleveland.Internal.Abstract: neVerbosityL :: Lens' NetworkEnv Word
+ Test.Cleveland.Internal.Actions: callView :: forall name arg ret cp st vd m caps. (MonadCleveland caps m, HasView vd name arg ret, NiceParameter arg, NiceViewable ret, NiceStorage ret, NiceParameter cp, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret)) => ContractHandle cp st vd -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland.Internal.Actions: setDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddress -> Maybe KeyHash -> m ()
+ Test.Cleveland.Internal.Actions: unsafeCallView :: forall ret arg name addr m caps. (MonadCleveland caps m, NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret), ToContractAddress addr) => addr -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland.Internal.Actions.Misc: setDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddress -> Maybe KeyHash -> m ()
+ Test.Cleveland.Internal.Actions.Originate: PropBalance :: Prop
+ Test.Cleveland.Internal.Actions.Originate: PropDelegate :: Prop
+ Test.Cleveland.Internal.Actions.Originate: PropLarge :: Prop
+ Test.Cleveland.Internal.Actions.Originate: data Prop
+ Test.Cleveland.Internal.Actions.Originate: instance ((TypeError ...), Data.Constraint.Bottom) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (x -> r)
+ Test.Cleveland.Internal.Actions.Originate: instance (Test.Cleveland.Internal.Actions.MonadOps.MonadOpsInternal m, forall ct (props :: [Test.Cleveland.Internal.Actions.Originate.Prop]) a. Test.Cleveland.Internal.Actions.Originate.Originator (Test.Cleveland.Internal.Actions.Originate.ContractOriginateData ct (Test.Cleveland.Internal.Actions.Originate.GetLarge props)) (m a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (m a)) => Test.Cleveland.Internal.Actions.Originate.MonadOriginate m
+ Test.Cleveland.Internal.Actions.Originate: instance (Test.Cleveland.Internal.Actions.Originate.OFConstraints ct 'Test.Cleveland.Internal.Actions.Originate.PropLarge props r, Test.Cleveland.Internal.Actions.Originate.GetLarge props GHC.Types.~ 'Test.Cleveland.Internal.Abstract.NotLarge) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (Test.Cleveland.Internal.Actions.Originate.Large -> r)
+ Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.OFConstraints ct 'Test.Cleveland.Internal.Actions.Originate.PropBalance props r => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (Morley.Tezos.Core.Mutez -> r)
+ Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.OFConstraints ct 'Test.Cleveland.Internal.Actions.Originate.PropDelegate props r => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (Morley.Tezos.Crypto.KeyHash -> r)
+ Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.Originator (Test.Cleveland.Internal.Actions.Originate.ContractOriginateData ct (Test.Cleveland.Internal.Actions.Originate.GetLarge props)) (Control.Monad.Trans.Reader.ReaderT cap base a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (Control.Monad.Trans.Reader.ReaderT cap base a)
+ Test.Cleveland.Internal.Actions.Originate: instance Test.Cleveland.Internal.Actions.Originate.Originator (Test.Cleveland.Internal.Actions.Originate.ContractOriginateData ct (Test.Cleveland.Internal.Actions.Originate.GetLarge props)) (Test.Cleveland.Internal.Abstract.ClevelandOpsBatch a) => Test.Cleveland.Internal.Actions.Originate.OriginateFunc ct props (Test.Cleveland.Internal.Abstract.ClevelandOpsBatch a)
+ Test.Cleveland.Internal.Actions.Originate: setDelegate :: ModifyOriginationData od => KeyHash -> od large -> od large
+ Test.Cleveland.Internal.Actions.Originate: type OFConstraints ct prop props r = (ModifyOriginationData (ContractOriginateData ct), OriginateFunc ct (prop : props) r, CheckDupProp prop props)
+ Test.Cleveland.Internal.Actions.Transfer: instance (Data.Constraint.Bottom, (TypeError ...)) => Test.Cleveland.Internal.Actions.Transfer.TransferFunc mode emit am (x -> r)
+ Test.Cleveland.Internal.Actions.View: callView :: forall name arg ret cp st vd m caps. (MonadCleveland caps m, HasView vd name arg ret, NiceParameter arg, NiceViewable ret, NiceStorage ret, NiceParameter cp, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret)) => ContractHandle cp st vd -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland.Internal.Actions.View: runnerContract :: forall name arg ret. (NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name) => ContractAddress -> Contract arg (Maybe ret) ()
+ Test.Cleveland.Internal.Actions.View: unsafeCallView :: forall ret arg name addr m caps. (MonadCleveland caps m, NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name, HasRPCRepr ret, IsoValue (AsRPC ret), ToContractAddress addr) => addr -> Label name -> arg -> m (AsRPC ret)
+ Test.Cleveland.Internal.Exceptions: CallStackAnnotation :: CallStack -> CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions: ErrorsClarification :: [Builder] -> ErrorsClarification
+ Test.Cleveland.Internal.Exceptions: ScenarioBranchName :: [Text] -> ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions: [unCallStackAnnotation] :: CallStackAnnotation -> CallStack
+ Test.Cleveland.Internal.Exceptions: [unTestBranch] :: ScenarioBranchName -> [Text]
+ Test.Cleveland.Internal.Exceptions: annotateExceptions :: forall m a ann. (MonadCatch m, Semigroup ann, ExceptionAnnotation ann) => ann -> m a -> m a
+ Test.Cleveland.Internal.Exceptions: annotationPriority :: ExceptionAnnotation ann => Int
+ Test.Cleveland.Internal.Exceptions: class (Show ann, Typeable ann) => ExceptionAnnotation ann
+ Test.Cleveland.Internal.Exceptions: displayAnnotation :: ExceptionAnnotation ann => ann -> Builder -> Builder
+ Test.Cleveland.Internal.Exceptions: fromPossiblyAnnotatedException :: Exception e => SomeException -> Maybe e
+ Test.Cleveland.Internal.Exceptions: insertAnnEx :: (Semigroup ann, ExceptionAnnotation ann) => ann -> SomeException -> SomeException
+ Test.Cleveland.Internal.Exceptions: lookupAnnEx :: forall ann. ExceptionAnnotation ann => SomeException -> Maybe ann
+ Test.Cleveland.Internal.Exceptions: newtype CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions: newtype ErrorsClarification
+ Test.Cleveland.Internal.Exceptions: newtype ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions: removeAnnEx :: forall ann. ExceptionAnnotation ann => SomeException -> SomeException
+ Test.Cleveland.Internal.Exceptions.Annotated: AnnotatedException :: AnnotationMap -> SomeException -> AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: AnnotationMap :: DMap Key Identity -> AnnotationMap
+ Test.Cleveland.Internal.Exceptions.Annotated: [Key] :: ExceptionAnnotation a => Key a
+ Test.Cleveland.Internal.Exceptions.Annotated: [unAnnotationMap] :: AnnotationMap -> DMap Key Identity
+ Test.Cleveland.Internal.Exceptions.Annotated: annotateExceptions :: forall m a ann. (MonadCatch m, Semigroup ann, ExceptionAnnotation ann) => ann -> m a -> m a
+ Test.Cleveland.Internal.Exceptions.Annotated: annotationPriority :: ExceptionAnnotation ann => Int
+ Test.Cleveland.Internal.Exceptions.Annotated: class (Show ann, Typeable ann) => ExceptionAnnotation ann
+ Test.Cleveland.Internal.Exceptions.Annotated: data AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: data Key ann
+ Test.Cleveland.Internal.Exceptions.Annotated: displayAnnotation :: ExceptionAnnotation ann => ann -> Builder -> Builder
+ Test.Cleveland.Internal.Exceptions.Annotated: fromPossiblyAnnotatedException :: Exception e => SomeException -> Maybe e
+ Test.Cleveland.Internal.Exceptions.Annotated: insertAnn :: (Semigroup t, ExceptionAnnotation t) => t -> AnnotationMap -> AnnotationMap
+ Test.Cleveland.Internal.Exceptions.Annotated: insertAnnEx :: (Semigroup ann, ExceptionAnnotation ann) => ann -> SomeException -> SomeException
+ Test.Cleveland.Internal.Exceptions.Annotated: insertAnnEx' :: (Semigroup ann, ExceptionAnnotation ann) => ann -> AnnotatedException -> AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: instance Data.GADT.Internal.GCompare Test.Cleveland.Internal.Exceptions.Annotated.Key
+ Test.Cleveland.Internal.Exceptions.Annotated: instance Data.GADT.Internal.GEq Test.Cleveland.Internal.Exceptions.Annotated.Key
+ Test.Cleveland.Internal.Exceptions.Annotated: instance GHC.Exception.Type.Exception Test.Cleveland.Internal.Exceptions.Annotated.AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.Annotated.AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.Annotated.AnnotationMap
+ Test.Cleveland.Internal.Exceptions.Annotated: lookupAnn :: ExceptionAnnotation t => AnnotationMap -> Maybe t
+ Test.Cleveland.Internal.Exceptions.Annotated: lookupAnnEx :: forall ann. ExceptionAnnotation ann => SomeException -> Maybe ann
+ Test.Cleveland.Internal.Exceptions.Annotated: lookupAnnEx' :: forall ann. ExceptionAnnotation ann => AnnotatedException -> Maybe ann
+ Test.Cleveland.Internal.Exceptions.Annotated: newtype AnnotationMap
+ Test.Cleveland.Internal.Exceptions.Annotated: printAnnotations :: Buildable a => AnnotationMap -> a -> Builder
+ Test.Cleveland.Internal.Exceptions.Annotated: removeAnn :: forall t. ExceptionAnnotation t => AnnotationMap -> AnnotationMap
+ Test.Cleveland.Internal.Exceptions.Annotated: removeAnnEx :: forall ann. ExceptionAnnotation ann => SomeException -> SomeException
+ Test.Cleveland.Internal.Exceptions.Annotated: removeAnnEx' :: forall ann. ExceptionAnnotation ann => AnnotatedException -> AnnotatedException
+ Test.Cleveland.Internal.Exceptions.Annotated: singletonAnn :: ExceptionAnnotation t => t -> AnnotationMap
+ Test.Cleveland.Internal.Exceptions.CallStack: CallStackAnnotation :: CallStack -> CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions.CallStack: [unCallStackAnnotation] :: CallStackAnnotation -> CallStack
+ Test.Cleveland.Internal.Exceptions.CallStack: addCallStack :: (MonadCatch m, HasCallStack) => m a -> m a
+ Test.Cleveland.Internal.Exceptions.CallStack: instance GHC.Base.Semigroup Test.Cleveland.Internal.Exceptions.CallStack.CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions.CallStack: instance GHC.Classes.Eq Test.Cleveland.Internal.Exceptions.CallStack.OrdSrcLoc
+ Test.Cleveland.Internal.Exceptions.CallStack: instance GHC.Classes.Ord Test.Cleveland.Internal.Exceptions.CallStack.OrdSrcLoc
+ Test.Cleveland.Internal.Exceptions.CallStack: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.CallStack.CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions.CallStack: instance Test.Cleveland.Internal.Exceptions.Annotated.ExceptionAnnotation Test.Cleveland.Internal.Exceptions.CallStack.CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions.CallStack: newtype CallStackAnnotation
+ Test.Cleveland.Internal.Exceptions.ErrorsClarification: ErrorsClarification :: [Builder] -> ErrorsClarification
+ Test.Cleveland.Internal.Exceptions.ErrorsClarification: instance GHC.Base.Semigroup Test.Cleveland.Internal.Exceptions.ErrorsClarification.ErrorsClarification
+ Test.Cleveland.Internal.Exceptions.ErrorsClarification: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.ErrorsClarification.ErrorsClarification
+ Test.Cleveland.Internal.Exceptions.ErrorsClarification: instance Test.Cleveland.Internal.Exceptions.Annotated.ExceptionAnnotation Test.Cleveland.Internal.Exceptions.ErrorsClarification.ErrorsClarification
+ Test.Cleveland.Internal.Exceptions.ErrorsClarification: newtype ErrorsClarification
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: ScenarioBranchName :: [Text] -> ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: [unTestBranch] :: ScenarioBranchName -> [Text]
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: instance Formatting.Buildable.Buildable Test.Cleveland.Internal.Exceptions.ScenarioBranchName.ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: instance GHC.Base.Semigroup Test.Cleveland.Internal.Exceptions.ScenarioBranchName.ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: instance GHC.Classes.Eq Test.Cleveland.Internal.Exceptions.ScenarioBranchName.ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: instance GHC.Show.Show Test.Cleveland.Internal.Exceptions.ScenarioBranchName.ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: instance Test.Cleveland.Internal.Exceptions.Annotated.ExceptionAnnotation Test.Cleveland.Internal.Exceptions.ScenarioBranchName.ScenarioBranchName
+ Test.Cleveland.Internal.Exceptions.ScenarioBranchName: newtype ScenarioBranchName
- Test.Cleveland: MorleyClientEnv :: TezosClientEnv -> ClientLogAction m -> Maybe SecretKey -> ClientEnv -> MorleyClientEnv' (m :: Type -> Type)
+ Test.Cleveland: MorleyClientEnv :: TezosClientEnv -> ClientLogAction MorleyClientM -> Maybe SecretKey -> ClientEnv -> MorleyClientEnv
- Test.Cleveland: NetworkEnv :: MorleyClientEnv -> Maybe SecretKey -> ImplicitAlias -> Bool -> NetworkEnv
+ Test.Cleveland: NetworkEnv :: MorleyClientEnv -> Maybe SecretKey -> ImplicitAlias -> Bool -> Word -> NetworkEnv
- Test.Cleveland: [mceClientEnv] :: MorleyClientEnv' (m :: Type -> Type) -> ClientEnv
+ Test.Cleveland: [mceClientEnv] :: MorleyClientEnv -> ClientEnv
- Test.Cleveland: [mceLogAction] :: MorleyClientEnv' (m :: Type -> Type) -> ClientLogAction m
+ Test.Cleveland: [mceLogAction] :: MorleyClientEnv -> ClientLogAction MorleyClientM
- Test.Cleveland: [mceSecretKey] :: MorleyClientEnv' (m :: Type -> Type) -> Maybe SecretKey
+ Test.Cleveland: [mceSecretKey] :: MorleyClientEnv -> Maybe SecretKey
- Test.Cleveland: [mceTezosClient] :: MorleyClientEnv' (m :: Type -> Type) -> TezosClientEnv
+ Test.Cleveland: [mceTezosClient] :: MorleyClientEnv -> TezosClientEnv
- Test.Cleveland: getDelegate :: (HasCallStack, MonadCleveland caps m, ToContractAddress addr) => addr -> m (Maybe KeyHash)
+ Test.Cleveland: getDelegate :: (HasCallStack, MonadCleveland caps m, ToL1Address addr) => addr -> m (Maybe KeyHash)
- Test.Cleveland: originate :: forall contract r. (HasCallStack, OriginateFunc contract 'NoBalance 'NotLarge r) => ContractAlias -> ContractStorage contract -> contract -> r
+ Test.Cleveland: originate :: forall contract r. (HasCallStack, ContractClass contract, OriginateFunc contract '[] r) => ContractAlias -> ContractStorage contract -> contract -> r
- Test.Cleveland.Internal.Abstract: AddressAndAlias :: Address -> Maybe ContractAlias -> AddressAndAlias
+ Test.Cleveland.Internal.Abstract: AddressAndAlias :: KindedAddress kind -> Maybe (Alias kind) -> AddressAndAlias
- Test.Cleveland.Internal.Abstract: ClevelandMiscImpl :: (forall res. HasCallStack => IO res -> m res) -> (forall kind. HasCallStack => Alias kind -> m (KindedAddress kind)) -> (HasCallStack => SpecificOrDefaultAlias -> m ImplicitAddress) -> (HasCallStack => SpecificOrDefaultAlias -> m ImplicitAddress) -> (HasCallStack => ByteString -> ImplicitAddress -> m Signature) -> (HasCallStack => Sender -> UntypedOriginateData 'IsLarge -> m ContractAddress) -> (HasCallStack => Text -> m ()) -> (HasCallStack => L1Address -> m Mutez) -> (HasCallStack => ContractAddress -> m SomeAnnotatedValue) -> (forall k v. (HasCallStack, NiceComparable k, NicePackedValue k, NiceUnpackedValue v) => BigMapId k v -> k -> m (Maybe v)) -> (forall k v. (HasCallStack, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m (Maybe [v])) -> (HasCallStack => ImplicitAddress -> m PublicKey) -> (HasCallStack => ContractAddress -> m (Maybe KeyHash)) -> (HasCallStack => ImplicitAddress -> m ()) -> (HasCallStack => m ChainId) -> (forall unit. (HasCallStack, KnownDivRat unit Second) => Time unit -> m ()) -> (HasCallStack => (Natural -> Natural) -> m ()) -> (HasCallStack => m Timestamp) -> (HasCallStack => m Natural) -> (forall a. HasCallStack => Builder -> m a) -> (forall a. HasCallStack => SomeException -> m a) -> (HasCallStack => m (Time Second)) -> (forall a e. (Exception e, HasCallStack) => m a -> m (Either e a)) -> (ImplicitAddress -> m ()) -> m (Either (EmulatedImpl m) NetworkEnv) -> (forall cp st vd. (HasCallStack, HasRPCRepr st, IsoValue (AsRPC st)) => Sender -> RunCode cp st vd -> m (AsRPC st)) -> ClevelandMiscImpl m
+ Test.Cleveland.Internal.Abstract: ClevelandMiscImpl :: (forall res. HasCallStack => IO res -> m res) -> (forall kind. HasCallStack => Alias kind -> m (KindedAddress kind)) -> (HasCallStack => SpecificOrDefaultAlias -> m ImplicitAddress) -> (HasCallStack => SpecificOrDefaultAlias -> m ImplicitAddress) -> (HasCallStack => ByteString -> ImplicitAddress -> m Signature) -> (HasCallStack => Sender -> UntypedOriginateData 'IsLarge -> m ContractAddress) -> (HasCallStack => Text -> m ()) -> (HasCallStack => L1Address -> m Mutez) -> (HasCallStack => ContractAddress -> m SomeAnnotatedValue) -> (forall k v. (HasCallStack, NiceComparable k, NicePackedValue k, NiceUnpackedValue v) => BigMapId k v -> k -> m (Maybe v)) -> (forall k v. (HasCallStack, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m (Maybe [v])) -> (HasCallStack => ImplicitAddress -> m PublicKey) -> (HasCallStack => L1Address -> m (Maybe KeyHash)) -> (HasCallStack => m ChainId) -> (forall unit. (HasCallStack, KnownDivRat unit Second) => Time unit -> m ()) -> (HasCallStack => (Natural -> Natural) -> m ()) -> (HasCallStack => m Timestamp) -> (HasCallStack => m Natural) -> (forall a. HasCallStack => Builder -> m a) -> (forall a. HasCallStack => SomeException -> m a) -> (HasCallStack => m (Time Second)) -> (forall a e. (Exception e, HasCallStack) => m a -> m (Either e a)) -> (ImplicitAddress -> m ()) -> m (Either (EmulatedImpl m) NetworkEnv) -> (forall cp st vd. (HasCallStack, HasRPCRepr st, IsoValue (AsRPC st)) => Sender -> RunCode cp st vd -> m (AsRPC st)) -> ClevelandMiscImpl m
- Test.Cleveland.Internal.Abstract: NetworkEnv :: MorleyClientEnv -> Maybe SecretKey -> ImplicitAlias -> Bool -> NetworkEnv
+ Test.Cleveland.Internal.Abstract: NetworkEnv :: MorleyClientEnv -> Maybe SecretKey -> ImplicitAlias -> Bool -> Word -> NetworkEnv
- Test.Cleveland.Internal.Abstract: OriginateData :: ContractAlias -> Mutez -> st -> Contract param st vd -> OriginateData param st vd (large :: LargeOrigination)
+ Test.Cleveland.Internal.Abstract: OriginateData :: ContractAlias -> Mutez -> st -> Contract param st vd -> Maybe KeyHash -> OriginateData param st vd (large :: LargeOrigination)
- Test.Cleveland.Internal.Abstract: TypedOriginateData :: ContractAlias -> Mutez -> st -> Contract (ToT cp) (ToT st) -> TypedOriginateData cp st vd (large :: LargeOrigination)
+ Test.Cleveland.Internal.Abstract: TypedOriginateData :: ContractAlias -> Mutez -> st -> Contract (ToT cp) (ToT st) -> Maybe KeyHash -> TypedOriginateData cp st vd (large :: LargeOrigination)
- Test.Cleveland.Internal.Abstract: UntypedOriginateData :: ContractAlias -> Mutez -> Value -> Contract -> UntypedOriginateData (large :: LargeOrigination)
+ Test.Cleveland.Internal.Abstract: UntypedOriginateData :: ContractAlias -> Mutez -> Value -> Contract -> Maybe KeyHash -> UntypedOriginateData (large :: LargeOrigination)
- Test.Cleveland.Internal.Abstract: [cmiGetDelegate] :: ClevelandMiscImpl m -> HasCallStack => ContractAddress -> m (Maybe KeyHash)
+ Test.Cleveland.Internal.Abstract: [cmiGetDelegate] :: ClevelandMiscImpl m -> HasCallStack => L1Address -> m (Maybe KeyHash)
- Test.Cleveland.Internal.Actions: class (forall ct bal large a. OFConstraint ct large (m a) => OriginateFunc ct bal large (m a)) => MonadOriginate m
+ Test.Cleveland.Internal.Actions: class (MonadOpsInternal m, forall ct props a. Originator (ContractOriginateData ct (GetLarge props)) (m a) => OriginateFunc ct props (m a)) => MonadOriginate m
- Test.Cleveland.Internal.Actions: getDelegate :: (HasCallStack, MonadCleveland caps m, ToContractAddress addr) => addr -> m (Maybe KeyHash)
+ Test.Cleveland.Internal.Actions: getDelegate :: (HasCallStack, MonadCleveland caps m, ToL1Address addr) => addr -> m (Maybe KeyHash)
- Test.Cleveland.Internal.Actions: originate :: forall contract r. (HasCallStack, OriginateFunc contract 'NoBalance 'NotLarge r) => ContractAlias -> ContractStorage contract -> contract -> r
+ Test.Cleveland.Internal.Actions: originate :: forall contract r. (HasCallStack, ContractClass contract, OriginateFunc contract '[] r) => ContractAlias -> ContractStorage contract -> contract -> r
- Test.Cleveland.Internal.Actions.Misc: getDelegate :: (HasCallStack, MonadCleveland caps m, ToContractAddress addr) => addr -> m (Maybe KeyHash)
+ Test.Cleveland.Internal.Actions.Misc: getDelegate :: (HasCallStack, MonadCleveland caps m, ToL1Address addr) => addr -> m (Maybe KeyHash)
- Test.Cleveland.Internal.Actions.Originate: class (forall ct bal large a. OFConstraint ct large (m a) => OriginateFunc ct bal large (m a)) => MonadOriginate m
+ Test.Cleveland.Internal.Actions.Originate: class (MonadOpsInternal m, forall ct props a. Originator (ContractOriginateData ct (GetLarge props)) (m a) => OriginateFunc ct props (m a)) => MonadOriginate m
- Test.Cleveland.Internal.Actions.Originate: class ContractClass contract => OriginateFunc contract (bal :: HasBalance) isLarge r
+ Test.Cleveland.Internal.Actions.Originate: class OriginateFunc contract (props :: [Prop]) r
- Test.Cleveland.Internal.Actions.Originate: originate :: forall contract r. (HasCallStack, OriginateFunc contract 'NoBalance 'NotLarge r) => ContractAlias -> ContractStorage contract -> contract -> r
+ Test.Cleveland.Internal.Actions.Originate: originate :: forall contract r. (HasCallStack, ContractClass contract, OriginateFunc contract '[] r) => ContractAlias -> ContractStorage contract -> contract -> r
- Test.Cleveland.Internal.Actions.Originate: originate'r :: (OriginateFunc contract bal isLarge r, HasCallStack, Originator (ContractOriginateData contract isLarge) r) => ContractOriginateData contract isLarge -> r
+ Test.Cleveland.Internal.Actions.Originate: originate'r :: (OriginateFunc contract props r, HasCallStack, Originator (ContractOriginateData contract (GetLarge props)) r) => ContractOriginateData contract (GetLarge props) -> r
- Test.Cleveland.Internal.Exceptions: addCallStack :: forall m a. (HasCallStack, MonadCatch m) => m a -> m a
+ Test.Cleveland.Internal.Exceptions: addCallStack :: (MonadCatch m, HasCallStack) => m a -> m a
- Test.Cleveland.Internal.Pure: UnexpectedTypeCheckError :: TCError -> TestError
+ Test.Cleveland.Internal.Pure: UnexpectedTypeCheckError :: TcError -> TestError
- Test.Cleveland.Lorentz.Import: CRETypeCheck :: MichelsonSource -> TCError -> ContractReadError
+ Test.Cleveland.Lorentz.Import: CRETypeCheck :: MichelsonSource -> TcError -> ContractReadError
- Test.Cleveland.Lorentz.Import: VRETypeCheck :: MichelsonSource -> TCError -> ValueReadError
+ Test.Cleveland.Lorentz.Import: VRETypeCheck :: MichelsonSource -> TcError -> ValueReadError
- Test.Cleveland.Michelson.Entrypoints: mkEntrypointsMap :: ParameterType -> Map EpName Ty
+ Test.Cleveland.Michelson.Entrypoints: mkEntrypointsMap :: HandleImplicitDefaultEp -> ParameterType -> Map EpName Ty
- Test.Cleveland.Michelson.Import: CRETypeCheck :: MichelsonSource -> TCError -> ContractReadError
+ Test.Cleveland.Michelson.Import: CRETypeCheck :: MichelsonSource -> TcError -> ContractReadError
- Test.Cleveland.Michelson.Import: VRETypeCheck :: MichelsonSource -> TCError -> ValueReadError
+ Test.Cleveland.Michelson.Import: VRETypeCheck :: MichelsonSource -> TcError -> ValueReadError
- Test.Cleveland.Michelson.Internal.Entrypoints: assertEPComparisonSuccessful :: Either TCError EPMismatch -> Assertion
+ Test.Cleveland.Michelson.Internal.Entrypoints: assertEPComparisonSuccessful :: Either TcTypeError EPMismatch -> Assertion
- Test.Cleveland.Michelson.Internal.Entrypoints: contractCoversEntrypoints :: Contract -> Map EpName Ty -> Either TCError EPMismatch
+ Test.Cleveland.Michelson.Internal.Entrypoints: contractCoversEntrypoints :: Contract -> Map EpName Ty -> Either TcTypeError EPMismatch
- Test.Cleveland.Michelson.Internal.Entrypoints: contractMatchesEntrypoints :: Contract -> Map EpName Ty -> Either TCError EPMismatch
+ Test.Cleveland.Michelson.Internal.Entrypoints: contractMatchesEntrypoints :: Contract -> Map EpName Ty -> Either TcTypeError EPMismatch

Files

CHANGES.md view
@@ -1,6 +1,62 @@ <!-- Unreleased: append new entries here -->  +0.3.0+=====+* [!1281](https://gitlab.com/morley-framework/morley/-/merge_requests/1281)+  Use the new binaries names, `octez-client` and `octez-node`+* [!1270](https://gitlab.com/morley-framework/morley/-/merge_requests/1270)+  Add lima protocol TICKET instruction, rename old one to TICKET_DEPRECATED+  + The `TICKET` instruction was renamed to `TICKET_DEPRECATED`+  + A new `TICKET` instuction was added which no longer allows zero amount tickets.+    It now returns `Some Ticket` and `None` in case of zero ammount supplied.+* [!1252](https://gitlab.com/morley-framework/morley/-/merge_requests/1252)+  Better errors on stuck GetEntrypointArgCustom+  + Particularly in `transfer` with polymorphic/ambiguous contract parameter.+* [!1258](https://gitlab.com/morley-framework/morley/-/merge_requests/1258)+  Support implicit contract delegates and setting delegates during origination+  + New function `setDelegate` for setting the delegate on implicit addresses.+  + `originate` now allows specifying optional delegate by passing a `KeyHash` value as argument.+  + `getDelegate` now accepts either implicit or contract addresses.+* [!1226](https://gitlab.com/morley-framework/morley/-/merge_requests/1226)+  Implement delegation operation via RPC+* [!1257](https://gitlab.com/morley-framework/morley/-/merge_requests/1257)+  Add ability to call on-chain views directly from test scenarios+* [!1244](https://gitlab.com/morley-framework/morley/-/merge_requests/1244)+  Carry verbosity setting to only-rpc env in `mkMorleyOnlyRpcEnvNetwork`+* [!1243](https://gitlab.com/morley-framework/morley/-/merge_requests/1243)+  Use Morley's `run_code` emulation+* [!1242](https://gitlab.com/morley-framework/morley/-/merge_requests/1242)+  Use `Constrained` utility existential+* [!1246](https://gitlab.com/morley-framework/morley/-/merge_requests/1246)+  Fix `MonadOriginate` blowing up with `Reduction stack overflow`+  + `MonadOriginate` constraint caused GHC to go loopy; now it doesn't, and a+    test was added to prevent this in the future.+* [!1247](https://gitlab.com/morley-framework/morley/-/merge_requests/1247)+  Refactor MorleyClientEnv+  + Removed `MorleyClientEnv'`, constructor now lives in `MorleyClientEnv`+  + Removed `Morley.Client.Env` module+  + `MorleyClientEnv`, `mkMorleyClientEnv` and `MorleyClientEnv` lenses moved to `Morley.Client.Full`+* [!1220](https://gitlab.com/morley-framework/morley/-/merge_requests/1220)+  Better `transfer` errors on bad address type+* [!1219](https://gitlab.com/morley-framework/morley/-/merge_requests/1219)+  Add resolving contract aliases in network tests+* [!1237](https://gitlab.com/morley-framework/morley/-/merge_requests/1237)+  Support delegate registration on the emulator+* [!1178](https://gitlab.com/morley-framework/morley/-/merge_requests/1178)+  Fix `contract t` typed value generator+  + `contract t` value generator where `t /= unit` could produce implicit+    addresses. This is invalid. Now it only produces smart contract addresses.+  + `contract unit` generator can still produce both implicit and smart contract+    addresses.+* [!1228](https://gitlab.com/morley-framework/morley/-/merge_requests/1228)+  Handle implicit default entrypoint in `testContractCoversEntrypoints` &c+  + Implicit default entrypoint is considered in entrypoint coverage tests iff+    the default entrypoint is defined in the spec. Otherwise, implicit default+    is ignored. Explicit default entrypoint is always considered.+* [!1211](https://gitlab.com/morley-framework/morley/-/merge_requests/1211)+  Unify handling of annotated exceptions+ 0.2.1 ===== * [!1199](https://gitlab.com/morley-framework/morley/-/merge_requests/1199)
cleveland.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           cleveland-version:        0.2.1+version:        0.3.0 synopsis:       Testing framework for Morley. description:    This package provides an eDSL for testing contracts written in Michelson, Morley or Lorentz. These tests can be run on an emulated environment or on a real network. category:       Blockchain@@ -66,8 +66,13 @@       Test.Cleveland.Internal.Actions.Originate       Test.Cleveland.Internal.Actions.Transfer       Test.Cleveland.Internal.Actions.TransferFailurePredicate+      Test.Cleveland.Internal.Actions.View       Test.Cleveland.Internal.Client       Test.Cleveland.Internal.Exceptions+      Test.Cleveland.Internal.Exceptions.Annotated+      Test.Cleveland.Internal.Exceptions.CallStack+      Test.Cleveland.Internal.Exceptions.ErrorsClarification+      Test.Cleveland.Internal.Exceptions.ScenarioBranchName       Test.Cleveland.Internal.Hedgehog       Test.Cleveland.Internal.Pure       Test.Cleveland.Internal.Scenario@@ -145,18 +150,18 @@       UndecidableInstances       UndecidableSuperClasses       ViewPatterns-  ghc-options: -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-implicit-prelude -Wno-prepositive-qualified-module -Wno-missing-safe-haskell-mode -Wno-unused-packages+  ghc-options: -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-implicit-prelude -Wno-prepositive-qualified-module -Wno-missing-safe-haskell-mode   build-depends:       HUnit     , MonadRandom     , aeson     , base-noprelude >=4.7 && <5-    , bytestring     , constraints >=0.11     , containers     , criterion     , cryptonite     , data-default+    , dependent-map     , directory     , either     , exceptions@@ -170,13 +175,12 @@     , morley-client     , morley-prelude     , mtl-    , named     , o-clock     , optparse-applicative-    , safe-exceptions     , servant-client-core     , singletons     , singletons-base+    , some     , statistics     , tagged     , tasty >=1.4@@ -203,8 +207,10 @@       TestSuite.Cleveland.BlockIntervalGetter       TestSuite.Cleveland.BytesSigning       TestSuite.Cleveland.CallStack+      TestSuite.Cleveland.CallStack.Fixtures       TestSuite.Cleveland.ChainIdGet       TestSuite.Cleveland.ContractAllocation+      TestSuite.Cleveland.Delegates       TestSuite.Cleveland.DFS       TestSuite.Cleveland.EmitMachinery       TestSuite.Cleveland.EmptyImplicitAddress@@ -219,6 +225,7 @@       TestSuite.Cleveland.Lorentz.Contracts.ContractAllocator       TestSuite.Cleveland.Lorentz.Entrypoints       TestSuite.Cleveland.MismatchError+      TestSuite.Cleveland.MonadOps       TestSuite.Cleveland.NetworkCaps       TestSuite.Cleveland.NewAddressCheck       TestSuite.Cleveland.OperationReplay@@ -236,6 +243,7 @@       TestSuite.Cleveland.TransferCheck       TestSuite.Cleveland.UsedFramework       TestSuite.Cleveland.Util+      TestSuite.Cleveland.ViewCall       TestSuite.Cleveland.VotingPower       TestSuite.Cleveland.WithMoneybag       TestSuite.Cleveland.WithSender@@ -296,7 +304,7 @@       UndecidableInstances       UndecidableSuperClasses       ViewPatterns-  ghc-options: -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-implicit-prelude -Wno-prepositive-qualified-module -Wno-missing-safe-haskell-mode -Wno-unused-packages -threaded -eventlog -rtsopts "-with-rtsopts=-N -A64m -AL256m"+  ghc-options: -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-monomorphism-restriction -Wno-implicit-prelude -Wno-prepositive-qualified-module -Wno-missing-safe-haskell-mode -threaded -eventlog -rtsopts "-with-rtsopts=-N -A64m -AL256m"   build-tool-depends:       tasty-discover:tasty-discover   build-depends:@@ -312,7 +320,6 @@     , morley     , morley-client     , morley-prelude-    , named     , o-clock     , servant-client     , tasty
src/Hedgehog/Gen/Michelson/Typed.hs view
@@ -45,7 +45,7 @@ import Morley.Michelson.Typed.Haskell.Value (BigMap(..), BigMapId(..), ToT, WellTypedToT) import Morley.Michelson.Typed.Scope import Morley.Michelson.Typed.Value (RemFail(..))-import Morley.Tezos.Address (ConstrainedAddress(..), TxRollupL2Address(..))+import Morley.Tezos.Address (Constrained(..), TxRollupL2Address(..)) import Morley.Tezos.Core (Mutez, Timestamp) import Morley.Tezos.Crypto (parseHash) import Morley.Tezos.Crypto.BLS12381 qualified as BLS@@ -172,10 +172,9 @@   STList (STPair STBls12381G1 STBls12381G2) -> genBls12Pairing   STList st -> genValueList def $ genValue' st   STSet st -> genValueSet def $ genValue' st-  STContract (s :: SingT p) -> case (checkOpPresence s, checkNestedBigMapsPresence s) of-    (OpAbsent, NestedBigMapsAbsent) -> VContract <$> genAddress <*> pure unsafeSepcCallRoot-    _ -> Gen.discard-  STTicket (s :: SingT p) -> genValueTicket def $ genValue' s+  STContract STUnit -> VContract <$> genAddress <*> pure unsafeSepcCallRoot+  STContract _ -> VContract <$> (MkAddress <$> genContractAddress) <*> pure unsafeSepcCallRoot+  STTicket s -> genValueTicket def $ genValue' s   STPair STChestKey STChest -> VPair . bimap VChestKey VChest . swap <$> genChestAndKey   STPair l r -> VPair <$> ((,) <$> genNoOpValue l <*> genNoOpValue r)   STOr l r -> VOr <$> Gen.choice
src/Hedgehog/Range/Defaults.hs view
@@ -44,7 +44,7 @@   deriving newtype (Eq, Ord, Enum, Integral, Real, Num)  instance Default (Range TicketAmount) where-  def = MkTicketAmount <$> Range.linearFrom 0 0 1000+  def = MkTicketAmount <$> Range.linearFrom 1 1 1000  -- | Newtype for the range of @ValueInt@ constructor of untyped @Value'@. newtype ValueInt = MkValueInt { unValueInt :: Integer }
src/Test/Cleveland.hs view
@@ -22,7 +22,7 @@   -- * Validation   , TransferFailure -  -- * Real network implementation based on @tezos-client@ and RPC.+  -- * Real network implementation based on @octez-client@ and RPC.   , testScenario   , testScenarioOnNetwork   , scenarioNetwork@@ -71,6 +71,7 @@   , getBalance   , getDelegate   , registerDelegate+  , setDelegate   , getMorleyLogs   , getMorleyLogs_   , getStorage@@ -127,6 +128,10 @@   , evalRight   , Showing(..) +  -- * Calling views+  , callView+  , unsafeCallView+     -- * Exception handling   , attempt   , catchTransferFailure@@ -170,8 +175,7 @@    -- * Config (reexports)   , TezosClientEnv(..)-  , MorleyClientEnv-  , MorleyClientEnv'(..)+  , MorleyClientEnv(..)   , NetworkEnv (..)   , MorleyLogs   -- ** Config utilities@@ -193,7 +197,7 @@  import Lorentz (EntrypointRef(..), Mutez, ToAddress(..), pattern DefEpName, tz) import Morley.AsRPC qualified as AsRPC-import Morley.Client (MorleyClientEnv, MorleyClientEnv'(..))+import Morley.Client (MorleyClientEnv(..)) import Morley.Client.TezosClient.Types (TezosClientEnv(..)) import Morley.Michelson.Interpret (MorleyLogs) import Morley.Michelson.Runtime (VotingPowers, mkVotingPowers, mkVotingPowersFromMap)
src/Test/Cleveland/Instances.hs view
@@ -123,6 +123,7 @@     U.LOOP ops                  -> U.LOOP $ withoutEsp' ops     U.LOOP_LEFT ops             -> U.LOOP_LEFT $ withoutEsp' ops     U.LAMBDA va ty1 ty2 ops     -> U.LAMBDA va ty1 ty2 (withoutEsp' ops)+    U.LAMBDA_REC va ty1 ty2 ops -> U.LAMBDA_REC va ty1 ty2 (withoutEsp' ops)     U.DIP ops                   -> U.DIP $ withoutEsp' ops     U.DIPN n ops -> U.DIPN n (withoutEsp' ops)     U.CREATE_CONTRACT va1 va2 c ->
src/Test/Cleveland/Internal/Abstract.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Abstract cleveland interface not bound to a particular -- implementation. --@@ -20,7 +22,7 @@ -- before trying to run scenario on a live network. -- -- Also this interface uses 'Address' rather than 'EpAddress'.--- I (\@gromak) concluded that 'EpAddress' can not be passed to @tezos-client@.+-- I (\@gromak) concluded that 'EpAddress' can not be passed to @octez-client@. -- For key addresses it just does not make sense and for contract addresses -- I get such errors: --@@ -66,8 +68,6 @@   , AddressAndAlias(..)   , TransferFailure (..)   , TransferFailureReason (..)-  , FailedInBranch (..)-  , ScenarioBranchName(..)   , GenericTestError (..)   , ExpressionOrTypedValue (..) @@ -119,12 +119,13 @@   , neSecretKeyL   , neMoneybagAliasL   , neExplicitDataDirL+  , neVerbosityL   ) where  import Control.Lens (Each, each, filtered, makeLenses, makeLensesFor, makeLensesWith)+import Data.Constraint (Bottom(..), (\\)) import Data.Default (Default(..)) import Data.Type.Equality (pattern Refl)-import Data.Typeable (cast) import Fmt (Buildable(..), Builder, pretty, (+|), (|+)) import Prelude hiding (Each) import Time (KnownDivRat, Second, Time)@@ -154,7 +155,7 @@ import Morley.Util.Lens (postfixLFields) import Morley.Util.Sing (eqI) import Morley.Util.TypeLits-import Test.Cleveland.Internal.Exceptions (WithCallStack(..))+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Lorentz.Types  -- | Whether this contract should be originated in@@ -176,6 +177,8 @@   -- We are using Lorentz version here which is convenient. However, keep in   -- mind that if someone wants to test a contract from @.tz@ file, they should use   -- 'UntypedOriginateData'.+  , odDelegate :: Maybe KeyHash+  -- ^ Contract delegate.   }  -- | Untyped version of OriginateData. It can be used for interaction with raw@@ -189,6 +192,8 @@   -- ^ Initial storage.   , uodContract :: U.Contract   -- ^ The contract itself.+  , uodDelegate :: Maybe KeyHash+  -- ^ Contract delegate.   }  -- | Untyped version of OriginateData. It can be used for interaction with raw@@ -202,6 +207,8 @@   -- ^ Initial storage.   , todContract :: T.Contract (T.ToT cp) (T.ToT st)   -- ^ The contract itself.+  , todDelegate :: Maybe KeyHash+  -- ^ Contract delegate.   }  -- | Information about transfer operation.@@ -229,6 +236,7 @@   type TransferInfo ClevelandInput = TransferData   type OriginationInfo ClevelandInput = UntypedOriginateData 'NotLarge   type RevealInfo ClevelandInput = PublicKey+  type DelegationInfo ClevelandInput = Maybe KeyHash  -- | Data structure representing a contract event. data ContractEvent = ContractEvent@@ -243,6 +251,7 @@   type TransferInfo ClevelandResult = [ContractEvent]   type OriginationInfo ClevelandResult = OriginationInfo Result   type RevealInfo ClevelandResult = RevealInfo Result+  type DelegationInfo ClevelandResult = DelegationInfo Result  -- | A batch returned invalid output, e.g. origination address when transaction -- was supplied.@@ -350,10 +359,8 @@   , cmiGetPublicKey :: HasCallStack => ImplicitAddress -> m Crypto.PublicKey   -- ^ Get the public key associated with the given address.   -- Fail if the given address is not an implicit account.-  , cmiGetDelegate :: HasCallStack => ContractAddress -> m (Maybe Crypto.KeyHash)+  , cmiGetDelegate :: HasCallStack => L1Address -> m (Maybe Crypto.KeyHash)   -- ^ Get the delegate for the given contract. Fails on implicit contracts.-  , cmiRegisterDelegate :: HasCallStack => ImplicitAddress -> m ()-  -- ^ Register the given address as a valid delegate.   , cmiGetChainId :: HasCallStack => m ChainId   -- ^ Get the chain's @ChainId@.   , cmiAdvanceTime :: forall unit. (HasCallStack, KnownDivRat unit Second) => Time unit -> m ()@@ -454,6 +461,7 @@   , neSecretKey :: Maybe Crypto.SecretKey   , neMoneybagAlias :: ImplicitAlias   , neExplicitDataDir :: Bool+  , neVerbosity :: Word   }  ----------------------------------------------------------------------------@@ -511,15 +519,16 @@   } deriving newtype (Functor, Applicative)  instance-  TypeError-  ( 'Text "Attempt to use monad capabilities within a batch" ':$$:-    'Text "In case you are using a do-block, make sure that" ':$$:-    'Text "• `ApplicativeDo` extension is enabled" ':$$:-    'Text "• there is a return statement in the end" ':$$:-    'Text "• returned value picks variables in the order in which they are defined"-  ) =>-  Monad ClevelandOpsBatch where-    (>>=) = error "impossible"+  ( Bottom+  , TypeError+        ( 'Text "Attempt to use monad capabilities within a batch" ':$$:+          'Text "In case you are using a do-block, make sure that" ':$$:+          'Text "• `ApplicativeDo` extension is enabled" ':$$:+          'Text "• there is a return statement in the end" ':$$:+          'Text "• returned value picks variables in the order in which they are defined"+        )+  ) => Monad ClevelandOpsBatch where+    (>>=) = no  {- | Run a series of operations within a batch. @@ -602,9 +611,19 @@     EOTVExpression e -> either (const $ build e) build $ fromExpression @U.Value e     EOTVTypedValue v -> build v -data AddressAndAlias = AddressAndAlias Address (Maybe ContractAlias)-  deriving stock (Show, Eq)+data AddressAndAlias = forall kind. AddressAndAlias (KindedAddress kind) (Maybe (Alias kind)) +deriving stock instance Show AddressAndAlias++instance Eq AddressAndAlias where+  (AddressAndAlias (addr1 :: KindedAddress kind1) _) ==+    (AddressAndAlias (addr2 :: KindedAddress kind2) _) =+      maybe False (\Refl -> addr1 == addr2) $+        eqI @kind1 @kind2 \\ addressKindSanity addr1 \\ addressKindSanity addr2++instance ToAddress AddressAndAlias where+  toAddress (AddressAndAlias a _) = toAddress a+ instance Buildable AddressAndAlias where   build (AddressAndAlias addr mbAlias) =     build addr +| maybe "" (\alias -> " (" +| alias |+ ")") mbAlias@@ -633,20 +652,6 @@   -- TODO [#284]: add more errors here!   deriving stock (Show, Eq) --- | When an exception is thrown in a 'Test.Cleveland.branchout' branch, we wrap it in this--- constructor to remember in _which_ branch it was thrown.--- We use this information to provide better error messages when a test fails.-data FailedInBranch = FailedInBranch ScenarioBranchName SomeException-  deriving stock (Show)---- | When using 'Test.Cleveland.branchout' function for building test scenarios - names--- of branches we are currently within.-newtype ScenarioBranchName = ScenarioBranchName { unTestBranch :: [Text] }-  deriving stock (Show, Eq)--instance Buildable ScenarioBranchName where-  build = mconcat . intersperse "/" . map build . unTestBranch- instance Buildable TransferFailure where   build (TransferFailure addr reason) = case reason of     EmptyTransaction -> reason |+ ": " +| addr |+ ""@@ -663,10 +668,6 @@     ShiftOverflow -> "overflow error"     GasExhaustion -> "gas exhaustion" -instance Buildable FailedInBranch where-  build (FailedInBranch branchName (SomeException err)) = "In '" +| branchName |+-    "' branch:\n" +| (build $ displayException err)- data GenericTestError   = UnexpectedSuccess   deriving stock Show@@ -678,25 +679,11 @@  instance Exception TransferFailure where   displayException = pretty-  fromException someEx@(SomeException ex) =-    cast @_ @TransferFailure ex-    <|>-    ( do-        WithCallStack _ exInner <- fromException @WithCallStack someEx-        fromException exInner-    )-    <|>-    ( do-        FailedInBranch _ exInner <- fromException @FailedInBranch someEx-        fromException exInner-    )---instance Exception FailedInBranch where-  displayException = pretty+  fromException = fromPossiblyAnnotatedException  instance Exception GenericTestError where   displayException = pretty+  fromException = fromPossiblyAnnotatedException  ---------------------------------------------------------------------------- -- Other helpers@@ -762,7 +749,6 @@     , cmiGetAllBigMapValuesMaybe = \bmId -> f $ cmiGetAllBigMapValuesMaybe bmId     , cmiGetPublicKey = \addr -> f $ cmiGetPublicKey addr     , cmiGetDelegate = f <$> cmiGetDelegate-    , cmiRegisterDelegate = f <$> cmiRegisterDelegate     , cmiGetChainId = f $ cmiGetChainId     , cmiAdvanceTime = \time -> f $ cmiAdvanceTime time     , cmiAdvanceToLevel = \level -> f $ cmiAdvanceToLevel level
src/Test/Cleveland/Internal/Actions.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Cleveland actions. module Test.Cleveland.Internal.Actions   ( MonadOps@@ -54,6 +56,7 @@   , offshoot   , getDelegate   , registerDelegate+  , setDelegate   , setVotingPowers   , whenEmulation   , whenNetwork@@ -72,6 +75,10 @@   , evalJust   , evalRight +  -- * Calling views+  , callView+  , unsafeCallView+   -- * Exception handling   , attempt   , catchTransferFailure@@ -104,9 +111,10 @@ import Test.Cleveland.Internal.Actions.Assertions import Test.Cleveland.Internal.Actions.ExceptionHandling import Test.Cleveland.Internal.Actions.Misc-import Test.Cleveland.Internal.Actions.Originate+import Test.Cleveland.Internal.Actions.Originate hiding (setDelegate) import Test.Cleveland.Internal.Actions.Transfer import Test.Cleveland.Internal.Actions.TransferFailurePredicate+import Test.Cleveland.Internal.Actions.View  -- | Synonym typeclass for monads where network operations can occur. --
src/Test/Cleveland/Internal/Actions/Assertions.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Various test assertions in the 'MonadCleveland' context. module Test.Cleveland.Internal.Actions.Assertions   ( module Test.Cleveland.Internal.Actions.Assertions
src/Test/Cleveland/Internal/Actions/ExceptionHandling.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Exception handling module Test.Cleveland.Internal.Actions.ExceptionHandling   ( module Test.Cleveland.Internal.Actions.ExceptionHandling@@ -8,7 +10,7 @@  import Data.Either.Validation (Validation(..)) import Data.List.NonEmpty qualified as NE-import Fmt (Builder, build, indentF, nameF, pretty, unlinesF)+import Fmt (Builder, build, indentF, unlinesF)  import Lorentz (CustomError(..), ErrorTagMap, IsError, Label, MText, MustHaveErrorArg) import Lorentz.Constraints@@ -17,9 +19,7 @@ import Test.Cleveland.Internal.Actions.Helpers import Test.Cleveland.Internal.Actions.Misc import Test.Cleveland.Internal.Actions.TransferFailurePredicate-import Test.Cleveland.Internal.Client qualified as Client (TestError(..))-import Test.Cleveland.Internal.Exceptions (WithCallStack(..))-import Test.Cleveland.Internal.Pure as Pure (TestError(..))+import Test.Cleveland.Internal.Exceptions  -- | Attempt to run an action and return its result or, if interpretation fails, an error. attempt@@ -145,8 +145,7 @@   => ErrorTagMap -> err -> m a -> m () expectNumericError tagMap err = expectTransferFailure $ failedWith (numericError tagMap err) --- | Prefix /scenario-custom/ error messages (i.e. @CustomTestError@ either from pure or non-pure--- implementation), potentially thrown from the given code block.+-- | Prefix error messages potentially thrown from the given code block. -- -- The prefix will be put at a separate line before the main text, if text is multiline, otherwise -- it will be separated from the main text with @: @.@@ -160,29 +159,8 @@ -- >   askContract i @@== i * 2 clarifyErrors :: forall caps m a. (MonadCleveland caps m)               => Builder -> m a -> m a-clarifyErrors message action = do+clarifyErrors message action =   attempt action >>= \case-    Left (e :: SomeException) -> withCap getMiscCap \cap -> cmiThrow cap (handle e)+    Left e -> withCap getMiscCap \cap -> cmiThrow cap $+      insertAnnEx (ErrorsClarification [message]) e     Right val -> pure val-  where-  handle :: SomeException -> SomeException-  handle e = fromMaybe e $-        wrap testClientErrorHandler e-    <|> wrap testPureErrorHandler e-    <|> wrap withCallStackErrorHandler e--  wrap f = fmap (toException . f) . fromException--  addPrefix = pretty . nameF message . build--  testClientErrorHandler :: Client.TestError -> Client.TestError-  testClientErrorHandler = \case-    Client.CustomTestError msg -> Client.CustomTestError $ addPrefix msg--  testPureErrorHandler :: Pure.TestError -> Pure.TestError-  testPureErrorHandler = \case-    Pure.CustomTestError msg -> Pure.CustomTestError $ addPrefix msg-    err -> err--  withCallStackErrorHandler :: WithCallStack -> WithCallStack-  withCallStackErrorHandler (WithCallStack cst e) = WithCallStack cst $ handle e
src/Test/Cleveland/Internal/Actions/Helpers.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Helpers for working in @MonadCleveland@ context. module Test.Cleveland.Internal.Actions.Helpers   ( module Test.Cleveland.Internal.Actions.Helpers
src/Test/Cleveland/Internal/Actions/Misc.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | The bulk of Cleveland actions. module Test.Cleveland.Internal.Actions.Misc   ( module Test.Cleveland.Internal.Actions.Misc@@ -16,13 +18,15 @@ import Lorentz.Bytes import Lorentz.Constraints import Morley.AsRPC (HasRPCRepr(..))-import Morley.Client (MorleyClientEnv)-import Morley.Michelson.Runtime (VotingPowers)+import Morley.Client (MorleyClientEnv, OperationInfo(..), RunError(..), UnexpectedErrors(..))+import Morley.Michelson.Runtime (ExecutorError'(..), VotingPowers)+import Morley.Michelson.Runtime.GState (GStateUpdateError(..)) import Morley.Michelson.Runtime.Import qualified as Runtime import Morley.Michelson.Typed (SomeAnnotatedValue) import Morley.Michelson.Typed qualified as T import Morley.Michelson.Typed.AnnotatedValue (castTo, getT, value) import Morley.Michelson.Untyped qualified as U+import Morley.Tezos.Address (unImplicitAddress) import Morley.Tezos.Address.Alias (Alias(..)) import Morley.Tezos.Core (ChainId, Mutez, Timestamp) import Morley.Tezos.Crypto (KeyHash, PublicKey, Signature)@@ -32,7 +36,9 @@ import Test.Cleveland.Internal.Abstract import Test.Cleveland.Internal.Actions.Assertions import Test.Cleveland.Internal.Actions.Helpers+import Test.Cleveland.Internal.Actions.MonadOps import Test.Cleveland.Internal.Actions.Transfer+import Test.Cleveland.Internal.Exceptions (fromPossiblyAnnotatedException) import Test.Cleveland.Lorentz.Import qualified as LorentzImport import Test.Cleveland.Lorentz.Types @@ -215,18 +221,40 @@ getBalance addr = do   withCap getMiscCap \cap -> cmiGetBalance cap (toL1Address addr) --- | Get the delegate for the given contract. Fails on implicit contracts.+-- | Get the delegate for the given contract/implicit address. getDelegate-  :: (HasCallStack, MonadCleveland caps m, ToContractAddress addr)+  :: (HasCallStack, MonadCleveland caps m, ToL1Address addr)   => addr -> m (Maybe KeyHash) getDelegate addr = do-  withCap getMiscCap \cap -> cmiGetDelegate cap (toContractAddress addr)+  withCap getMiscCap \cap -> cmiGetDelegate cap (toL1Address addr) --- | Register the given address as a valid delegate.-registerDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddress -> m ()+-- | Register the given implicit address as a delegate.+registerDelegate+  :: (HasCallStack, MonadCleveland caps m)+  => ImplicitAddress -> m () registerDelegate addr = do-  withCap getMiscCap \cap -> cmiRegisterDelegate cap addr+  caps <- ask+  r <- lift $ cmiAttempt (getMiscCap caps) $+    runReaderT (setDelegate addr $ Just $ unImplicitAddress addr) caps+  -- NB: we do some exception wrangling such that registerDelegate doesn't error+  -- out if an address is already a delegate. The primary reason for this is the+  -- disconnect between network, which remembers delegation state between+  -- scenarios, and the emulator, which does not. Hence we want registerDelegate+  -- to be idempotent.+  case r of+    Right () -> pass+    Left e+      | Just (UnexpectedRunErrors [DelegateAlreadyActive]) <- fromPossiblyAnnotatedException e -> pass+      | Just (EEFailedToApplyUpdates GStateAlreadySetDelegate{} :: ExecutorError' AddressAndAlias)+        <- fromPossiblyAnnotatedException e+      -> pass+      | otherwise -> lift $ cmiThrow (getMiscCap caps) e +-- | Set/unset delegate+setDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddress -> Maybe KeyHash -> m ()+setDelegate addr kh = void $ withSender addr $+  withOpsCap \cap -> coiRunOperationBatch cap [OpDelegation kh]+ -- | Retrieve a contract's storage in its "RPC representation" -- (i.e., all its big_maps will be replaced by big_map IDs). --@@ -544,7 +572,7 @@   Left impl -> withCap (view clevelandCapsL) (runReaderT onEmu . EmulatedCaps impl)  -- | Get a 'MorleyClientEnv' when running a test on network. Useful to run--- f.ex. @tezos-client@ inside a network test.+-- f.ex. @octez-client@ inside a network test. -- -- This is considered a pretty low-level function, so it's better to avoid it in -- most cases.
src/Test/Cleveland/Internal/Actions/MonadOps.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Internally used typeclass for operations-related actions module Test.Cleveland.Internal.Actions.MonadOps   ( module Test.Cleveland.Internal.Actions.MonadOps
src/Test/Cleveland/Internal/Actions/Originate.hs view
@@ -1,17 +1,17 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Machinery for the variadic 'originate' function. module Test.Cleveland.Internal.Actions.Originate   ( module Test.Cleveland.Internal.Actions.Originate   ) where -import Lorentz-  (Contract(..), NiceParameter, NiceStorage, NiceViewsDescriptor, niceStorageEvi,-  toMichelsonContract)+import Lorentz (Contract(..), NiceParameter, NiceStorage, NiceViewsDescriptor, toMichelsonContract) -import Data.Constraint ((\\))-import GHC.TypeLits (ErrorMessage(..), TypeError)+import Data.Constraint (Bottom(..))+import GHC.TypeLits (ErrorMessage(..), Symbol, TypeError)  import Morley.Client.Types import Morley.Michelson.Typed (convertContract, toVal, untypeValue)@@ -19,6 +19,7 @@ import Morley.Michelson.Untyped qualified as U import Morley.Tezos.Address import Morley.Tezos.Core+import Morley.Tezos.Crypto (KeyHash) import Test.Cleveland.Internal.Abstract import Test.Cleveland.Internal.Actions.Helpers import Test.Cleveland.Internal.Actions.MonadOps@@ -41,9 +42,10 @@ -- > originate "contract" initialStorage contract [tz|123micro|] Large -- -- The order is arbitrary, but each can be specified at most once.-originate :: forall contract r. (HasCallStack, OriginateFunc contract 'NoBalance 'NotLarge r)+originate :: forall contract r. ( HasCallStack, ContractClass contract+                                , OriginateFunc contract '[] r)           => ContractAlias -> ContractStorage contract -> contract -> r-originate = originate'r @contract @'NoBalance @'NotLarge ... initialData @contract+originate = originate'r @contract @'[] ... initialData @contract  ---------------------------------------------------------------------------- -- Main origination implementations@@ -64,8 +66,9 @@     let uod = UntypedOriginateData @large           odName           odBalance-          (untypeValue (toVal odStorage) \\ niceStorageEvi @st)+          (untypeValue (toVal odStorage))           (convertContract $ toMichelsonContract (odContract od))+          odDelegate     ContractHandle odName <$> originateFn uod  instance (a ~ ContractHandle cp st vd, MonadOpsInternal m@@ -78,6 +81,7 @@           todBalance           (untypeValue (toVal todStorage))           (convertContract (todContract tod))+          todDelegate     ContractHandle todName <$> originateFn uod  instance (a ~ ContractAddress, MonadOpsInternal m)@@ -109,12 +113,12 @@ instance ContractClass (Contract cp st vd) where   type ContractStorage (Contract cp st vd) = st   type ContractOriginateData (Contract cp st vd) = OriginateData cp st vd-  initialData = flip OriginateData zeroMutez+  initialData name store contract = OriginateData name zeroMutez store contract Nothing  instance ContractClass U.Contract where   type ContractStorage U.Contract = U.Value   type ContractOriginateData U.Contract = UntypedOriginateData-  initialData = flip UntypedOriginateData zeroMutez+  initialData name store contract = UntypedOriginateData name zeroMutez store contract Nothing  instance ContractClass (TypedContract cp st vd) where   type ContractStorage (TypedContract cp st vd) = st@@ -125,6 +129,7 @@       , todBalance = zeroMutez       , todStorage = store       , todContract = contract+      , todDelegate = Nothing       }  ----------------------------------------------------------------------------@@ -135,67 +140,84 @@ -- -- If you see GHC asking for this constraint, you most likely need to add -- 'MonadOriginate' constraint on the return monad instead.-class ContractClass contract => OriginateFunc contract (bal :: HasBalance) isLarge r where-  originate'r :: HasCallStack => ContractOriginateData contract isLarge -> r+class OriginateFunc contract (props :: [Prop]) r where+  originate'r :: HasCallStack => ContractOriginateData contract (GetLarge props) -> r   default originate'r-    :: (HasCallStack, Originator (ContractOriginateData contract isLarge) r)-    => ContractOriginateData contract isLarge -> r+    :: (HasCallStack, Originator (ContractOriginateData contract (GetLarge props)) r)+    => ContractOriginateData contract (GetLarge props) -> r   originate'r = originateFn --- | Simple flag to track duplicate balance specification.-data HasBalance = NoBalance | HasBalance+-- | Enum for props we track duplicates of.+data Prop = PropBalance | PropDelegate | PropLarge --- | Type family raising a type error on 'HasBalance' argument. Used to improve--- error reporting for 'OriginateFunc' instances with equality constraints.-type family CheckDupBalance mod :: Constraint where-  CheckDupBalance 'HasBalance = TypeError ('Text "Balance is specified more than once.")-  CheckDupBalance 'NoBalance = ()+-- | Pretty prop name.+type PropName :: Prop -> Symbol+type family PropName a where+  PropName 'PropBalance = "Balance"+  PropName 'PropDelegate = "Delegate"+  PropName 'PropLarge = "Large" -instance-   ( ModifyOriginationData (ContractOriginateData ct)-   , OriginateFunc ct 'HasBalance isLarge r-   , CheckDupBalance bal, bal ~ 'NoBalance)-  => OriginateFunc ct bal isLarge (Mutez -> r) where-  originate'r initData x = originate'r @ct @'HasBalance $ setBalance x initData+-- | Convert a list of props into 'LargeOrigination'.+type GetLarge :: [Prop] -> LargeOrigination+type family GetLarge a where+  GetLarge ('PropLarge ': _) = 'IsLarge+  GetLarge (_ ': xs) = GetLarge xs+  GetLarge '[] = 'NotLarge --- | Type family raising a type error on 'IsLarge' argument. Used to improve+-- | Type family raising a type error if element is in list. Used to improve -- error reporting for 'OriginateFunc' instances with equality constraints.-type family CheckDupLarge mod :: Constraint where-  CheckDupLarge 'IsLarge = TypeError ('Text "Large is specified more than once.")-  CheckDupLarge 'NotLarge = ()+type CheckDupProp :: Prop -> [Prop] -> Constraint+type family CheckDupProp name props where+  CheckDupProp name (name ': _) =+    TypeError ('Text (PropName name) ':<>: 'Text " is specified more than once.")+  CheckDupProp name (_ ': xs) = CheckDupProp name xs+  CheckDupProp _ '[] = () -instance (ModifyOriginationData (ContractOriginateData ct)-   , OriginateFunc ct bal 'IsLarge r-   , CheckDupLarge isLarge, isLarge ~ 'NotLarge)-  => OriginateFunc ct bal isLarge (Large -> r) where-  originate'r initData Large = originate'r @ct @bal $ setLarge initData+-- | Convenience synonym for constraints used in OriginateFunc instances.+type OFConstraints ct prop props r =+  ( ModifyOriginationData (ContractOriginateData ct)+  , OriginateFunc ct (prop ': props) r+  , CheckDupProp prop props) --- | Convenience synonym.-type OFConstraint ct large r =-  ( ContractClass ct, Originator (ContractOriginateData ct large) r)+-- | Set balance.+instance OFConstraints ct 'PropBalance props r => OriginateFunc ct props (Mutez -> r) where+  originate'r initData x = originate'r @ct @('PropBalance : props) $ setBalance x initData +-- | Set delegate.+instance OFConstraints ct 'PropDelegate props r => OriginateFunc ct props (KeyHash -> r) where+  originate'r initData x = originate'r @ct @('PropDelegate : props) $ setDelegate x initData++-- | Set large origination.+instance (OFConstraints ct 'PropLarge props r, GetLarge props ~ 'NotLarge)+  => OriginateFunc ct props (Large -> r) where+  originate'r initData Large = originate'r @ct @('PropLarge ': props) $ setLarge initData+ -- | The terminating case for batched transfer.-instance OFConstraint ct large (ClevelandOpsBatch a)-  => OriginateFunc ct bal large (ClevelandOpsBatch a)+instance Originator (ContractOriginateData ct (GetLarge props)) (ClevelandOpsBatch a)+  => OriginateFunc ct props (ClevelandOpsBatch a)  -- | The terminating case for Cleveland monads.-instance OFConstraint ct large (ReaderT cap base a)-  => OriginateFunc ct bal large (ReaderT cap base a)+instance Originator (ContractOriginateData ct (GetLarge props)) (ReaderT cap base a)+  => OriginateFunc ct props (ReaderT cap base a)  -- | A convenient synonym class to require the terminating instance for a given -- monad without leaking too much implementation detail.-class (forall ct bal large a. OFConstraint ct large (m a) => OriginateFunc ct bal large (m a))+class (MonadOpsInternal m+  , forall ct props a. Originator (ContractOriginateData ct (GetLarge props)) (m a)+      => OriginateFunc ct props (m a))   => MonadOriginate m-instance (forall ct bal large a. OFConstraint ct large (m a) => OriginateFunc ct bal large (m a))+instance (MonadOpsInternal m+  , forall ct props a. Originator (ContractOriginateData ct (GetLarge props)) (m a)+      => OriginateFunc ct props (m a))   => MonadOriginate m  -- | Catchall incoherent instance to report argument errors. instance {-# INCOHERENT #-}-     ( ContractClass ct-     , TypeError ('Text "Incorrect argument for the 'originate' function: " ':<>: 'ShowType x ':$$:-      'Text "If in doubt, try adding a type annotation."))-  => OriginateFunc ct bal large (x -> r) where-  originate'r = error "impossible"+    ( TypeError ('Text "Incorrect argument for the 'originate' function: " ':<>: 'ShowType x ':$$:+     'Text "If in doubt, try adding a type annotation.")+    , Bottom)+  => OriginateFunc ct props (x -> r) where+  originate'r = no  ---------------------------------------------------------------------------- -- Applying modifiers to the initial data@@ -210,16 +232,20 @@ -- | Type class implementing modifications to origination data. class ModifyOriginationData od where   setBalance :: Mutez -> od large -> od large+  setDelegate :: KeyHash -> od large -> od large   setLarge :: od 'NotLarge -> od 'IsLarge  instance ModifyOriginationData (OriginateData cp st vd) where   setBalance bal od = od {odBalance = bal}+  setDelegate kh od = od {odDelegate = Just kh}   setLarge OriginateData{..} = OriginateData{..}  instance ModifyOriginationData (UntypedOriginateData) where   setBalance bal od = od {uodBalance = bal}+  setDelegate kh od = od {uodDelegate = Just kh}   setLarge UntypedOriginateData{..} = UntypedOriginateData{..}  instance ModifyOriginationData (TypedOriginateData cp st vd) where   setBalance bal od = od {todBalance = bal}+  setDelegate kh od = od {todDelegate = Just kh}   setLarge TypedOriginateData{..} = TypedOriginateData{..}
src/Test/Cleveland/Internal/Actions/Transfer.hs view
@@ -1,11 +1,14 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Machinery for the variadic 'transfer' function. module Test.Cleveland.Internal.Actions.Transfer   ( module Test.Cleveland.Internal.Actions.Transfer   ) where +import Data.Constraint (Bottom(..)) import Data.Singletons.TH (SingI(..), genSingletons) import GHC.TypeLits (ErrorMessage(..), TypeError) @@ -18,6 +21,9 @@ import Test.Cleveland.Internal.Actions.MonadOps import Test.Cleveland.Lorentz.Types +-- $setup+-- >>> :m Lorentz.Constraints.Scopes Lorentz.Entrypoints.Core Test.Cleveland+ ---------------------------------------------------------------------------- -- TransferResult and its singletons ----------------------------------------------------------------------------@@ -52,37 +58,100 @@ -- transfer ---------------------------------------------------------------------------- --- | Base method for making a transfer.------ You can specify additional arguments after the destination address to modify--- optional transfer arguments. Those can either be 'Mutez' to specify transfer--- amount (0 by default), or a specially constructed call descriptor. The order--- is arbitrary, but it is usually more convenient to specify transfer amount--- first. For example:------ > transfer addr [tz|123u|] $ calling (ep @"Entrypoint") ()--- > transfer addr [tz|123u|]------ If the call isn't specified, then the default entrypoint will be called with--- @()@, i.e.------ > transfer addr------ is functionally the same as------ > transfer addr $ calling def ()------ If the address in the first argument is untyped, the transfer is unchecked.--- Unchecked transfers must use 'unsafeCalling' for the call specification. You--- can also use 'unsafeCalling' with typed address to force an unchecked--- transfer.------ See "Test.Cleveland.Internal.Actions.Transfer" for further explanation of the--- interface.------ By default, the sender is the account associated with the @moneybag@ alias.--- This can be overridden with the @--cleveland-moneybag-alias@ command line--- option, the @TASTY_CLEVELAND_MONEYBAG_ALIAS@ env var, or @withSender@.+{- | Base method for making a transfer.++You can specify additional arguments after the destination address to modify+optional transfer arguments. Those can either be 'Mutez' to specify transfer+amount (0 by default), or a specially constructed call descriptor. The order+is arbitrary, but it is usually more convenient to specify transfer amount+first. For example:++> transfer addr [tz|123u|] $ calling (ep @"Entrypoint") ()+> transfer addr [tz|123u|]++If the call isn't specified, then the default entrypoint will be called with+@()@, i.e.++> transfer addr++is functionally the same as++> transfer addr $ calling def ()++If the address in the first argument is untyped, the transfer is unchecked.+Unchecked transfers must use 'unsafeCalling' for the call specification. You+can also use 'unsafeCalling' with typed address to force an unchecked+transfer.++See "Test.Cleveland.Internal.Actions.Transfer" for further explanation of the+interface.++By default, the sender is the account associated with the @moneybag@ alias.+This can be overridden with the @--cleveland-moneybag-alias@ command line+option, the @TASTY_CLEVELAND_MONEYBAG_ALIAS@ env var, or @withSender@.++In some polymorphic cases, you may need to add 'HasEntrypointArg' constraint:++>>> :{+example+  :: (MonadCleveland caps m, NiceParameter cp)+  => ContractHandle cp st vd -> m ()+example ch = transfer ch (123 :: Mutez)+:}+...+... Can not look up entrypoints in type+...   cp+... The most likely reason it is ambiguous, or you need+...   HasEntrypointArg cp (EntrypointRef 'Nothing) ()+... constraint+...++You can fix this by adding the constraint:++>>> :{+example+  :: ( MonadCleveland caps m, NiceParameter cp+     , HasEntrypointArg cp (EntrypointRef 'Nothing) ())+  => ContractHandle cp st vd -> m ()+example ch = transfer ch (123 :: Mutez)+:}++GHC may not always figure out the type of the entrypoint parameter. In that+case, it'll show unbound type variable, usually @arg0@:++>>> :{+example+  :: (MonadCleveland caps m, NiceParameter cp, NiceParameter arg)+  => ContractHandle cp st vd -> arg -> m ()+example ch x = transfer ch (123 :: Mutez) $ calling def x+:}+...+... Can not look up entrypoints in type+...   cp+... The most likely reason it is ambiguous, or you need+...   HasEntrypointArg cp (EntrypointRef 'Nothing) arg0+... constraint+...++Either specifying a concrete type in the constraint, or leaving it polymorphic,+fixes this:++>>> :{+example+  :: ( MonadCleveland caps m, NiceParameter cp, NiceParameter arg+     , HasEntrypointArg cp (EntrypointRef 'Nothing) Integer)+  => ContractHandle cp st vd -> Integer -> m ()+example ch x = transfer ch (123 :: Mutez) $ calling def x+:}++>>> :{+example+  :: ( MonadCleveland caps m, NiceParameter cp, NiceParameter arg+     , HasEntrypointArg cp (EntrypointRef 'Nothing) arg)+  => ContractHandle cp st vd -> arg -> m ()+example ch x = transfer ch (123 :: Mutez) $ calling def x+:}+-} transfer :: forall addr r.             ( HasCallStack             , TransferFunc ('Incomplete (InitialTransferMode addr))@@ -121,6 +190,16 @@   InitialTransferMode L1Address = 'Unchecked   InitialTransferMode (L1TAddress param _) = 'Checked param   InitialTransferMode (ContractHandle param _ _) = 'Checked param+  InitialTransferMode Address = TypeError (+    'Text "'Address' can not be used as the first argument of 'transfer'." ':$$:+    'Text "Perhaps you meant to use 'L1Address'?")+  InitialTransferMode (TAddress _ _) = TypeError (+    'Text "'TAddress' can not be used as the first argument of 'transfer'." ':$$:+    'Text "Perhaps you meant to use 'L1TAddress'?")+  InitialTransferMode x = TypeError (+    'Text "Address type '" ':<>: 'ShowType x ':<>: 'Text "' is unsupported or ambiguous." ':$$:+    'Text "The supported address types are" ':$$:+    'Text "'ContractAddress', 'ImplicitAddress', 'L1Address', 'L1TAddress', and 'ContractHandle'")  -- | Construct initial 'GenericTransferData' for a given address. initialData@@ -214,10 +293,11 @@  -- | Catchall incoherent instance to report argument errors. instance {-# INCOHERENT #-}-     TypeError ('Text "Incorrect argument for the 'transfer' function: " ':<>: 'ShowType x ':$$:-      'Text "If in doubt, try adding a type annotation.")+     ( Bottom+     , TypeError ('Text "Incorrect argument for the 'transfer' function: " ':<>: 'ShowType x ':$$:+                  'Text "If in doubt, try adding a type annotation."))   => TransferFunc mode emit am (x -> r) where-  transfer'r = error "impossible"+  transfer'r = no  ---------------------------------------------------------------------------- -- Making the actual transfer
src/Test/Cleveland/Internal/Actions/TransferFailurePredicate.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | 'TransferFailure' Predicates module Test.Cleveland.Internal.Actions.TransferFailurePredicate   ( module Test.Cleveland.Internal.Actions.TransferFailurePredicate@@ -15,7 +17,7 @@ import Lorentz.Constraints import Morley.Micheline (Expression, fromExpression, toExpression) import Morley.Michelson.Printer.Util (buildRenderDoc)-import Morley.Michelson.Typed (SomeConstant, SomeConstrainedValue(..))+import Morley.Michelson.Typed (Constrained(..), SomeConstant) import Morley.Michelson.Typed qualified as T import Test.Cleveland.Internal.Abstract import Test.Cleveland.Lorentz.Types@@ -94,8 +96,8 @@   => addr -- ^ The expected address.   -> TransferFailurePredicate addressIs (toAddress -> expectedAddr) = TransferFailurePredicate \err -> do-  let TransferFailure (AddressAndAlias actualAddr _) _ = err-  when (actualAddr /= expectedAddr) $+  let TransferFailure addrAndAlias _ = err+  when (toAddress addrAndAlias /= expectedAddr) $     Failure $ "Failure occurred in contract with address: " <> build expectedAddr  ----------------------------------------------------------------------------@@ -104,9 +106,7 @@  -- | A constant michelson value that a contract threw with @FAILWITH@. constant :: forall err. NiceConstant err => err -> SomeConstant-constant err =-  withDict (niceConstantEvi @err) $-    SomeConstant $ toVal err+constant err = SomeConstant $ toVal err  -- | A lorentz error. lerror :: forall err. IsError err => err -> SomeConstant
+ src/Test/Cleveland/Internal/Actions/View.hs view
@@ -0,0 +1,111 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_HADDOCK not-home #-}++-- | On-chain view utilities.+module Test.Cleveland.Internal.Actions.View+  ( module Test.Cleveland.Internal.Actions.View+  ) where++import Data.Constraint (pattern Dict)+import Fmt ((+|), (|+))++import Lorentz (Contract(..), HasView, Label, NiceViewable, toVal)+import Lorentz qualified as L+import Morley.AsRPC+import Morley.Michelson.Typed (pattern (:#))+import Morley.Michelson.Typed qualified as T+import Morley.Util.TypeLits (KnownSymbol, symbolValT')+import Test.Cleveland.Internal.Abstract+import Test.Cleveland.Internal.Actions.Assertions (failure)+import Test.Cleveland.Internal.Actions.Misc+import Test.Cleveland.Lorentz.Types++-- | Call an on-chain view by name. The existence of the view is checked at+-- compile time. If you don't have compile-time information about views, see+-- 'unsafeCallView'.+--+-- Example:+--+-- > callView contract #sum (123, -321)+callView+  :: forall name arg ret cp st vd m caps.+    ( MonadCleveland caps m, HasView vd name arg ret+    , NiceParameter arg, NiceViewable ret, NiceStorage ret+    , NiceParameter cp, KnownSymbol name, HasRPCRepr ret+    , T.IsoValue (AsRPC ret))+  => ContractHandle cp st vd -- ^ Contract to call.+  -> Label name -- ^ View name. Use @OverloadedLabels@ syntax.+  -> arg -- ^ Parameter to pass to the view.+  -> m (AsRPC ret)+callView = unsafeCallView @ret+  where _ = Dict @(HasView vd name arg ret) -- silence redundant constraint warning++-- | Version of 'callView' that doesn't check if the view exists in the type.+-- You'll have to specify the return type. You can use @TypeApplications@ syntax+-- for that.+--+-- If the view doesn't exist or has incorrect type, a test failure will be+-- thrown.+--+-- Note that first type argument is return type, the second is parameter type.+-- The reason for this inversion is you often only need to specify the return+-- type, while the parameter type can be either inferred or explicitly specified+-- with a type annotation on the parameter argument value.+--+-- Examples:+--+-- > unsafeCallView @() contract #id ()+-- Calls view @id@ with argument @unit@ and return type @unit@.+--+-- > unsafeCallView @(Integer, MText) contract #query [mt|hello|]+-- Calls view @query@ with argument @string@ and return type @pair int string@.+--+-- > unsafeCallView @Integer contract #sum (123 :: Natural, -321 :: Integer)+-- Calls view @sum@ with argument @pair nat int@ and return type @int@. Type+-- annotations are required due to polymorphic numeric literals.+--+-- This last example could also be written as+--+-- > unsafeCallView @Integer @(Natural, Integer) contract #sum (123, -321)+unsafeCallView+  :: forall ret arg name addr m caps.+    ( MonadCleveland caps m, NiceParameter arg, NiceViewable ret+    , NiceStorage ret, KnownSymbol name+    , HasRPCRepr ret, T.IsoValue (AsRPC ret)+    , ToContractAddress addr)+  => addr -- ^ Contract to call.+  -> Label name -- ^ View name. Use @OverloadedLabels@ syntax.+  -> arg -- ^ Parameter to pass to the view.+  -> m (AsRPC ret)+unsafeCallView (toContractAddress -> ch) _ arg = do+  Sender sender' <- Prelude.view senderL+  contractBalance <- getBalance ch+  let ct = runnerContract @name @arg @ret ch+      callFail = failure $ "Failed to call view " +| symbolValT' @name |++        ": either it doesn't exist or types don't match."+  res <- runCode RunCode+    { rcAmount = 0+    , rcBalance = contractBalance+    , rcSource = Just sender'+    , rcContract = ct+    , rcParameter = T.untypeValue $ T.toVal arg+    , rcStorage = T.untypeValue $ T.toVal (Nothing :: Maybe ret)+    , rcLevel = Nothing+    , rcNow = Nothing+    }+  maybe callFail pure res++-- | Contract that calls a view and saves the result to storage.+runnerContract+  :: forall name arg ret. (NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name)+  => ContractAddress -> Contract arg (Maybe ret) ()+runnerContract ch = flip Contract fakeDoc $ T.defaultContract $+  -- NB: It's not a Lorentz contract to avoid requiring NiceParameterFull and+  -- NiceStorageFull on arg and ret respectively.+  T.CAR :# T.DIP (T.PUSH $ toVal $ toAddress ch)+    :# T.VIEW (T.UnsafeViewName $ symbolValT' @name)+    :# T.NIL :# T.PAIR+  where+    fakeDoc = L.ContractCode $ L.fakeCoercing L.nop
src/Test/Cleveland/Internal/Client.hs view
@@ -1,8 +1,10 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Implementation that works with real Tezos network, it--- talks to a Tezos node and uses @tezos-client@.+-- talks to a Tezos node and uses @octez-client@.  module Test.Cleveland.Internal.Client   ( ClientM (..)@@ -34,7 +36,7 @@  import Control.Lens (_head, each, filtered) import Data.Aeson.Text qualified as J-import Data.Constraint (withDict, (\\))+import Data.Constraint (withDict) import Data.Default (def) import Data.Ratio ((%)) import Data.Set qualified as Set@@ -46,21 +48,23 @@  import Lorentz (NicePackedValue) import Lorentz qualified as L-import Lorentz.Constraints.Scopes (NiceUnpackedValue, niceParameterEvi)+import Lorentz.Constraints.Scopes (NiceUnpackedValue) import Morley.AsRPC (AsRPC, HasRPCRepr(..), TAsRPC, notesAsRPC, rpcSingIEvi)-import Morley.Client (MorleyClientEnv, OperationInfo(..), disableAlphanetWarning, runMorleyClientM)+import Morley.Client+  (AliasBehavior(..), MorleyClientEnv, OperationInfo(..), disableAlphanetWarning, runMorleyClientM) import Morley.Client qualified as Client import Morley.Client.Action (Result)+import Morley.Client.Action.Common (DelegationData(..), runErrorsToClientError) import Morley.Client.Action.Reveal qualified as RevealRPC import Morley.Client.App (failOnTimeout, retryOnceOnTimeout)-import Morley.Client.Init qualified as Client+import Morley.Client.Full qualified as Client import Morley.Client.Logging (logInfo, logWarning) import Morley.Client.RPC.Error qualified as RPC (ClientRpcError(..), RunCodeErrors(..)) import Morley.Client.RPC.Types   (AppliedResult(..), BlockConstants(bcHeader), BlockHeaderNoHash(bhnhLevel, bhnhTimestamp),   BlockId(..), IntOpEvent(..), OriginationScript(..),   ProtocolParameters(ProtocolParameters, ppCostPerByte, ppMinimalBlockDelay, ppOriginationSize))-import Morley.Client.TezosClient.Impl as TezosClient (getPublicKey, getSecretKey, importKey)+import Morley.Client.TezosClient.Impl qualified as TezosClient import Morley.Client.TezosClient.Types (tceMbTezosClientDataDirL) import Morley.Client.Util qualified as Client import Morley.Micheline@@ -77,10 +81,11 @@   (Mutez, Timestamp(..), addMutez, subMutez, timestampFromUTCTime, unsafeAddMutez, unsafeMulMutez,   unsafeSubMutez) import Morley.Tezos.Crypto+import Morley.Util.Constrained import Morley.Util.Exception import Morley.Util.Named import Test.Cleveland.Internal.Abstract-import Test.Cleveland.Internal.Exceptions (addCallStack)+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Lorentz (toL1Address) import Test.Cleveland.Util (ceilingUnit) @@ -91,7 +96,7 @@   -> Client.MorleyOnlyRpcEnv mkMorleyOnlyRpcEnvNetwork NetworkEnv{..} extraSecrets =   Client.MorleyOnlyRpcEnv-  { moreLogAction = Client.mkLogAction 0+  { moreLogAction = Client.mkLogAction neVerbosity   , moreClientEnv = Client.mceClientEnv neMorleyClientEnv   , moreSecretKeys = mconcat       [ one (mkKeyAddress (toPublic sk), sk)@@ -133,6 +138,7 @@  instance Exception MoneybagConfigurationException where   displayException = pretty+  fromException = fromPossiblyAnnotatedException  data ClientState = ClientState   { csDefaultAliasCounter :: DefaultAliasCounter@@ -155,6 +161,7 @@  instance Exception InternalNetworkScenarioError where   displayException = pretty+  fromException = fromPossiblyAnnotatedException  runNetworkT :: NetworkEnv -> NetworkT ClientM a -> IO a runNetworkT env scenario = do@@ -208,24 +215,24 @@         failOnTimeout ... TezosClient.importKey False neMoneybagAlias ek       return $ mkKeyAddress (toPublic ek) --- | Implementation that works with real network and uses @tezos-node@--- RPC and @tezos-client@.+-- | Implementation that works with real network and uses @octez-node@+-- RPC and @octez-client@. networkOpsImpl :: MorleyClientEnv -> Sender -> ClevelandOpsImpl ClientM networkOpsImpl env (Sender sender) =-  mapClevelandOpsImplExceptions (addCallStack . exceptionHandler)+  mapClevelandOpsImplExceptions (addCallStack . exceptionHandler env)     ClevelandOpsImpl     { coiRunOperationBatch = runOperationBatch env sender     }  networkMiscImpl :: NetworkEnv -> ClevelandMiscImpl ClientM networkMiscImpl env@NetworkEnv{..} =-  mapClevelandMiscImplExceptions (addCallStack . exceptionHandler) ClevelandMiscImpl+  mapClevelandMiscImplExceptions (addCallStack . exceptionHandler neMorleyClientEnv) ClevelandMiscImpl     { cmiRunIO = liftIO      , cmiOriginateLargeUntyped = \(Sender sender) UntypedOriginateData{..} -> do         let originationScenario =-              Client.originateLargeUntypedContract True uodName (AddressResolved sender)-                uodBalance uodContract uodStorage Nothing+              Client.originateLargeUntypedContract OverwriteDuplicateAlias uodName+                (AddressResolved sender) uodBalance uodContract uodStorage Nothing uodDelegate         -- Note that tezos key reveal operation cost an additional fee         -- so that's why we reveal keys in origination and transaction         -- rather than doing it before scenario execution@@ -247,14 +254,11 @@         alias <- resolveSpecificOrDefaultAlias sodAlias         liftIO $ runMorleyClientM neMorleyClientEnv $ Client.genFreshKey alias -    , cmiGetBalance = \(MkConstrainedAddress a) -> getBalanceHelper a+    , cmiGetBalance = foldConstrained getBalanceHelper     , cmiGetChainId = liftIO $ runMorleyClientM neMorleyClientEnv Client.getChainId     , cmiAttempt = try     , cmiThrow = throwM     , cmiMarkAddressRefillable = setAddressRefillable-    , cmiRegisterDelegate = \addr -> liftIO $ runMorleyClientM neMorleyClientEnv $ do-        alias <- Client.getAlias (AddressResolved addr)-        Client.registerDelegate alias Nothing     , cmiComment = comment     , cmiUnderlyingImpl = pure $ Right env     , cmiFailure = clientFailure@@ -327,7 +331,7 @@     getBalanceHelper :: L1AddressKind kind => KindedAddress kind -> ClientM Mutez     getBalanceHelper = liftIO . runMorleyClientM neMorleyClientEnv . Client.getBalance -    cmiGetDelegate :: ContractAddress -> ClientM (Maybe KeyHash)+    cmiGetDelegate :: L1Address -> ClientM (Maybe KeyHash)     cmiGetDelegate =       liftIO . runMorleyClientM neMorleyClientEnv . Client.getDelegate @@ -389,7 +393,7 @@     cmiRunCode       :: forall cp st vd. (HasRPCRepr st, T.IsoValue (AsRPC st))       => Sender -> RunCode cp st vd -> ClientM (AsRPC st)-    cmiRunCode (Sender sender) (RunCode rcContract rcParameter rcStorage rcAmount rcLevel rcNow rcBalance rcSource) =+    cmiRunCode (Sender sender) (RunCode rcContract rcParameter rcStorage rcAmount rcLevel rcNow rcBalance rcSource) = do       liftIO $ runMorleyClientM neMorleyClientEnv do         -- Pattern match on the contract constructor to reveal         -- a proof of `NiceStorage st`@@ -405,7 +409,11 @@           , rcpNow = rcNow           , rcpSender = Just sender           }-          \\ L.niceStorageEvi @st+      `catch` \case+        err@(RPC.RunCodeErrors errs)+          | Just clientErr <- runErrorsToClientError errs+          -> throwM =<< exceptionToTransferFailure neMorleyClientEnv clientErr+          | otherwise -> throwM err  clientFailure :: Builder -> ClientM a clientFailure = throwM . CustomTestError . pretty@@ -418,8 +426,15 @@   => MorleyClientEnv   -> KindedAddress kind   -> ClientM (Alias kind)-getAlias env = liftIO . runMorleyClientM env . Client.getAlias . AddressResolved+getAlias env = liftIO . runMorleyClientM env . TezosClient.getAlias . AddressResolved +getAliasMaybe+  :: L1AddressKind kind+  => MorleyClientEnv+  -> KindedAddress kind+  -> ClientM (Maybe (Alias kind))+getAliasMaybe env = liftIO . runMorleyClientM env . Client.getAliasMaybe . AddressResolved+ getLastBlockTimestamp :: MorleyClientEnv -> ClientM UTCTime getLastBlockTimestamp env = liftIO $   bhnhTimestamp . bcHeader <$> runMorleyClientM env (Client.getBlockConstants HeadId)@@ -452,6 +467,11 @@         { rdPublicKey = key         , rdMbFee = Nothing         }+    OpDelegation delegate ->+      pure $ OpDelegation DelegationData+        { ddDelegate = delegate+        , ddMbFee = Nothing+        }    let refill :: Word -> Client.MorleyClientM Word       refill iter = do@@ -524,6 +544,7 @@               OpOriginate uod -> (uodBalance uod, originationSz)               OpTransfer td -> (tdAmount td, 0)               OpReveal _ -> (zeroMutez, 0)+              OpDelegation _ -> (zeroMutez, 0)             storageDiff AppliedResult{..} = safetyStorage + Unsafe.fromIntegral @TezosInt64 @Natural arPaidStorageDiff             storageBurnInBytes = originationSize + sum (map storageDiff appliedResults)             storageBurnInMutez = unsafeMulMutez costPerByte storageBurnInBytes@@ -548,6 +569,7 @@       comment $ "Originated smart contract '" +| alias |+         "' with address " <> pretty addr     OpReveal () -> pass+    OpDelegation () -> pass    mapM toClevelandResult results @@ -556,6 +578,7 @@   OpTransfer ops -> OpTransfer <$> mapM intOpEventToContractEvent ops   OpOriginate ops -> pure $ OpOriginate ops   OpReveal ops -> pure $ OpReveal ops+  OpDelegation ops -> pure $ OpDelegation ops  intOpEventToContractEvent :: IntOpEvent -> ClientM ContractEvent intOpEventToContractEvent IntOpEvent{..} = do@@ -605,19 +628,28 @@ findCantPayStorageFee (_:xs) = findCantPayStorageFee xs findCantPayStorageFee [] = False -exceptionToTransferFailure :: RPC.ClientRpcError -> ClientM TransferFailure-exceptionToTransferFailure = \case-  RPC.ContractFailed addr expr -> return $ TransferFailure (AddressAndAlias (MkAddress addr) Nothing) $-    FailedWith (EOTVExpression expr) Nothing-  RPC.BadParameter addr _ -> return $ TransferFailure (AddressAndAlias addr Nothing) BadParameter-  RPC.EmptyTransaction addr -> return $ TransferFailure (AddressAndAlias (MkAddress addr) Nothing) EmptyTransaction-  RPC.ShiftOverflow addr -> return $ TransferFailure (AddressAndAlias (MkAddress addr) Nothing) ShiftOverflow-  RPC.GasExhaustion addr -> return $ TransferFailure (AddressAndAlias (MkAddress addr) Nothing) GasExhaustion-  internalError -> throwM internalError+resolveAddressAndAlias :: MorleyClientEnv -> KindedAddress kind -> ClientM AddressAndAlias+resolveAddressAndAlias env addr =+   case addr of+     ImplicitAddress{} -> AddressAndAlias addr <$> getAliasMaybe env addr+     ContractAddress{} -> AddressAndAlias addr <$> getAliasMaybe env addr+     TxRollupAddress{} -> pure (AddressAndAlias addr Nothing) -exceptionHandler :: ClientM a -> ClientM a-exceptionHandler action = try action >>= \case-  Left err -> exceptionToTransferFailure err >>= throwM+exceptionToTransferFailure :: MorleyClientEnv -> RPC.ClientRpcError -> ClientM TransferFailure+exceptionToTransferFailure env = \case+    RPC.ContractFailed addr expr -> mkTransferFailure addr $ FailedWith (EOTVExpression expr) Nothing+    RPC.BadParameter (MkAddress addr) _ -> mkTransferFailure addr BadParameter+    RPC.EmptyTransaction addr -> mkTransferFailure addr EmptyTransaction+    RPC.ShiftOverflow addr -> mkTransferFailure addr ShiftOverflow+    RPC.GasExhaustion addr -> mkTransferFailure addr GasExhaustion+    internalError -> throwM internalError+    where+      mkTransferFailure :: KindedAddress kind -> TransferFailureReason -> ClientM TransferFailure+      mkTransferFailure addr e = TransferFailure <$> resolveAddressAndAlias env addr <*> pure e++exceptionHandler :: MorleyClientEnv -> ClientM a -> ClientM a+exceptionHandler env action = try action >>= \case+  Left err -> exceptionToTransferFailure env err >>= throwM   Right res -> return res  resolveSpecificOrDefaultAlias :: SpecificOrDefaultAlias -> ClientM ImplicitAlias@@ -651,12 +683,13 @@     throwLeft . pure $ typeCheckingWith def $       typeCheckContractAndStorage uodContract uodStorage   return Client.OriginationData-    { odReplaceExisting = True+    { odAliasBehavior = OverwriteDuplicateAlias     , odName = uodName     , odBalance = uodBalance     , odContract = contract     , odStorage = storage     , odMbFee = Nothing+    , odDelegate = uodDelegate     }  convertTransferData@@ -668,7 +701,7 @@     , tdEpName = tdEntrypoint     , tdParam = toVal param     , tdMbFee = Nothing-    } \\ niceParameterEvi @p+    }  -- | Runs 'Client.revealKeyUnlessRevealed' with given client environment. revealKeyUnlessRevealed :: MorleyClientEnv -> ImplicitAddress -> IO ()@@ -687,6 +720,7 @@  instance Exception TestError where   displayException = pretty+  fromException = fromPossiblyAnnotatedException  instance Buildable TestError where   build (CustomTestError msg) = build msg
src/Test/Cleveland/Internal/Exceptions.hs view
@@ -1,87 +1,27 @@--- SPDX-FileCopyrightText: 2021 Oxhead Alpha+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA --- | This module defines common exception types and exception-related functions--- used throughout the "Test.Cleveland" modules.-module Test.Cleveland.Internal.Exceptions-  ( WithCallStack(..)-  , addCallStack-  , throwWithCallStack-  , tryWithCallStack-  , catchWithCallStack-  ) where--import Data.Typeable (cast)-import Fmt (Buildable(..), pretty, unlinesF)--------------------------------------------------------------------------------- WithCallStack--------------------------------------------------------------------------------- | Wraps an exception and adds some callstack information.-data WithCallStack where-  WithCallStack :: CallStack -> SomeException -> WithCallStack--deriving stock instance Show WithCallStack--instance Buildable WithCallStack where-  build (WithCallStack cstack e) = unlinesF-    [ prettyCallStack cstack-    , displayException e-    ]--instance Exception WithCallStack where-  displayException = pretty---- | Wrap any exceptions thrown by some monadic action with 'WithCallStack'.------ If the action throws an exception already wrapped in 'WithCallStack',--- that callstack will be overriden with the current one.-addCallStack :: forall m a. (HasCallStack, MonadCatch m) => m a -> m a-addCallStack ma =-  ma `catch` \se@(SomeException ex) ->-    case fromException @WithCallStack se of-      Just (WithCallStack _ innerEx) -> throwWithCallStack callStack innerEx-      Nothing -> throwWithCallStack callStack ex--throwWithCallStack :: forall e a m. (MonadThrow m, Exception e) => CallStack -> e -> m a-throwWithCallStack cstack ex = throwM (WithCallStack cstack (toException ex))+{-# OPTIONS_HADDOCK not-home #-} +-- | This module defines common exception helpers.+module Test.Cleveland.Internal.Exceptions+  ( ExceptionAnnotation(..)+  , annotateExceptions+  , fromPossiblyAnnotatedException --- | Similar to 'catch', but also catches exceptions of type @e@ wrapped in 'WithCallStack'.-catchWithCallStack-  :: forall e a m. (Exception e, MonadCatch m)-  => m a -> (Maybe CallStack -> e -> m a) -> m a-catchWithCallStack ma f =-  ma `catch` \(se :: SomeException) ->-    case fromExceptionWithCallStack @e se of-      Just (cstackMb, e) -> f cstackMb e-      Nothing -> throwM se+  -- * Utilities+  , lookupAnnEx+  , insertAnnEx+  , removeAnnEx --- | Attempts to run the given action.------ If it:------ * suceeds, the value will be returned in a 'Right'.--- * throws an exception of the given type @e@ (or an exception of---   type @e@ wrapped in 'WithCallStack'), it will be returned in a 'Left'.--- * throws an exception of any other type, it'll be rethrown---   (retaining the original callstack, if any).-tryWithCallStack :: forall e a m. (MonadCatch m, Exception e) => m a -> m (Either (Maybe CallStack, e) a)-tryWithCallStack ma =-  try @_ @SomeException ma >>= \case-    Right a -> pure (Right a)-    Left se ->-      case fromExceptionWithCallStack @e se of-        Just e -> pure (Left e)-        Nothing -> throwM se+  -- * Specific annotations+  , ErrorsClarification(..)+  , ScenarioBranchName(..)+  , CallStackAnnotation(..)+  , addCallStack+  ) where -fromExceptionWithCallStack :: forall e. Exception e => SomeException -> Maybe (Maybe CallStack, e)-fromExceptionWithCallStack se =-  (do-    WithCallStack cstack e <- fromException @WithCallStack se-    e' <- cast @_ @e e-    Just (Just cstack, e')-  )-  <|>-  (fromException @e se <&> (Nothing,))+import Test.Cleveland.Internal.Exceptions.Annotated+import Test.Cleveland.Internal.Exceptions.CallStack+import Test.Cleveland.Internal.Exceptions.ErrorsClarification+import Test.Cleveland.Internal.Exceptions.ScenarioBranchName
+ src/Test/Cleveland/Internal/Exceptions/Annotated.hs view
@@ -0,0 +1,183 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_HADDOCK not-home #-}++-- | This module defines annotated exceptions and machinery to work with them.+module Test.Cleveland.Internal.Exceptions.Annotated+  ( module Test.Cleveland.Internal.Exceptions.Annotated+  ) where++import Data.Dependent.Map qualified as Map+import Data.GADT.Compare (GCompare(..), GEq(..), GOrdering(..))+import Data.Typeable (cast, eqT)+import Fmt (Buildable(..), Builder, build, pretty)+import Text.Show qualified as Show (Show(..))+import Type.Reflection (typeRep)++-- $setup+-- >>> import Test.Cleveland.Internal.Abstract+-- >>> import Test.Cleveland.Internal.Exceptions.CallStack++----------------------------------------------------------------------------+-- AnnotatedException+----------------------------------------------------------------------------++-- | 'SomeException' augmented with arbitrary annotations.+data AnnotatedException = AnnotatedException AnnotationMap SomeException+  deriving stock Show++instance Exception AnnotatedException where+  displayException (AnnotatedException annmap e) =+    pretty $ printAnnotations annmap (displayException e)++-- | Insert a new annotation into 'AnnotatedException'.+insertAnnEx'+  :: (Semigroup ann, ExceptionAnnotation ann)+  => ann -> AnnotatedException -> AnnotatedException+insertAnnEx' ann (AnnotatedException anns ex) = AnnotatedException (insertAnn ann anns) ex++-- | Insert a new annotation into 'SomeException'.+--+-- If it's already an 'AnnotatedException', simply adds a new annotation.+-- Otherwise, wraps the exception into 'AnnotatedException' first.+insertAnnEx+  :: (Semigroup ann, ExceptionAnnotation ann)+  => ann -> SomeException -> SomeException+insertAnnEx ann se = toException $! case fromException @AnnotatedException se of+  Just ex -> insertAnnEx' ann ex+  Nothing -> AnnotatedException (singletonAnn ann) se++-- | Remove an annotation of the given type from 'AnnotatedException'.+removeAnnEx' :: forall ann. ExceptionAnnotation ann => AnnotatedException -> AnnotatedException+removeAnnEx' (AnnotatedException anns ex) = AnnotatedException (removeAnn @ann anns) ex++-- | Remove an annotation of the given type from 'SomeException'. If it's not an+-- 'AnnotatedException', this is a no-op.+removeAnnEx :: forall ann. ExceptionAnnotation ann => SomeException -> SomeException+removeAnnEx se = case fromException @AnnotatedException se of+  Just ex -> toException $ removeAnnEx' @ann ex+  Nothing -> se++-- | Extract the given annotation type from 'AnnotatedException' if possible.+lookupAnnEx' :: forall ann. (ExceptionAnnotation ann) => AnnotatedException -> Maybe ann+lookupAnnEx' (AnnotatedException anns _) = lookupAnn @ann anns++-- | Extract the given annotation type from 'SomeException' if possible.+lookupAnnEx :: forall ann. (ExceptionAnnotation ann) => SomeException -> Maybe ann+lookupAnnEx se = lookupAnnEx' =<< fromException @AnnotatedException se++{- | Try to extract a given exception type, skipping over annotations. This+essentially makes 'AnnotatedException' transparent for this function.++This is intended to be used as the default implementation of 'fromException' for+exception types that are expected to be annotated, as to make+'AnnotatedException' transparent for 'catch', 'try', etc.++For example:++@+instance Exception GenericTestError where+  displayException = pretty+  fromException = fromPossiblyAnnotatedException+@++Now, when catching @GenericTestError@, it'll work even if wrapped in+'AnnotatedException':++>>> try @_ @GenericTestError (addCallStack $ throwM UnexpectedSuccess)+Left UnexpectedSuccess++When catching exceptions not explicitly set up like this, this trick+unfortunately won't work, so using this function explicitly is required:++>>> data ExceptionToCatch = ExceptionToCatch deriving stock Show+>>> instance Exception ExceptionToCatch+>>> action = addCallStack $ throwM ExceptionToCatch+>>> try @_ @ExceptionToCatch action+*** Exception: AnnotatedException ...+...ExceptionToCatch+>>> :{+action `catch` \(err :: SomeException) -> case fromPossiblyAnnotatedException err of+  Just (err' :: ExceptionToCatch) -> pass+  Nothing -> throwM err+:}+-}+fromPossiblyAnnotatedException :: Exception e => SomeException -> Maybe e+fromPossiblyAnnotatedException se =+  (do+    AnnotatedException _ e <- fromException se+    fromException e+  ) <|> fromExceptionDefault se+  where+    fromExceptionDefault (SomeException e) = cast e++----------------------------------------------------------------------------+-- AnnotationMap+----------------------------------------------------------------------------++data Key ann where+  Key :: ExceptionAnnotation a => Key a++instance GEq Key where+  geq (Key :: Key a) (Key :: Key b) = eqT @a @b++instance GCompare Key where+  gcompare (Key :: Key a) (Key :: Key b) =+    case compare (annotationPriority @a) (annotationPriority @b) of+      LT -> GLT+      GT -> GGT+      EQ -> gcompare (typeRep @a) (typeRep @b)++-- | A map from 'Key' to corresponding annotation.+newtype AnnotationMap = AnnotationMap { unAnnotationMap :: Map.DMap Key Identity }++instance Show AnnotationMap where+  show = Map.showTreeWith (\Key -> Show.show) True False . unAnnotationMap++-- | Print all annotations from an 'AnnotationMap', given the initial message.+--+-- Essentially right-fold using 'displayAnnotation'.+printAnnotations :: Buildable a => AnnotationMap -> a -> Builder+printAnnotations (AnnotationMap annmap) = flip (Map.foldrWithKey go) annmap . build+  where+    go :: Key t -> Identity t -> Builder -> Builder+    go Key (Identity a) acc = displayAnnotation a acc++-- | Try to find the given type @t@ in an 'AnnotationMap'.+lookupAnn :: ExceptionAnnotation t => AnnotationMap -> Maybe t+lookupAnn (AnnotationMap anns) = runIdentity <$> Map.lookup Key anns++-- | Construct a singleton 'AnnotationMap'.+singletonAnn :: ExceptionAnnotation t => t -> AnnotationMap+singletonAnn = AnnotationMap . Map.singleton Key . Identity++-- | Insert a new annotation into an 'AnnotationMap'. If an annotation of this+-- type already exists, merge the annotations using the 'Semigroup' instance.+insertAnn :: (Semigroup t, ExceptionAnnotation t) => t -> AnnotationMap -> AnnotationMap+insertAnn x (AnnotationMap anns) = AnnotationMap $ Map.insertWith (<>) Key (Identity x) anns++-- | Remove an annotation of a given type @t@ from 'AnnotationMap'.+removeAnn :: forall t. ExceptionAnnotation t => AnnotationMap -> AnnotationMap+removeAnn (AnnotationMap am) = AnnotationMap $ Map.delete (Key @t) am++----------------------------------------------------------------------------+-- ExceptionAnnotation+----------------------------------------------------------------------------++-- | Type class for exception annotations.+class (Show ann, Typeable ann) => ExceptionAnnotation ann where+  -- | Given an annotation and the error message (as 'Builder'), produce the+  -- text annotated with the annotation.+  displayAnnotation :: ann -> Builder -> Builder++  -- | Relative priority for sorting annotations. Annotations with higher+  -- priority will be applied first. Default is @0@.+  annotationPriority :: Int+  annotationPriority = 0++-- | Add an annotation to exceptions thrown by a monadic action.+annotateExceptions+  :: forall m a ann. (MonadCatch m, Semigroup ann, ExceptionAnnotation ann)+  => ann -> m a -> m a+annotateExceptions ann ma = ma `catch` (throwM . insertAnnEx ann)
+ src/Test/Cleveland/Internal/Exceptions/CallStack.hs view
@@ -0,0 +1,55 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_HADDOCK not-home #-}++-- | This module defines 'CallStackAnnotation' and required helpers and+-- instances to use it with 'ExceptionAnnotation'.+module Test.Cleveland.Internal.Exceptions.CallStack+  ( CallStackAnnotation(..)+  , addCallStack+  ) where++import Fmt (build, unlinesF)+import GHC.Exception (SrcLoc(..), fromCallSiteList)+import GHC.Stack (popCallStack)++import Test.Cleveland.Internal.Exceptions.Annotated++-- | Newtype wrapper for 'CallStack' to avoid orphan instances.+--+-- Has instance of 'ExceptionAnnotation'.+newtype CallStackAnnotation = CallStackAnnotation { unCallStackAnnotation :: CallStack }+  deriving stock Show++-- | A convenience synonym for @annotateExceptions (CallStackAnnotation callStack)@.+addCallStack :: (MonadCatch m, HasCallStack) => m a -> m a+addCallStack = annotateExceptions (CallStackAnnotation $ popCallStack callStack)+-- NB: 'popCallStack' is required to hide 'addCallStack' itself from the stack.++instance ExceptionAnnotation CallStackAnnotation where+  displayAnnotation cs acc = unlinesF+    [ acc+    , ""+    , build $ prettyCallStack $ unCallStackAnnotation cs+    ]+  annotationPriority = -1000+  -- NB: we want call stacks to be basically printed last.++instance Semigroup CallStackAnnotation where+  a <> b = CallStackAnnotation $ unCallStackAnnotation a `mergeCallStacks` unCallStackAnnotation b++-- | Merge two 'CallStack's, removing duplicates, but keeping the ordering.+mergeCallStacks :: CallStack -> CallStack -> CallStack+mergeCallStacks a b = fromCallSiteList+  $ fmap (fmap unOrdSrcLoc)+  $ ordNub+  $ fmap (fmap OrdSrcLoc)+  $ getCallStack a <> getCallStack b++newtype OrdSrcLoc = OrdSrcLoc { unOrdSrcLoc :: SrcLoc }+  deriving newtype Eq++instance Ord OrdSrcLoc where+  compare (OrdSrcLoc (SrcLoc a b c d e f g)) (OrdSrcLoc (SrcLoc a' b' c' d' e' f' g'))+    = compare (a, b, c, d, e, f, g) (a', b', c', d', e', f', g')
+ src/Test/Cleveland/Internal/Exceptions/ErrorsClarification.hs view
@@ -0,0 +1,24 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_HADDOCK not-home #-}++-- | This module defines 'ErrorsClarification' and required instances to use it+-- with 'ExceptionAnnotation'.+module Test.Cleveland.Internal.Exceptions.ErrorsClarification+  ( ErrorsClarification(..)+  ) where++import Fmt (Builder, nameF)++import Test.Cleveland.Internal.Exceptions.Annotated++-- | Used to add text prefixes to exception messages.+--+-- Implementation detail of 'Test.Cleveland.clarifyErrors'.+newtype ErrorsClarification = ErrorsClarification [Builder]+  deriving stock Show+  deriving newtype Semigroup++instance ExceptionAnnotation ErrorsClarification where+  displayAnnotation (ErrorsClarification as) = flip (foldr nameF) as
+ src/Test/Cleveland/Internal/Exceptions/ScenarioBranchName.hs view
@@ -0,0 +1,26 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++{-# OPTIONS_HADDOCK not-home #-}++-- | This module defines 'ScenarioBranchName' and required instances to use it+-- with 'ExceptionAnnotation'.+module Test.Cleveland.Internal.Exceptions.ScenarioBranchName+  (ScenarioBranchName(..)+  ) where++import Fmt (Buildable(..), nameF, (+|), (|+))++import Test.Cleveland.Internal.Exceptions.Annotated++-- | When using 'Test.Cleveland.branchout' function for building test scenarios - names+-- of branches we are currently within.+newtype ScenarioBranchName = ScenarioBranchName { unTestBranch :: [Text] }+  deriving stock (Show, Eq)+  deriving newtype Semigroup++instance ExceptionAnnotation ScenarioBranchName where+  displayAnnotation ann = nameF ("In branch '" +| ann |+ "'")++instance Buildable ScenarioBranchName where+  build = mconcat . intersperse "/" . map build . unTestBranch
src/Test/Cleveland/Internal/Hedgehog.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Hedgehog-related helpers module Test.Cleveland.Internal.Hedgehog   ( MonadTest (..)@@ -19,7 +21,7 @@ import Hedgehog.Internal.Property (Failure(..), MonadTest(..), mkTest) import Hedgehog.Internal.Source (ColumnNo(..), LineNo(..), Span(..)) -import Test.Cleveland.Internal.Exceptions (WithCallStack(..))+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Internal.Pure import Test.Cleveland.Internal.Scenario @@ -33,11 +35,8 @@  failWithException :: (HasCallStack, MonadTest m) => SomeException -> m a failWithException e =-  case fromException @WithCallStack e of-    Just (WithCallStack cs _) -> failWithCallStack cs message-    _                         -> failWithCallStack callStack message-  where-    message = formatException e+  failWithCallStack (fromMaybe callStack $ unCallStackAnnotation <$> lookupAnnEx e) $+    formatException e  failWithCallStack :: (MonadTest m) => CallStack -> String -> m a failWithCallStack cs message = liftTest $ mkTest
src/Test/Cleveland/Internal/Pure.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Integration with integrational testing engine (pun intended). module Test.Cleveland.Internal.Pure   ( PureM(..)@@ -17,9 +19,7 @@   , initEnv    -- * Support functions-  , failedInsideBranch   , moneybagAlias-  , emptyScenarioBranch    -- * Optics   , psSecretKeys@@ -31,7 +31,7 @@   , psGState   ) where -import Control.Lens (assign, at, each, makeLenses, modifying, to, (%=), (.=), (?=), (?~))+import Control.Lens (assign, at, makeLenses, modifying, to, (%=), (.=), (?=), (?~)) import Control.Lens.Unsound (lensProduct) import Control.Monad.Catch.Pure (CatchT, runCatchT) import Control.Monad.Writer (MonadWriter, WriterT, listen, runWriterT, tell)@@ -51,33 +51,32 @@ import Morley.Michelson.Interpret   (InterpretError(..), InterpretResult(..), MichelsonFailed(..), MichelsonFailureWithStack(..)) import Morley.Michelson.Runtime hiding (ExecutorOp(..), transfer)-import Morley.Michelson.Runtime qualified as Runtime (ExecutorOp(..))+import Morley.Michelson.Runtime qualified as Runtime import Morley.Michelson.Runtime.Dummy   (dummyLevel, dummyMaxSteps, dummyMinBlockTime, dummyNow, dummyOrigination) import Morley.Michelson.Runtime.GState-  (GState(..), genesisAddress, genesisSecretKey, gsChainIdL, gsContractAddressAliasesL,-  gsContractAddressesL, gsCounterL, gsImplicitAddressAliasesL, gsVotingPowersL, initGState,-  lookupBalance)-import Morley.Michelson.TypeCheck-  (BigMapFinder, TCError(..), TypeCheckOptions(..), typeCheckContractAndStorage,-  typeCheckValueRunCodeCompat, typeCheckingWith)+  (AddressStateFam, GState(..), ImplicitState(..), addressesL, genesisAddress, genesisSecretKey,+  gsChainIdL, gsContractAddressAliasesL, gsContractAddressesL, gsImplicitAddressAliasesL,+  gsVotingPowersL, initGState, lookupBalance)+import Morley.Michelson.TypeCheck (TcError, typeCheckContractAndStorage, typeCheckingWith) import Morley.Michelson.Typed-  (BigMapId(..), IsoValue, SingI, SomeAnnotatedValue(..), SomeConstrainedValue(SomeValue),-  SomeVBigMap(..), SomeValue, ToT, Value, Value'(..), castM, dfsFoldMapValue, fromVal, toVal)+  (BigMapId(..), IsoValue, SingI, SomeAnnotatedValue(..), SomeVBigMap(..), ToT, Value, Value'(..),+  castM, fromVal, toVal) import Morley.Michelson.Typed qualified as T import Morley.Michelson.Typed.Operation-  (EmitOperation(..), OriginationOperation(..), TransferOperation(..))+  (EmitOperation(..), OriginationOperation(..), SetDelegateOperation(..), TransferOperation(..)) import Morley.Michelson.Untyped qualified as U import Morley.Tezos.Address import Morley.Tezos.Address.Alias import Morley.Tezos.Core (Timestamp, timestampPlusSeconds, unsafeSubMutez, zeroMutez)-import Morley.Tezos.Crypto (SecretKey(..), detSecretKey, sign, toPublic)+import Morley.Tezos.Crypto (KeyHash, SecretKey(..), detSecretKey, sign, toPublic)+import Morley.Util.Constrained import Morley.Util.MismatchError import Morley.Util.Named  import Morley.Util.Bimap qualified as Bimap import Test.Cleveland.Internal.Abstract-import Test.Cleveland.Internal.Exceptions (addCallStack, catchWithCallStack, throwWithCallStack)+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Lorentz import Test.Cleveland.Util (ceilingUnit) @@ -103,7 +102,7 @@                     MonadReader (IORef PureState), MonadWriter LogsInfo, MonadFail)  data TestError-  = UnexpectedTypeCheckError TCError+  = UnexpectedTypeCheckError TcError   | UnexpectedStorageType (MismatchError T.T)   | UnexpectedBigMapType Natural (MismatchError T.T)   | CustomTestError Text@@ -126,6 +125,7 @@  instance Exception TestError where   displayException = pretty+  fromException = fromPossiblyAnnotatedException  moneybagAlias :: ImplicitAlias moneybagAlias = ImplicitAlias "moneybag"@@ -151,8 +151,7 @@         forM_ scenarios $ \(name, scenario) -> do           aliasesState <- get           newRef <- newIORef aliasesState-          local (\_ -> newRef) scenario `catchWithCallStack` \originalCallStackMb err ->-            maybe throwM throwWithCallStack originalCallStackMb $ failedInsideBranch name err+          local (\_ -> newRef) scenario & annotateExceptions (ScenarioBranchName [name])       , eiGetStorage = addCallStack . exceptionHandler . getStorageImpl     , eiGetMorleyLogs = getMorleyLogsImpl     , eiSetVotingPowers = assign (psGState . gsVotingPowersL)@@ -164,7 +163,7 @@     ClevelandOpsImpl     { coiRunOperationBatch = mapM \case         OpOriginate UntypedOriginateData{..} -> do-          OpOriginate <$> originate uodContract uodName uodStorage uodBalance+          OpOriginate <$> originate uodContract uodName uodStorage uodBalance uodDelegate         OpTransfer TransferData{..} -> do           let fromAddr = #from :! sender           let toAddr = #to :! toL1Address tdTo@@ -187,6 +186,7 @@         OpReveal{} -> do           -- We do not care about reveals in our Morley runtime           return $ OpReveal ()+        OpDelegation mbAddress -> OpDelegation <$> setDelegate sender mbAddress     }  emitOpToContractEvent :: EmitOperation -> ContractEvent@@ -231,10 +231,9 @@     , cmiComment = const pass     , cmiGetPublicKey = \addr -> do         toPublic <$> getSecretKey addr-    , cmiGetDelegate = \addr -> do-        ContractState _ _ _ delegate <- contractStorage addr-        pure delegate-    , cmiRegisterDelegate = const pass+    , cmiGetDelegate = \(Constrained addr) -> addressState addr <&> case addr of+        ContractAddress{} -> csDelegate+        ImplicitAddress{} -> isDelegate     , cmiGetChainId = use $ psGState . gsChainIdL     , cmiAdvanceTime = \time -> do         modifying psNow . flip timestampPlusSeconds $@@ -250,7 +249,7 @@     , cmiAttempt = try     , cmiThrow = throwM     , cmiMarkAddressRefillable = setAddressRefillable-    , cmiGetBalance = \(MkConstrainedAddress a) -> getBalance a+    , cmiGetBalance = foldConstrained getBalance     , cmiUnderlyingImpl = pure $ Left emulatedImpl     , cmiFailure = failure     , ..@@ -260,7 +259,7 @@      originateUntyped :: Sender -> UntypedOriginateData 'IsLarge -> PureM ContractAddress     originateUntyped _ UntypedOriginateData {..} = do-      originate uodContract uodName uodStorage uodBalance+      originate uodContract uodName uodStorage uodBalance uodDelegate      cmiGetBigMapValueMaybe       :: forall k v.@@ -284,7 +283,7 @@       VBigMap _ bigMap <- findBigMapByIdMaybe @(ToT k) @(ToT v) bmId       pure $ fromVal @v <$> Map.elems bigMap -    -- | In a real chain, when we retrieve a contract's storage via the Tezos RPC,+    -- In a real chain, when we retrieve a contract's storage via the Tezos RPC,     -- the storage expression will have all the big_maps replaced with their respective big_map IDs.     --     -- Here, we mimic the RPC's behaviour.@@ -296,7 +295,7 @@     --   * A contract's code is run and it calls `EMPTY_BIG_MAP`, `DUP` or `DUP n`.     cmiGetSomeStorage :: ContractAddress -> PureM SomeAnnotatedValue     cmiGetSomeStorage addr = do-      ContractState _ contract (storage :: Value t) _ <- contractStorage addr+      ContractState _ contract (storage :: Value t) _ <- addressState addr       pure $         SomeAnnotatedValue           (notesAsRPC $ T.cStoreNotes contract)@@ -336,87 +335,38 @@       :: forall cp st vd. (HasRPCRepr st, T.IsoValue (AsRPC st))       => Sender -> RunCode cp st vd -> PureM (AsRPC st)     cmiRunCode (Sender sender) (RunCode rcContract rcParameter rcStorage rcAmount rcLevel rcNow rcBalance rcSource) = do-      -- Pattern match on the contract constructor to reveal-      -- a proof of `NiceParameter cp` and `NiceStorage st`-      L.Contract{} <- pure rcContract-      param <- typeCheckVal @(ToT cp) rcParameter-      storage <- typeCheckVal @(ToT st) rcStorage+      contract@T.Contract{..} <- pure $ L.toMichelsonContract rcContract+      T.MkEntrypointCallRes _ (epc :: T.EntrypointCallT (T.ToT cp) arg) <- pure $+        T.mkDefEntrypointCall cParamNotes        (now, level) <- use $ psNow `lensProduct` psLevel-      psNow %= maybe id const rcNow-      psLevel %= maybe id const rcLevel-      res <- interpret do-        counter0 <- use $ esGState . gsCounterL-        contractAddr <--          executeOrigination ! #isGlobalOp True $-            (dummyOrigination storage (L.toMichelsonContract rcContract) counter0) { ooBalance = zeroMutez }-              \\ L.niceStorageEvi @st-              \\ L.niceParameterEvi @cp--        esSourceAddress .= (MkConstrainedAddress <$> rcSource)-        counter1 <- use $ esGState . gsCounterL-        let overrideContractBalance = Just rcBalance-        executeTransfer (#isGlobalOp :! False) overrideContractBalance def $-          TransferOperation-            { toDestination = MkAddress contractAddr-            , toCounter = counter1-            , toTxData = TxData-              { tdSenderAddress = MkConstrainedAddress sender-              , tdParameter = TxTypedParam param \\ L.niceParameterEvi @cp-              , tdEntrypoint = DefEpName-              , tdAmount = rcAmount-              }+      knownContracts <- use $ psGState . gsContractAddressesL+      bigMapFinder <- registerInterpretation Runtime.mkBigMapFinder+      let tcBm :: forall (t :: T.T). T.SingI t => U.Value -> PureM (T.Value t)+          tcBm = either (throwM . UnexpectedTypeCheckError) pure .+            resolveRunCodeBigMaps bigMapFinder+      rcParameterT <- tcBm rcParameter+      rcStorageT <- tcBm rcStorage+      (_, finalStorage) <- either (throwEE . EEInterpreterFailed (toAddress sender)) pure $+        Runtime.runCode+          (Runtime.runCodeParameters contract rcStorageT epc rcParameterT)+            { Runtime.rcAmount = rcAmount+            , Runtime.rcLevel = fromMaybe level rcLevel+            , Runtime.rcNow = fromMaybe now rcNow+            , Runtime.rcBalance = rcBalance+            , Runtime.rcSource = Constrained $ fromMaybe genesisAddress rcSource+            , Runtime.rcKnownContracts = knownContracts+            , Runtime.rcSender = Constrained sender             }-        pure contractAddr-      psNow .= now-      psLevel .= level-      case res of-        Left executorError -> throwEE executorError-        Right (executorRes, contractAddr) -> do-          -- Find the storage of the contract and return it in its RPC representation.-          case executorRes ^. erGState . gsContractAddressesL . at contractAddr of-            Nothing ->-              failure $ "Internal error: failed to find contract: '" +| contractAddr |+ "'"-            Just (ContractState _ _ (finalStorage :: Value actualSt) _) -> do-              finalStorage' <- castM @actualSt @(ToT st) finalStorage (throwM . UnexpectedStorageType)-              pure $ fromVal $ valueAsRPC finalStorage'-      where-        typeCheckVal :: forall t. SingI t => U.Value -> PureM (Value t)-        typeCheckVal untypedVal = do-          bigMapFinder <- mkBigMapFinder-          let res =-                typeCheckingWith (TypeCheckOptions False False) $-                  typeCheckValueRunCodeCompat bigMapFinder untypedVal-          case res of-            Right val -> pure val-            Left tcErr -> throwM $ UnexpectedTypeCheckError tcErr--mkBigMapFinder :: PureM BigMapFinder-mkBigMapFinder = do-  pureState <- get--  pure \bigMapId ->-    pureState ^?-      psGState . gsContractAddressesL . each . to getContractStorage . to (getBigMapsWithId bigMapId) . each-  where-    getContractStorage :: ContractState -> SomeValue-    getContractStorage (ContractState _ _ storage _) = SomeValue storage--    getBigMapsWithId :: Natural -> SomeValue -> [SomeVBigMap]-    getBigMapsWithId bigMapId (SomeValue val) =-      dfsFoldMapValue-        (\v -> case v of-            VBigMap (Just bigMapId') _ | bigMapId' == bigMapId -> [SomeVBigMap v]-            _ -> []-        )-        val+      pure $ fromVal $ valueAsRPC finalStorage  -- | Traverse storage values of all contracts and looks for a big_map with the given ID. findBigMapByIdMaybe   ::forall k v. (SingI v, SingI k)   => Natural -> MaybeT PureM (Value ('T.TBigMap k v)) findBigMapByIdMaybe bigMapId = do-  SomeVBigMap (v@VBigMap{} :: Value t) <- MaybeT $ mkBigMapFinder <*> pure bigMapId+  SomeVBigMap (v@VBigMap{} :: Value t) <- MaybeT $+    registerInterpretation Runtime.mkBigMapFinder <*> pure bigMapId   castM @t @('T.TBigMap k v) v $ throwM . UnexpectedBigMapType bigMapId  isAddressRefillable :: ImplicitAddress -> PureM Bool@@ -463,19 +413,13 @@   => addr -> PureM st getStorageImpl addr = do   withDict (pickNiceStorage @st addr) $ do-    ContractState _ _ (storage :: Value actualT) _ <- contractStorage (toContractAddress addr)+    ContractState _ _ (storage :: Value actualT) _ <- addressState (toContractAddress addr)     val <- castM @actualT @(ToT st) storage (throwM . UnexpectedStorageType)     pure $ T.fromVal val --- Attempt to retrieve a ContractState given for the given address. Fails if the--- address is unknown or the address is a simple address (contract without--- code and storage).-contractStorage :: ContractAddress -> PureM ContractState-contractStorage addr = do-  GState{..} <- use psGState-  case Map.lookup addr gsContractAddresses of-    Just contractState -> pure contractState-    Nothing -> unknownAddress addr+addressState :: KindedAddress kind -> PureM (AddressStateFam kind)+addressState addr = maybe (unknownAddress addr) pure =<<+  use (psGState . addressesL addr . at addr)  resolveImplicit :: ImplicitAlias -> PureM ImplicitAddress resolveImplicit alias = do@@ -495,16 +439,6 @@   throwM . CustomTestError .   mappend "Unknown address alias: " . pretty --- | Make branch names for a case when we are not within any branch.-emptyScenarioBranch :: ScenarioBranchName-emptyScenarioBranch = ScenarioBranchName []---- | Add a new branch element to names provided by inner--- 'Test.Cleveland.branchout' calls.-appendScenarioBranch :: Text -> ScenarioBranchName -> ScenarioBranchName-appendScenarioBranch brName (ScenarioBranchName branches) =-  ScenarioBranchName (brName : branches)- failure :: forall a. Builder -> PureM a failure = throwM . CustomTestError . pretty @@ -529,13 +463,6 @@   , _psMinBlockTime = dummyMinBlockTime   } -failedInsideBranch :: Text -> SomeException -> FailedInBranch-failedInsideBranch name err = case fromException @FailedInBranch err of-  Just (FailedInBranch branch exception) ->-    FailedInBranch (appendScenarioBranch name branch) exception-  Nothing ->-    FailedInBranch (appendScenarioBranch name emptyScenarioBranch) err- ---------------------------------------------------------------------------- -- Emulator internals ----------------------------------------------------------------------------@@ -558,9 +485,8 @@           { toDestination = to'           , toCounter = 0           , toTxData = TxData-            { tdSenderAddress = MkConstrainedAddress from-            , tdParameter = withDict (T.properParameterEvi @(ToT epArg)) $-                TxTypedParam (T.toVal param)+            { tdSenderAddress = Constrained from+            , tdParameter = TxTypedParam (T.toVal param)             , tdEntrypoint = epName             , tdAmount = money             }@@ -568,8 +494,8 @@  -- | Originate a contract with given initial storage and balance. Its -- address is returned.-originate :: U.Contract -> ContractAlias -> U.Value -> Mutez -> PureM ContractAddress-originate uContract alias uStorage balance =+originate :: U.Contract -> ContractAlias -> U.Value -> Mutez -> Maybe KeyHash -> PureM ContractAddress+originate uContract alias uStorage balance delegate =   case typeCheckingWith def $ typeCheckContractAndStorage uContract uStorage of     Left tcErr -> throwM $ UnexpectedTypeCheckError tcErr     Right (T.SomeContractAndStorage contract storage) -> do@@ -578,6 +504,7 @@         (dummyOrigination storage contract counter)           { ooBalance = balance           , ooAlias = Just alias+          , ooDelegate = delegate           }  throwEE :: ExecutorError -> PureM a@@ -586,12 +513,14 @@   traverse addrToAddressAndAlias err >>= throwM   where     addrToAddressAndAlias :: Address -> PureM AddressAndAlias-    addrToAddressAndAlias addr@(MkAddress kindedAddr) =+    addrToAddressAndAlias (MkAddress kindedAddr) =       case kindedAddr of         ContractAddress{} ->-          use $ psGState . gsContractAddressAliasesL . Bimap.flipped . at kindedAddr . to (AddressAndAlias addr)+          use $ psGState . gsContractAddressAliasesL . Bimap.flipped . at kindedAddr . to (AddressAndAlias kindedAddr)+        ImplicitAddress{} ->+          use $ psGState . gsImplicitAddressAliasesL . Bimap.flipped . at kindedAddr . to (AddressAndAlias kindedAddr)         _ ->-          pure $ AddressAndAlias addr Nothing+          pure $ AddressAndAlias kindedAddr Nothing  -- | Runs a set of operations and updates the engine's state. registerInterpretation :: ExecutorM a -> PureM a@@ -621,3 +550,12 @@   gState <- use psGState   minBlockTime <- use psMinBlockTime   pure $ runExecutorM now level minBlockTime dummyMaxSteps gState action++setDelegate :: ImplicitAddress -> Maybe KeyHash -> PureM ()+setDelegate addr mbKh = void $ registerInterpretation $+  executeGlobalOperations def $ one $+    Runtime.SetDelegateOp SetDelegateOperation+      { sdoContract = Constrained addr+      , sdoDelegate = mbKh+      , sdoCounter = 0+      }
src/Test/Cleveland/Internal/Scenario.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ module Test.Cleveland.Internal.Scenario   ( Scenario   , Scenario'(..)
src/Test/Cleveland/Lorentz.hs view
@@ -20,8 +20,6 @@    -- * Basic types   , ContractHandle (..)-  , chNiceParameterEvi-  , chNiceStorageEvi    , ToContractAddress (..)   , ToL1Address (..)
src/Test/Cleveland/Lorentz/Internal/Entrypoints.hs view
@@ -1,8 +1,9 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA --- | Internal utilities for unit testing.+{-# OPTIONS_HADDOCK not-home #-} +-- | Internal utilities for unit testing. module Test.Cleveland.Lorentz.Internal.Entrypoints   ( -- * Entrypoint spec passed on the type level     testCompareContractEntrypointsT@@ -17,10 +18,11 @@  import Lorentz hiding (contract) +import Data.Map qualified as Map import Test.Tasty (TestName, TestTree, testGroup) import Test.Tasty.HUnit (testCase) -import Morley.Michelson.Typed (convertContract, flattenEntrypoints)+import Morley.Michelson.Typed (HandleImplicitDefaultEp(..), convertContract, flattenEntrypoints) import Morley.Michelson.Untyped qualified as U import Morley.Util.Named @@ -48,9 +50,9 @@      (M.EPMismatch -> M.EPMismatch)   -> TestName -> ContractEPTypeTest expectedEps testCompareContractEntrypointsT compareMode name contract =-  withDict (niceParameterEvi @expectedEps) $-    let entrypoints = flattenEntrypoints $ parameterEntrypointsToNotes @expectedEps-    in testCompareContractEntrypoints compareMode name contract entrypoints+  let entrypoints = flattenEntrypoints WithoutImplicitDefaultEp $+        parameterEntrypointsToNotes @expectedEps+  in testCompareContractEntrypoints compareMode name contract entrypoints  -- | Expect the contract to match with the entrypoints given in spec (with matching types). -- Checks both the contract type and the contract itself (when represented as an untyped Michelson@@ -63,14 +65,16 @@   => (M.EPMismatch -> M.EPMismatch)   -> TestName -> ContractEPTest contractEps st vd testCompareContractEntrypoints compareMode name contract@Contract{} spec =-  withDict (niceParameterEvi @contractEps) $-  withDict (niceStorageEvi @st) $-    let entrypointsInType = flattenEntrypoints $ parameterEntrypointsToNotes @contractEps-        contract' = convertContract . toMichelsonContract $ contract-    in testGroup name-        [ testCase "Contract type matches entrypoint spec" $-            M.assertEPComparisonSuccessful . Right . compareMode $-              M.compareEntrypoints (#expected :! spec) (#actual :! entrypointsInType)-        , M.testContractEntrypoints compareMode-            "Untyped contract matches entrypoint spec" contract' spec-        ]+  let entrypointsInType = flattenEntrypoints wantsDefaultEp $+        parameterEntrypointsToNotes @contractEps+      wantsDefaultEp+        | Map.member DefEpName spec = WithImplicitDefaultEp+        | otherwise = WithoutImplicitDefaultEp+      contract' = convertContract . toMichelsonContract $ contract+  in testGroup name+      [ testCase "Contract type matches entrypoint spec" $+          M.assertEPComparisonSuccessful . Right . compareMode $+            M.compareEntrypoints (#expected :! spec) (#actual :! entrypointsInType)+      , M.testContractEntrypoints compareMode+          "Untyped contract matches entrypoint spec" contract' spec+      ]
src/Test/Cleveland/Lorentz/Requester.hs view
@@ -9,7 +9,7 @@ -- _active_ - you call it, not the contract containing the view, in order to -- access the view. ----- TODO [#708]: mention that calling views directly should be preferred.+-- Prefer using @callView@ or @unsafeCallView@. module Test.Cleveland.Lorentz.Requester   ( contractRequester   ) where
src/Test/Cleveland/Lorentz/Ticketer.hs view
@@ -32,7 +32,9 @@   -> Contract (View_ (payload, (Natural, td)) callbackArg) () () ticketerContract' mkCallbackArg = defaultContract $   unpair # view_-    ( dip (drop @()) # unpair # dip (unpair # swap # ticket) # framed mkCallbackArg+    ( dip (drop @()) # unpair #+      dip (unpair # swap # ticket # assertSome @MText "Zero amount tickets are not allowed") #+      framed mkCallbackArg     )  -- | A simpler version of 'ticketerContract\'' where the target
src/Test/Cleveland/Lorentz/Types.hs view
@@ -4,8 +4,6 @@ -- | Basic types for the test framework. module Test.Cleveland.Lorentz.Types   ( ContractHandle (..)-  , chNiceParameterEvi-  , chNiceStorageEvi   , L1TAddress (..)    , ToContractAddress (..)@@ -26,12 +24,11 @@   -- $noteTAddress   ) where -import Data.Constraint (Dict(..), mapDict)+import Data.Constraint (Dict(..)) import Fmt (Buildable(..), (+|), (|+))  import Lorentz.Address import Lorentz.Constraints-import Morley.Michelson.Typed qualified as T import Morley.Tezos.Address import Morley.Tezos.Address.Alias @@ -66,16 +63,6 @@ instance ToContractRef arg (TAddress cp vd) => ToContractRef arg (ContractHandle cp st vd) where   toContractRef = toContractRef . toTAddress @cp --- | Extract the evidence in typed Michelson that the parameter type is valid--- for such scope.-chNiceParameterEvi :: forall param st vd. ContractHandle param st vd -> Dict (T.ParameterScope $ T.ToT st)-chNiceParameterEvi ContractHandle{} = mapDict (niceParameterEvi @st) Dict---- | Extract the evidence in typed Michelson that the storage type is valid--- for such scope.-chNiceStorageEvi :: forall param st vd. ContractHandle param st vd -> Dict (T.StorageScope $ T.ToT st)-chNiceStorageEvi ContractHandle{} = mapDict (niceStorageEvi @st) Dict- class ToContractAddress addr where   toContractAddress :: addr -> ContractAddress @@ -95,10 +82,10 @@   toL1Address = id  instance L1AddressKind kind => ToL1Address (KindedAddress kind) where-  toL1Address = MkConstrainedAddress+  toL1Address = Constrained  instance ToL1Address (ContractHandle cp st vd) where-  toL1Address = MkConstrainedAddress . chAddress+  toL1Address = Constrained . chAddress  -- | Counterpart of 'TAddress' that contains 'L1Address' instead of 'Address'. newtype L1TAddress cp vd = L1TAddress { unL1TAddress :: L1Address }
src/Test/Cleveland/Michelson/Internal/Entrypoints.hs view
@@ -1,8 +1,9 @@ -- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA --- | Internal utilities for unit testing.+{-# OPTIONS_HADDOCK not-home #-} +-- | Internal utilities for unit testing. module Test.Cleveland.Michelson.Internal.Entrypoints   ( EPList   , EPMismatch(.., EPComparisonResultOK)@@ -27,7 +28,7 @@ import Morley.Michelson.Parser (MichelsonSource(MSUnspecified)) import Morley.Michelson.Printer (printUntypedContract) import Morley.Michelson.Runtime (parseExpandContract)-import Morley.Michelson.TypeCheck (TCError, mkSomeParamType)+import Morley.Michelson.TypeCheck (TcTypeError, mkSomeParamType) import Morley.Michelson.Untyped hiding (Contract) import Morley.Michelson.Untyped qualified as U import Morley.Util.MismatchError (MismatchError(..))@@ -84,18 +85,24 @@  -- | Check if the contract exactly matches the given entrypoints. Will report both -- missing and extraneous entrypoint names, and type mismatches.-contractMatchesEntrypoints :: U.Contract -> Map EpName U.Ty -> Either TCError EPMismatch+contractMatchesEntrypoints :: U.Contract -> Map EpName U.Ty -> Either TcTypeError EPMismatch contractMatchesEntrypoints (contractParameter -> pt) expected = case mkSomeParamType pt of-  Right{} -> Right $ compareEntrypoints (#expected :! expected) (#actual :! mkEntrypointsMap pt)+  Right{} -> Right $ compareEntrypoints+    (#expected :! expected)+    (#actual :! mkEntrypointsMap wantsDefaultEp pt)   Left err -> Left err+  where+    wantsDefaultEp+      | Map.member DefEpName expected = WithImplicitDefaultEp+      | otherwise = WithoutImplicitDefaultEp  -- | Check if the contract contains the entrypoints given in spec (with matching types). -- Ignores any additional entrypoints present in the contract.-contractCoversEntrypoints :: U.Contract -> Map EpName U.Ty -> Either TCError EPMismatch+contractCoversEntrypoints :: U.Contract -> Map EpName U.Ty -> Either TcTypeError EPMismatch contractCoversEntrypoints = second ignoreExtraEntrypoints ... contractMatchesEntrypoints --- | Turn 'Either' 'TCError' 'EPMismatch' into an 'Assertion'-assertEPComparisonSuccessful :: Either TCError EPMismatch -> Assertion+-- | Turn 'Either' 'TcTypeError' 'EPMismatch' into an 'Assertion'+assertEPComparisonSuccessful :: Either TcTypeError EPMismatch -> Assertion assertEPComparisonSuccessful = \case   Right EPComparisonResultOK -> pass   Left tcerr -> assertFailure $ pretty tcerr
src/Test/Cleveland/Tasty/Internal.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | This module is the internal implementation of "Test.Cleveland.Tasty". module Test.Cleveland.Tasty.Internal   (@@ -54,7 +56,7 @@ import Morley.Client.TezosClient.Types (tceMbTezosClientDataDirL) import Test.Cleveland.Internal.Abstract (NetworkEnv(..), neMorleyClientEnvL) import Test.Cleveland.Internal.Client as Client (ClientM, runNetworkT)-import Test.Cleveland.Internal.Exceptions (WithCallStack(WithCallStack))+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Internal.Pure as Pure (PureM, runEmulatedT) import Test.Cleveland.Internal.Scenario import Test.Cleveland.Tasty.Internal.Options@@ -133,13 +135,11 @@  printFormattedException :: OptionSet -> SomeException -> IO Result printFormattedException opts se =-  case fromException @WithCallStack se of-    Nothing ->-      pure (testFailed $ displayException se)--    Just (WithCallStack cs ex) -> do-      msg <- formatError contextLines cs (displayException ex)-      pure (testFailed (pretty msg))+  case lookupAnnEx se of+    Nothing -> pure $ testFailed $ displayException se+    Just (CallStackAnnotation cs) -> testFailed . pretty <$> formatError contextLines cs (+      displayException $ removeAnnEx @CallStackAnnotation se+      )   where     ContextLinesOpt contextLines = lookupOption opts @@ -219,6 +219,7 @@             , neSecretKey = sk             , neMoneybagAlias = origAlias             , neExplicitDataDir = isJust dataDir+            , neVerbosity = verbosity             }  -- | Heuristics to check whether we are running within CI.
src/Test/Cleveland/Tasty/Internal/Options.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | This module declares all options/flags that @tasty@ will -- parse from the command line/environment variables. --@@ -78,9 +80,9 @@   deriving stock (Show, Eq)  instance IsOption PathOpt where-  defaultValue = PathOpt "tezos-client"+  defaultValue = PathOpt "octez-client"   optionName = "cleveland-client-path"-  optionHelp = "[Test.Cleveland] Path to tezos-client binary"+  optionHelp = "[Test.Cleveland] Path to `octez-client` binary"   parseValue = mkParseValue PathOpt   optionCLParser = mkOptionParser PathOpt (Just 'I') @@ -90,7 +92,7 @@ instance IsOption DataDirOpt where   defaultValue = DataDirOpt Nothing   optionName = "cleveland-data-dir"-  optionHelp = "[Test.Cleveland] Path to tezos-client data directory"+  optionHelp = "[Test.Cleveland] Path to `octez-client` data directory"   parseValue = mkParseValue (DataDirOpt . Just)   optionCLParser = mkOptionParser (DataDirOpt . Just) (Just 'd') 
src/Test/Cleveland/Tasty/Internal/Report.hs view
@@ -1,6 +1,8 @@ -- SPDX-FileCopyrightText: 2021 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA +{-# OPTIONS_HADDOCK not-home #-}+ -- | Pretty-printers for reports in Tasty logs. module Test.Cleveland.Tasty.Internal.Report   ( formatError
src/Test/Cleveland/Util.hs view
@@ -90,9 +90,10 @@   RatioNat, Second, Time, mcs, minute, ms, ns, sec, time, timeout, toUnit, unTime, unitNameVal)  import Morley.Michelson.Doc (DocItem, docItemPosition)-import Morley.Michelson.Typed (SingI, SomeConstrainedValue(..))+import Morley.Michelson.Typed (SingI, SomeConstrainedValue) import Morley.Michelson.Typed qualified as T import Morley.Tezos.Address+import Morley.Util.Constrained  import Test.Cleveland.Instances () @@ -301,7 +302,7 @@ formatValue v = "" +| build v |+ " of type " +| demote @t |+ ""  formatSomeValue :: (forall t. c t => SingI t) => SomeConstrainedValue c -> Builder-formatSomeValue (SomeConstrainedValue v) = formatValue v+formatSomeValue = foldConstrained formatValue  -- | Derive a 'Show' instance for a type using a custom "show" function. -- Note: the `show`n value is paren-wrapped iff it's a subexpression,
test/TestSuite/Cleveland/CallStack.hs view
@@ -10,7 +10,7 @@   , test_callStack_property   ) where -import Lorentz hiding (assert, comment, not)+import Lorentz hiding (assert, comment, not, or) import Lorentz qualified as L import Unsafe qualified @@ -31,12 +31,14 @@ import Morley.Client.TezosClient (tceEndpointUrlL) import Morley.Michelson.Typed (convertContract, untypeValue) import Morley.Tezos.Address-import Morley.Util.Interpolate (it, lit)+import Morley.Util.Interpolate (it, lit, litu) import Morley.Util.SizedList.Types import Test.Cleveland import Test.Cleveland.Internal.Client (neMorleyClientEnvL)+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Internal.Pure (TestError(CustomTestError)) import Test.Cleveland.Tasty+import TestSuite.Cleveland.CallStack.Fixtures  import TestSuite.Util   (idContract, outcomeIsFailure, runPropertyViaTasty, runViaTastyOnEmulator, runViaTastyOnNetwork)@@ -500,8 +502,7 @@         [lit|                   getStorage @() invalidContractAddr                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-                  | In 'a' branch:-                  | Unknown address provided: KT1BRd2ka5q2cPRdXALtXD1QZ38CPam2j1ye+                  | In branch 'a': Unknown address provided: KT1BRd2ka5q2cPRdXALtXD1QZ38CPam2j1ye         |]         do           branchout@@ -510,12 +511,26 @@                   getStorage @() invalidContractAddr             ]     , testFailureIncludesCallStackOnEmulator+        "when a nested branchout branch throws, the callstack branch name is correct"+        [lit|+                  void $ getStorage @() invalidContractAddr+                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+                         | In branch 'a/b': Unknown address provided: KT1BRd2ka5q2cPRdXALtXD1QZ38CPam2j1ye+        |]+        do+          branchout+            [ "a" ?-+              branchout+                ["b" ?-+                  void $ getStorage @() invalidContractAddr+                ]+            ]+    , testFailureIncludesCallStackOnEmulator         "when a branchout branch throws ANY exception, the exception raised is printed in a right way"         [lit|                 runIO $ throwM DummyException                 ^^^^^-                | In 'a' branch:-                | DummyException+                | In branch 'a': DummyException          |]         do@@ -529,8 +544,7 @@         [lit|               getStorage @() invalidContractAddr               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-              | In 'a' branch:-              | Unknown address provided: KT1BRd2ka5q2cPRdXALtXD1QZ38CPam2j1ye+              | In branch 'a': Unknown address provided: KT1BRd2ka5q2cPRdXALtXD1QZ38CPam2j1ye          |]         do@@ -670,25 +684,37 @@     invalidTAddr = ContractHandle @() @() @() "asdf" invalidContractAddr  test_callStack_property :: TestTree-test_callStack_property =-  testGroup "Error messages of property tests include a helpful callstack" $+test_callStack_property = let+  fixturePath = "test" </> "TestSuite" </> "Cleveland" </> "CallStack" </> "Fixtures.hs"+  in testGroup "Error messages of property tests include a helpful callstack" $     [ testFailureIncludesCallStackProperty "callstack points to line which led scenario to error"         [lit|     f x y = x @== y     ^^^^^^^^^^^^^^^         |]         dummyProp-    , testFailureIncludesCallStackProperty "callstack does not point to internals when a pure error is thrown"-        -- TODO [#818]: include the actual error message+    , testFailureIncludesCallStackProperty' "callstack does not point to internals when a pure error is thrown"         -- NB: a single quote with two of these lines unindented causes tasty to output a different error message-        (List.unlines-          [ [lit|dummyPropWithPureError = property $ testScenarioProps $ scenario do|]-          , [lit|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|]])+        ([litu|+           dummyPropWithPureError :: Property+           dummyPropWithPureError = property $ testScenarioProps $ scenario do+           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+           │ ━━━ Exception (ErrorCall) ━━━+           │ Pure error+           │ CallStack (from HasCallStack):+           │   error, called at test/TestSuite/Cleveland/CallStack/Fixtures.hs:15:5 in main:TestSuite.Cleveland.CallStack.Fixtures+               error "Pure error" @== (1 :: Int)+           |])+        fixturePath         dummyPropWithPureError-    , testFailureIncludesCallStackProperty "callstack does not point to internals when a nested pure error is thrown"-        (List.unlines-          [ [lit|dummyPropWithNestedPureError = property $ testScenarioProps $ scenario do|]-          , [lit|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|]])+    , testFailureIncludesCallStackProperty' "callstack does not point to internals when a nested pure error is thrown"+        ([litu|+           dummyPropWithNestedPureError = property $ testScenarioProps $ scenario do+           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+           │ ━━━ Exception (ErrorCall) ━━━+           │ unsafeSubMutez: underflow+           |])+        fixturePath         dummyPropWithNestedPureError     ] @@ -733,9 +759,15 @@   :: HasCallStack   => TestName -> String -> Property -> TestTree testFailureIncludesCallStackProperty testName expectedErrorLines prop =+  testFailureIncludesCallStackProperty' testName expectedErrorLines thisPath prop++testFailureIncludesCallStackProperty'+  :: HasCallStack+  => TestName -> String -> String -> Property -> TestTree+testFailureIncludesCallStackProperty' testName expectedErrorLines testPath prop =   runPropertyViaTasty testName mempty prop $ \tastyResult -> do     outcomeIsFailure tastyResult-    checkErrorMessage (resultDescription tastyResult) expectedErrorLines+    checkErrorMessage' (resultDescription tastyResult) expectedErrorLines testPath  -- | If we can't force a function to fail on a network by, e.g., -- passing the wrong arguments or violating its pre-conditions,@@ -760,9 +792,18 @@ -- | Checks that an error message includes a pretty-printed callstack, -- and that it points to this file and contains the expected lines. checkErrorMessage :: HasCallStack => String -> String -> Assertion-checkErrorMessage err (List.lines -> expectedLines) = do-  Unsafe.head (List.lines err) `shouldContain` ("test" </> "TestSuite" </> "Cleveland" </> "CallStack.hs")+checkErrorMessage err expectedLines = checkErrorMessage' err expectedLines thisPath +-- | Path to this file to use for tests in a couple of places.+thisPath :: String+thisPath = "test" </> "TestSuite" </> "Cleveland" </> "CallStack.hs"++-- | Checks that an error message includes a pretty-printed callstack,+-- and that it points to the provided path and contains the expected lines.+checkErrorMessage' :: HasCallStack => String -> String -> String -> Assertion+checkErrorMessage' err (List.lines -> expectedLines) path = do+  Unsafe.head (List.lines err) `shouldContain` path+   if expectedLines `List.isInfixOf` strippedErrorLines     then pass     else@@ -784,6 +825,7 @@      -- Strip 1) the header, 2) the callstack entries, 3) the line numbers and 4) the vertical border     -- from the error message, to make writing these tests easier.+    strippedErrorLines :: [String]     strippedErrorLines =       err       & List.lines@@ -815,6 +857,7 @@   deriving stock (Eq, Show)  instance Exception DummyException where+  fromException = fromPossiblyAnnotatedException  ---------------------------------------------------------------------------- -- Test scenarios@@ -830,11 +873,3 @@     g y   = f 10 y    g (20 :: Int)--dummyPropWithPureError :: Property-dummyPropWithPureError = property $ testScenarioProps $ scenario do-  error "Pure error" @== (1 :: Int)--dummyPropWithNestedPureError :: Property-dummyPropWithNestedPureError = property $ testScenarioProps $ scenario do-  (10 - 11 :: Mutez) @== 0
+ test/TestSuite/Cleveland/CallStack/Fixtures.hs view
@@ -0,0 +1,19 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++module TestSuite.Cleveland.CallStack.Fixtures+  ( dummyPropWithPureError+  , dummyPropWithNestedPureError+  ) where++import Hedgehog (Property, property)+import Morley.Tezos.Core+import Test.Cleveland++dummyPropWithPureError :: Property+dummyPropWithPureError = property $ testScenarioProps $ scenario do+    error "Pure error" @== (1 :: Int)++dummyPropWithNestedPureError :: Property+dummyPropWithNestedPureError = property $ testScenarioProps $ scenario do+    (10 - 11 :: Mutez) @== 0
+ test/TestSuite/Cleveland/Delegates.hs view
@@ -0,0 +1,60 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++module TestSuite.Cleveland.Delegates+  ( test_Delegates+  ) where++import Test.Tasty (TestTree)++import Morley.Tezos.Address+import Test.Cleveland+import TestSuite.Util++test_Delegates :: [TestTree]+test_Delegates =+  [ testScenario "Registering delegate works" $ scenario do+      addr@(ImplicitAddress kh) <- newFreshAddress "delegated"+      transfer addr [tz|1milli|] -- just about enough to pay all the fees+      getDelegate addr @@== Nothing+      registerDelegate addr+      getDelegate addr @@== Just kh+  , testScenario "Setting delegate on origination works" $ scenario do+      addr@(ImplicitAddress kh) <- newFreshAddress "delegated"+      transfer addr [tz|1milli|] -- just about enough to pay all the fees+      registerDelegate addr+      contract <- originate "idContract" () (idContract @()) kh+      getDelegate contract @@== Just kh+  , testScenario "Registering delegate twice doesn't error" $ scenario do+      addr@(ImplicitAddress kh) <- newFreshAddress "delegated"+      transfer addr [tz|1milli|] -- just about enough to pay all the fees+      registerDelegate addr+      getDelegate addr @@== Just kh+      registerDelegate addr+      getDelegate addr @@== Just kh+  , testScenario "Setting/unsetting delegate explicitly works" $ scenario do+      addr <- newFreshAddress "delegated"+      transfer addr [tz|2milli|]+      delegate@(ImplicitAddress delegateKh) <- newAddress "delegate"+      registerDelegate delegate+      getDelegate addr @@== Nothing+      setDelegate addr (Just delegateKh)+      getDelegate addr @@== Just delegateKh+      setDelegate addr Nothing+      getDelegate addr @@== Nothing+  , testScenario "Can't set/unset delegate on a registered delegate" $ scenario do+      addr@(ImplicitAddress kh) <- newFreshAddress "delegated"+      transfer addr [tz|1milli|]+      delegate@(ImplicitAddress delegateKh) <- newAddress "delegate"+      registerDelegate delegate+      registerDelegate addr+      getDelegate addr @@== Just kh+      errorMessage <- ifEmulation+        (pure "Delegate deletion is forbidden")+        (pure "Failed to withdraw delegation for")+      setDelegate addr (Just delegateKh)+        & shouldFailWithMessage errorMessage+      setDelegate addr Nothing+        & shouldFailWithMessage errorMessage+      getDelegate addr @@== Just kh+  ]
test/TestSuite/Cleveland/Entrypoints.hs view
@@ -15,7 +15,7 @@ test_duplicateEntrypoints :: TestTree test_duplicateEntrypoints = testContractMatchesEntrypoints "Ill-typed contract fails the test"   illTypedContract mempty-  & expectFailure "invalid parameter declaration:  Duplicated entrypoint names: 'do1'"+  & expectFailure "Duplicated entrypoint names: 'do1'"   where     n = unsafe $ mkAnnotation ""     do1 = unsafe $ mkAnnotation "do1"
test/TestSuite/Cleveland/ErrorMessages.hs view
@@ -12,7 +12,7 @@  test_error_message_shows_contract_alias :: TestTree test_error_message_shows_contract_alias =-  testScenarioOnEmulator "Error message shows contract alias" $ scenario do+  testScenario "Error message shows contract alias" $ scenario do     ch <- originate "my-contract-alias" () $ L.defaultContract @() @() $ L.car # L.failWith     shouldFailWithMessage "(my-contract-alias) failed with: Unit" do       transfer ch
test/TestSuite/Cleveland/ExpectFailure.hs view
@@ -21,16 +21,15 @@  import Morley.Micheline (toExpression) import Morley.Michelson.Runtime.GState (genesisAddress1)-import Morley.Tezos.Address (ConstrainedAddress(..), ta)+import Morley.Tezos.Address (ta) import Morley.Tezos.Core (parseChainId)-import Morley.Util.Interpolate (i)+import Morley.Util.Interpolate (it) import Test.Cleveland import Test.Cleveland.Internal.Abstract-  (AddressAndAlias(..), ExpressionOrTypedValue(..), FailedInBranch(..), GenericTestError(..),-  TransferFailure(..), TransferFailureReason(..))+  (AddressAndAlias(..), ExpressionOrTypedValue(..), GenericTestError(..), TransferFailure(..),+  TransferFailureReason(..)) import Test.Cleveland.Internal.Actions (TransferFailurePredicate(..))-import Test.Cleveland.Internal.Exceptions (WithCallStack(..))-import Test.Cleveland.Internal.Pure (emptyScenarioBranch)+import Test.Cleveland.Internal.Exceptions import Test.Cleveland.Util (failedTest, fromHex) import TestSuite.Util (shouldFailWithMessage) @@ -133,12 +132,12 @@ test_BranchErrorHandleInRightWay =   testScenario "catchTransferFailure and attempt unwrap exceptions with extra info" $ scenario do     let action =-          runIO . throwM $-              WithCallStack callStack $ SomeException $-                FailedInBranch emptyScenarioBranch $ SomeException $-                  WithCallStack callStack $ SomeException $-                    FailedInBranch emptyScenarioBranch $ SomeException $-                      TransferFailure (AddressAndAlias (MkAddress [ta|tz1fsFpWk691ncq1xwS62dbotECB67B13gfC|]) Nothing) BadParameter+          runIO $+              addCallStack $+                annotateExceptions (ScenarioBranchName ["a"]) $+                  addCallStack $+                    annotateExceptions (ScenarioBranchName ["b"]) $+                      throwM $ TransferFailure (AddressAndAlias [ta|tz1fsFpWk691ncq1xwS62dbotECB67B13gfC|] Nothing) BadParameter      res <- attempt @TransferFailure action @@ -302,12 +301,12 @@  impl_test_AndPredicate_succeeds_if_all_conditions_hold conv =   testScenario "AndPredicate succeeds if all conditions hold" $ scenario do-    let err = TransferFailure (AddressAndAlias (toAddress genesisAddress1) Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing+    let err = TransferFailure (AddressAndAlias genesisAddress1 Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing     checkTransferFailure err $ failedWith (constant @Integer 1) && addressIs genesisAddress1  impl_test_OrPredicate_succeeds_if_any_condition_holds conv =   testScenario "AndPredicate succeeds if any condition holds" $ scenario do-    let err = TransferFailure (AddressAndAlias (toAddress genesisAddress1) Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing+    let err = TransferFailure (AddressAndAlias genesisAddress1 Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing     checkTransferFailure err $       failedWith (constant @Integer 1) ||       failedWith (constant @Integer 2) ||@@ -315,14 +314,14 @@  impl_test_AndPredicate_fails_if_any_condition_fails conv =   testScenario "AndPredicate succeeds if all conditions hold" $ scenario do-    let err = TransferFailure (AddressAndAlias (toAddress genesisAddress1) Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing+    let err = TransferFailure (AddressAndAlias genesisAddress1 Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing      checkTransferFailure err       ( failedWith (constant @Integer 1) &&         failedWith (constant @Integer 2) &&         failedWith (constant @Integer 3)       )-      & shouldFailWithMessage [i|+      & shouldFailWithMessage [it| Expected transfer to fail with an error such that:    (@@ -333,18 +332,18 @@  But these conditions were not met. Actual transfer error:-  Contract: tz1bTXrPQCMsGbjPQcSH4uHCbbwtqotAuvHF failed with: 1|]+  Contract: #{genesisAddress1} failed with: 1|]  impl_test_OrPredicate_fails_if_all_conditions_fail conv =   testScenario "AndPredicate succeeds if all conditions hold" $ scenario do-    let err = TransferFailure (AddressAndAlias (toAddress genesisAddress1) Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing+    let err = TransferFailure (AddressAndAlias genesisAddress1 Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing      checkTransferFailure err       ( failedWith (constant @Integer 2) ||         failedWith (constant @Integer 3) ||         failedWith (constant @Integer 4)       )-      & shouldFailWithMessage [i|+      & shouldFailWithMessage [it| Expected transfer to fail with an error such that:    (@@ -357,11 +356,11 @@  But these conditions were not met. Actual transfer error:-  Contract: tz1bTXrPQCMsGbjPQcSH4uHCbbwtqotAuvHF failed with: 1|]+  Contract: #{genesisAddress1} failed with: 1|]  impl_test_checkTransferFailure_shows_only_failing_predicates conv =   testScenario "checkTransferFailure shows only failing predicates" $ scenario do-    let err = TransferFailure (AddressAndAlias (toAddress genesisAddress1) Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing+    let err = TransferFailure (AddressAndAlias genesisAddress1 Nothing) $ FailedWith (conv $ toVal @Integer 1) Nothing      checkTransferFailure err       ( (failedWith (constant @Integer 1) && failedWith (constant @Integer 2)) &&@@ -369,7 +368,7 @@         (failedWith (constant @Integer 1) || failedWith (constant @Integer 6)) &&         (failedWith (constant @Integer 7) || failedWith (constant @Integer 8))       )-      & shouldFailWithMessage [i|+      & shouldFailWithMessage [it| Expected transfer to fail with an error such that:    (@@ -388,4 +387,4 @@  But these conditions were not met. Actual transfer error:-  Contract: tz1bTXrPQCMsGbjPQcSH4uHCbbwtqotAuvHF failed with: 1|]+  Contract: #{genesisAddress1} failed with: 1|]
test/TestSuite/Cleveland/Lorentz/Entrypoints.hs view
@@ -22,6 +22,8 @@ import Lorentz.Annotation import Lorentz.Entrypoints import Lorentz.Value+import Morley.Michelson.Parser (utypeQ)+import Morley.Michelson.Typed.Convert (convertParamNotes) import Morley.Michelson.Untyped qualified as U import Morley.Util.Interpolate @@ -42,6 +44,12 @@   deriving stock Generic   deriving anyclass (IsoValue) +data MyEntrypoints3+  = Default Natural+  | Do33 Integer+  deriving stock Generic+  deriving anyclass (IsoValue)+ data MyParams = MyParams   { param1 :: ()   , param2 :: ByteString@@ -55,27 +63,19 @@ instance ParameterHasEntrypoints MyEntrypoints2 where   type ParameterEntrypointsDerivation MyEntrypoints2 = EpdPlain +instance ParameterHasEntrypoints MyEntrypoints3 where+  type ParameterEntrypointsDerivation MyEntrypoints3 = EpdPlain+ epSpecPartial :: Map EpName U.Ty epSpecPartial =-  [ ( U.UnsafeEpName "do1", U.Ty (U.TInt) def )-  , ( U.UnsafeEpName "do2"-    , U.Ty (U.TPair def def def def (U.Ty U.TInt def) (U.Ty U.TInt def)) def )-  , ( U.UnsafeEpName "do10", U.Ty (U.TUnit) def )-  , ( U.UnsafeEpName "do11", U.Ty (U.TNat) def )+  [ ( #do1, [utypeQ| int |] )+  , ( #do2, [utypeQ| pair int int |] )+  , ( #do10, [utypeQ| unit |] )+  , ( #do11, [utypeQ| nat |] )   ]  epSpecFull :: Map EpName U.Ty-epSpecFull = epSpecPartial <>-  [ ( U.UnsafeEpName "do4"-    , U.Ty (-        U.TPair (unsafe $ U.mkAnnotation "param1")-                (unsafe $ U.mkAnnotation "param2")-                def-                def-                (U.Ty U.TUnit def)-                (U.Ty U.TBytes def)-        ) def )-  ]+epSpecFull = epSpecPartial <> [ ( #do4, [utypeQ| pair (unit %param1) (bytes %param2) |]) ]  extractTests :: TestTree -> (forall t. IsTest t => String -> t -> TestTree) -> TestTree extractTests tree f = case tree of@@ -103,23 +103,36 @@         (idContract @MyEntrypoints1 @()) epSpecPartial   , testContractCoversEntrypoints       "testContractCoversEntrypoints fails on wrong type"-        (idContract @MyEntrypoints1 @()) [ ( U.UnsafeEpName "do1", U.Ty (U.TNat) def ) ]+        (idContract @MyEntrypoints1 @()) [ ( #do1, [utypeQ| nat |] ) ]       & expectFailure "Expected: nat\nActual:   int"   , testContractCoversEntrypoints       "testContractCoversEntrypoints fails on missing entrypoints"-        (idContract @MyEntrypoints1 @()) [ ( U.UnsafeEpName "do123", U.Ty (U.TInt) def ) ]+        (idContract @MyEntrypoints1 @()) [ ( #do123, [utypeQ| int |] ) ]       & expectFailure "Entrypoints do not match specification: \           \Missing entrypoints in the contract: do123: int"+  , testContractCoversEntrypoints+      "testContractCoversEntrypoints handles implicit default entrypoints if those are expected"+        (idContract @MyEntrypoints2 @()) [ ( U.DefEpName, [utypeQ| or (unit %do10) (nat %do11) |] ) ]+  , testContractCoversEntrypoints+      "testContractCoversEntrypoints handles explicit default entrypoints if those are expected"+        (idContract @MyEntrypoints3 @()) [ ( U.DefEpName, [utypeQ| nat |] ) ]+  , testContractCoversEntrypoints+      "testContractCoversEntrypoints fails on invalid implicit default entrypoint"+        (idContract @MyEntrypoints2 @()) [ ( U.DefEpName, [utypeQ| int |] ) ]+      & expectFailure [it|+          Type mismatch in entrypoints:+            <default>:+      |]   ]  genBigPair :: Int -> U.Ty-genBigPair 0 = U.Ty U.TBytes def+genBigPair 0 = [utypeQ| bytes |] genBigPair n = U.Ty (     U.TPair (unsafe $ U.mkAnnotation "param1")             (unsafe $ U.mkAnnotation "param2")             def             def-            (U.Ty U.TUnit def)+            [utypeQ| unit |]             (genBigPair (n - 1))     ) def @@ -129,11 +142,11 @@       "testContractMatchesEntrypoints works as expected" (idContract @MyEntrypoints1 @()) epSpecFull   , testContractMatchesEntrypoints       "testContractMatchesEntrypoints fails on wrong type"-        (idContract @MyEntrypoints1 @()) [ ( U.UnsafeEpName "do1", U.Ty (U.TNat) def ) ]+        (idContract @MyEntrypoints1 @()) [ ( #do1, [utypeQ| nat |] ) ]       & expectFailure  "Expected: nat\nActual:   int"   , testContractMatchesEntrypoints       "testContractMatchesEntrypoints fails on wrong nested type"-        (idContract @MyEntrypoints1 @()) [( U.UnsafeEpName "do4", genBigPair 6)]+        (idContract @MyEntrypoints1 @()) [( #do4, genBigPair 6)]       & expectFailure [it|             pair (unit %param1)           -      (pair %param2 (unit %param1)@@ -147,19 +160,48 @@           |]   , testContractMatchesEntrypoints       "testContractMatchesEntrypoints fails on missing entrypoints"-        (idContract @MyEntrypoints1 @()) [ ( U.UnsafeEpName "do123", U.Ty (U.TInt) def ) ]+        (idContract @MyEntrypoints1 @()) [ ( #do123, [utypeQ| int |] ) ]       & expectFailure "Missing entrypoints in the contract: do123: int"   , testContractMatchesEntrypoints       "testContractMatchesEntrypoints fails on extraneous entrypoints"         (idContract @MyEntrypoints1 @()) epSpecPartial       & expectFailure "Entrypoints do not match specification:\           \ Extraneous entrypoints in the contract: do4: pair (unit %param1) (bytes %param2)"+  , testContractMatchesEntrypoints+      "testContractMatchesEntrypoints handles implicit default entrypoints if those are expected"+        (idContract @MyEntrypoints1 @()) $+          epSpecFull+          <> [ ( U.DefEpName, stripRootAnn $ convertParamNotes $+                   parameterEntrypointsToNotes @MyEntrypoints1 ) ]+  , testContractMatchesEntrypoints+      "testContractMatchesEntrypoints handles explicit default entrypoints if those are expected"+        (idContract @MyEntrypoints3 @())+          [ ( U.DefEpName, [utypeQ| nat |] ), (#do33, [utypeQ| int |]) ]+  , testContractMatchesEntrypoints+      "testContractMatchesEntrypoints handles explicit default entrypoints if those are unexpected"+        (idContract @MyEntrypoints3 @()) [ (#do33, [utypeQ| int |]) ]+      & expectFailure "Entrypoints do not match specification: \+          \Extraneous entrypoints in the contract: <default>: nat"+  , testContractMatchesEntrypoints+      "testContractMatchesEntrypoints fails on type mismatch in default entrypoint"+        (idContract @MyEntrypoints1 @()) (epSpecFull <> [ ( U.DefEpName, [utypeQ| unit |] ) ])+      & expectFailure [it|+          Type mismatch in entrypoints:+            <default>:+              Expected: unit+      |]   ] +stripRootAnn :: U.ParameterType -> U.Ty+stripRootAnn (U.ParameterType ty _) = ty+ test_ContractMatchEntrypointsT :: [TestTree] test_ContractMatchEntrypointsT =   [ testContractMatchesEntrypointsT @MyEntrypoints1       "testContractMatchesEntrypointsT works as expected" (idContract @MyEntrypoints1 @())+  , testContractMatchesEntrypointsT @MyEntrypoints3+      "testContractMatchesEntrypointsT works as expected with explicit default"+        (idContract @MyEntrypoints3 @())   , testContractMatchesEntrypointsT @MyEntrypoints2       "testContractMatchesEntrypointsT fails on extra entrypoints" (idContract @MyEntrypoints1 @())       & expectFailure [it|@@ -176,4 +218,6 @@       "testContractCoversEntrypointsT works on partial spec" (idContract @MyEntrypoints1 @())   , testContractCoversEntrypointsT @MyEntrypoints1       "testContractCoversEntrypointsT works on full spec" (idContract @MyEntrypoints1 @())+  , testContractCoversEntrypointsT @MyEntrypoints3+      "testContractCoversEntrypointsT works on explicit default" (idContract @MyEntrypoints3 @())   ]
+ test/TestSuite/Cleveland/MonadOps.hs view
@@ -0,0 +1,49 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++module TestSuite.Cleveland.MonadOps+  ( test_MonadOps+  , test_MonadOpsBatch+  ) where++import Test.Tasty (TestTree)++import Morley.Util.SizedList (IsoNatPeano, SizedList)+import Test.Cleveland+import Test.Cleveland.Internal.Actions (MonadOriginate, MonadTransfer)++import TestSuite.Util++test_MonadOps :: TestTree+test_MonadOps =+  testScenario "MonadOps works" $ scenario go++test_MonadOpsBatch :: TestTree+test_MonadOpsBatch =+  testScenario "Batched MonadOps works" $ scenario do+    addrs <- newAddresses $ enumAliases "test"+    inBatch $ goBatch @3 addrs++-- NB: We're testing 'MonadOps' behavior here, hence it's important for 'go' and+-- 'goBatch' to be separate polymorphic functions, otherwise those would just+-- run in 'MonadCleveland' context.++go :: (Monad m, MonadOps m) => m ()+go = do+  ct <- originateMonadOps+  transferMonadOps ct++goBatch+  :: forall n n' m. (IsoNatPeano n n', Applicative m, MonadOps m)+  => SizedList n ImplicitAddress -> m ()+goBatch addrs = for_ addrs \addr -> transfer addr (123 :: Mutez)++-- NB: The same applies to 'MonadOriginate' and 'MonadTransfer' in functions+-- below as to 'MonadOps' above -- we want those to be separate polymorphic+-- functions as it's basically the point of these tests.++originateMonadOps :: MonadOriginate m => m (ContractHandle () () ())+originateMonadOps = originate "idContract" () idContract++transferMonadOps :: MonadTransfer m => ContractHandle () () () -> m ()+transferMonadOps ct = transfer ct (123 :: Mutez) $ calling def ()
+ test/TestSuite/Cleveland/ViewCall.hs view
@@ -0,0 +1,88 @@+-- SPDX-FileCopyrightText: 2022 Oxhead Alpha+-- SPDX-License-Identifier: LicenseRef-MIT-OA++-- | Views are tested mainly in lorentz-test, but here we check everything at+-- least works in simple scenarios.+module TestSuite.Cleveland.ViewCall+  ( test_RequesterContract+  , test_ViewCall+  , test_UnsafeViewCall+  ) where++import Lorentz+import Prelude hiding (drop, some, swap, take, view)++import Test.Tasty (TestTree)++import Morley.Michelson.Untyped (pattern ValueUnit)+import Test.Cleveland+import Test.Cleveland.Lorentz+import Test.Cleveland.Lorentz.Requester+import Test.Cleveland.Michelson.Import (testTreesWithUntypedContract)+import TestSuite.Util+import TestSuite.Util.Contracts (inContractsDir)++type Views = ViewsList+  [ "add" ?:: Natural >-> Natural+  , "id" ?:: Natural >-> (Natural, ())+  , "fail" ?:: MText >-> Never+  ]++viewedContract :: Contract Never () Views+viewedContract = $$(embedContract $ inContractsDir "view_example.tz")++test_RequesterContract :: TestTree+test_RequesterContract = testScenario "Views can be called via requester contract" $ scenario do+  viewed <- originate "viewed" () viewedContract++  clarifyErrors "Calling view 'add'" do+    requester <- originate "requester" [] (contractRequester @"add" viewed)+    forM_ [5, 10] $ transfer requester . calling def+    getStorage requester @@== [11, 6]++  clarifyErrors "Calling view 'fail'" do+    requester <- originate "requester" [] (contractRequester @"fail" viewed)+    transfer requester (calling def [mt|nyan|])+      & expectFailedWith [mt|nyan|]++  clarifyErrors "Calling view 'id'" do+    requester <- originate "requester" [] (contractRequester @"id" viewed)+    forM_ [5, 0] $ transfer requester . calling def+    getStorage requester @@== [(0, ()), (5, ())]++test_ViewCall :: TestTree+test_ViewCall = testScenario "Views can be called directly" $ scenario do+  viewed <- originate "viewed" () viewedContract++  clarifyErrors "Calling view 'add'" do+    forM [5, 10] (callView viewed #add) @@== [6, 11]++  clarifyErrors "Calling view 'fail'" do+    callView viewed #fail [mt|nyan|]+      & expectFailedWith [mt|nyan|]++  clarifyErrors "Calling view 'id'" do+    forM [5, 0] (callView viewed #id) @@== [(5, ()), (0, ())]++test_UnsafeViewCall :: IO [TestTree]+test_UnsafeViewCall = testTreesWithUntypedContract (inContractsDir "view_example.tz") \ct ->+  pure $ pure $ testScenario "Views can be called directly" $ scenario do+    viewed <- originate "viewed" ValueUnit ct++    clarifyErrors "Calling view 'add'" do+      forM [5 :: Natural, 10] (unsafeCallView @Natural viewed #add) @@== [6, 11]++    clarifyErrors "Calling view 'fail'" do+      unsafeCallView @Never viewed #fail [mt|nyan|]+        & expectFailedWith [mt|nyan|]++    clarifyErrors "Calling view 'id'" do+      forM [5 :: Natural, 0] (unsafeCallView @(Natural, ()) viewed #id) @@== [(5, ()), (0, ())]++    clarifyErrors "Calling view 'nonexistent' which doesn't exist" do+      unsafeCallView @Never viewed #nonexistent ()+        & shouldFailWithMessage "Failed to call view nonexistent"++    clarifyErrors "Calling view 'id' with incorrect types" do+      unsafeCallView @Never viewed #id ()+        & shouldFailWithMessage "Failed to call view id"
test/TestSuite/Cleveland/WithMoneybag.hs view
@@ -17,7 +17,7 @@      -- At the end of this test, we want to check that `newAddress` transfers funds from "newMoneybag" to "testAccount".     -- However, this will only happen if:-    --   1. the "testAccount" alias is not yet known to tezos-client+    --   1. the "testAccount" alias is not yet known to @octez-client@     --   2. or, it is known, but it has less than 0.5 XTZ.     -- We use `newFreshAddress` here to ensure "testAccount" is a known alias with 0 XTZ.     _ <- newFreshAddress "testAccount"