cleveland-0.3.1: Testing framework for Morley.
Safe HaskellSafe-Inferred
LanguageHaskell2010

Test.Cleveland.Internal.Actions

Description

Cleveland actions.

Synopsis

Documentation

data TransferFailurePredicate Source #

A predicate that checks whether a transfer operation failed for the expected reason.

Predicates can be combined using the && and || operators.

Constructors

TransferFailurePredicate

Predicate with a description

Fields

AndPredicate (NonEmpty TransferFailurePredicate) 
OrPredicate (NonEmpty TransferFailurePredicate) 

shiftOverflow :: TransferFailurePredicate Source #

Asserts that interpretation of a contract failed due to an overflow error.

emptyTransaction :: TransferFailurePredicate Source #

Asserts that an action failed due to an attempt to transfer 0tz towards a simple address.

badParameter :: TransferFailurePredicate Source #

Asserts that an action failed due to an attempt to call a contract with an invalid parameter.

gasExhaustion :: TransferFailurePredicate Source #

Asserts that interpretation of a contract failed due to gas exhaustion.

failedWith :: SomeConstant -> TransferFailurePredicate Source #

Asserts that interpretation of a contract ended with FAILWITH, throwing the given error.

This function should be used together with one of the "FAILWITH constructors" (e.g. constant, customError).

failedWithPredicate :: Builder -> (Expression -> Bool) -> TransferFailurePredicate Source #

Asserts that interpretation of a contract ended with FAILWITH, and the error satisfies the given predicate.

addressIs Source #

Arguments

:: ToAddress addr 
=> addr

The expected address.

-> TransferFailurePredicate 

Asserts that the error occurred while interpreting the contract with the given address.

constant :: forall err. NiceConstant err => err -> SomeConstant Source #

A constant michelson value that a contract threw with FAILWITH.

lerror :: forall err. IsError err => err -> SomeConstant Source #

A lorentz error.

customError :: forall arg tag. (IsError (CustomError tag), MustHaveErrorArg tag (MText, arg)) => Label tag -> arg -> SomeConstant Source #

A custom lorentz error.

customError_ :: (IsError (CustomError tag), MustHaveErrorArg tag (MText, ())) => Label tag -> SomeConstant Source #

A custom lorentz error with a unit argument.

customErrorNoArg :: (IsError (CustomError tag), MustHaveErrorArg tag MText) => Label tag -> SomeConstant Source #

A custom lorentz error with no argument.

numericError :: forall err. IsError err => ErrorTagMap -> err -> SomeConstant Source #

A lorentz numeric error.

type family ImplicitAddressParameterHelper addr cp arg :: Constraint where ... Source #

Implicit address may only have the root entrypoint, so full parameter type is exactly the argument parameter type. This is used to improve type inference when using transferTicket with implicit addresses.

transferTicket :: forall cp vd arg m addr ticketerAddr mname. (MonadOpsInternal m, NiceParameter arg, NiceComparable arg, ImplicitAddressParameterHelper addr cp (Ticket arg), ToL1TAddress cp vd addr, ToAddress ticketerAddr, HasEntrypointArg cp (EntrypointRef mname) (Ticket arg), HasCallStack) => addr -> EntrypointRef mname -> ticketerAddr -> arg -> Natural -> m [ContractEvent] Source #

Transfer tickets.

unsafeTransferTicket :: forall arg m addr ticketerAddr. (MonadOpsInternal m, NiceParameter arg, NiceComparable arg, ToL1Address addr, ToAddress ticketerAddr, HasCallStack) => addr -> EpName -> ticketerAddr -> arg -> Natural -> m [ContractEvent] Source #

Transfer tickets without checking the recipient can accept them.

type family FTransferResult emit :: Type where ... Source #

Type family encoding the actual transfer result depending on TransferResult

data TransferResult Source #

Simple flag to track whether we want to return list of emitted events.

data WithContractEvents Source #

transfer flag to signal we want contract events emitted by EMIT returned. Passed in the variadic part of transfer, e.g.

transfer addr [tz|123u|] WithContractEvents $ calling (ep @"Entrypoint") ()

Constructors

WithContractEvents 

Instances

Instances details
(TransferFunc mode 'TransferWithEmits am r, NoDuplicateEmit emit, emit ~ 'TransferIgnoreResult) => TransferFunc mode emit am (WithContractEvents -> r) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

class (forall mod am emit a. (SingI emit, DoTransfer mod, a ~ FTransferResult emit) => TransferFunc mod emit am (m a)) => MonadTransfer m Source #

A convenient synonym class to require the terminating instance for a given monad without leaking too much implementation detail.

Instances

Instances details
(forall (mod :: TransferMode) (am :: HasAmount) (emit :: TransferResult) a. (SingI emit, DoTransfer mod, a ~ FTransferResult emit) => TransferFunc mod emit am (m a)) => MonadTransfer m Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

type family MatchModes from to :: Constraint where ... Source #

Type family that defines possible mode conversions in TransferFunc. Basically, we don't allow unchecked calls to become checked, and we require that checked calls do not change the parameter type mid-way.

Equations

MatchModes ('Incomplete _) 'Unchecked = () 
MatchModes ('Incomplete ('Checked param1)) ('Checked param2) = param1 ~ param2 
MatchModes ('Incomplete 'Unchecked) _ = TypeError ('Text "Can not use this type of call with an untyped address." :$$: 'Text "Try using 'unsafeCalling' instead.") 
MatchModes _ _ = TypeError ('Text "Call is specified more than once.") 

type family NoDuplicateEmit am :: Constraint where ... Source #

Type family raising a type error on TransferWithEmits argument. Used to improve error reporting for TransferFunc instances with equality constraints.

Equations

NoDuplicateEmit 'TransferWithEmits = TypeError ('Text "WithContractEvents is specified more than once.") 
NoDuplicateEmit 'TransferIgnoreResult = () 

type family NoDuplicateAmount am :: Constraint where ... Source #

Type family raising a type error on HasAmount argument. Used to improve error reporting for TransferFunc instances with equality constraints.

Equations

NoDuplicateAmount 'HasAmount = TypeError ('Text "Amount is specified more than once.") 
NoDuplicateAmount 'HasNoAmount = () 

class TransferFunc (mode :: TransferMode) (emit :: TransferResult) (hasAmount :: HasAmount) r where Source #

The class implementing a guarded "printf trick" for the transfer function.

If you see GHC asking for this constraint, you most likely need to add MonadTransfer constraint on the return monad instead.

Instances

Instances details
(SingI emit, DoTransfer mode, a ~ FTransferResult emit) => TransferFunc mode emit am (ClevelandOpsBatch a) Source #

The terminating case for batched transfer

Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

(TransferFunc mode 'TransferWithEmits am r, NoDuplicateEmit emit, emit ~ 'TransferIgnoreResult) => TransferFunc mode emit am (WithContractEvents -> r) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

(TransferFunc mode emit 'HasAmount r, NoDuplicateAmount am, am ~ 'HasNoAmount) => TransferFunc mode emit am (Mutez -> r) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

(Bottom, TypeError (('Text "Incorrect argument for the 'transfer' function: " :<>: 'ShowType x) :$$: 'Text "If in doubt, try adding a type annotation.") :: Constraint) => TransferFunc mode emit am (x -> r) Source #

Catchall incoherent instance to report argument errors.

Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

Methods

transfer'r :: GenericTransferData mode -> x -> r Source #

(TransferFunc modeTo emit am r, MatchModes modeFrom modeTo) => TransferFunc modeFrom emit am (GenericCall modeTo -> r) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

Methods

transfer'r :: GenericTransferData modeFrom -> GenericCall modeTo -> r Source #

(SingI emit, DoTransfer mode, HasClevelandCaps cap, base ~ ClevelandBaseMonad cap, a ~ FTransferResult emit) => TransferFunc mode emit am (ReaderT cap base a) Source #

The terminating case for Cleveland monads

Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

Methods

transfer'r :: GenericTransferData mode -> ReaderT cap base a Source #

data HasAmount Source #

Simple flag to track duplicate amount specification.

Constructors

HasAmount 
HasNoAmount 

type family InitialTransferMode addr :: TransferMode where ... Source #

Choose the initial TransferMode based on the type of destination address.

Equations

InitialTransferMode ContractAddress = 'Unchecked 
InitialTransferMode ImplicitAddress = 'Unchecked 
InitialTransferMode ContractAddressWithAlias = 'Unchecked 
InitialTransferMode ImplicitAddressWithAlias = 'Unchecked 
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'") 

data GenericTransferData mode Source #

Generic version of TransferData

Constructors

GenericTransferData 

Fields

data GenericCall mode where Source #

Data-kind for call specification.

Constructors

CheckedCall :: (NiceParameter epArg, HasEntrypointArg param epRef epArg) => epRef -> epArg -> GenericCall ('Checked param) 
UncheckedCall :: NiceParameter epArg => EpName -> epArg -> GenericCall 'Unchecked 
UnspecifiedCall :: GenericCall ('Incomplete param) 

Instances

Instances details
(TransferFunc modeTo emit am r, MatchModes modeFrom modeTo) => TransferFunc modeFrom emit am (GenericCall modeTo -> r) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Transfer

Methods

transfer'r :: GenericTransferData modeFrom -> GenericCall modeTo -> r Source #

data TransferMode Source #

Data-kind for tracking what type of call we're making.

transfer :: forall addr r. (HasCallStack, TransferFunc ('Incomplete (InitialTransferMode addr)) 'TransferIgnoreResult 'HasNoAmount r, ToL1Address addr) => addr -> r Source #

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
:}

calling :: forall mname. EntrypointRef mname -> forall epArg param. (NiceParameter epArg, HasEntrypointArg param (EntrypointRef mname) epArg) => epArg -> GenericCall ('Checked param) Source #

Safely call an entrypoint specified by the first argument with the provided parameter.

The first character of the entrypoint name must be capitalized.

This is "safe" in the sense that the contract is checked if it indeed has the specified entrypoint and the entrypoint in question accepts the argument provided, a type error is raised otherwise.

transfer addr $ calling (ep @"Entrypoint") ()

Use CallDefault or def to call the default entrypoint.

transfer addr $ calling def ()

Notice that type variables for entrypoint argument and full parameter are specified after the entrypoint. This is done so more for readability. F. ex.:

transfer addr $ calling def @Integer 123

This does also marginally simplify type inference in the case of partial application.

unsafeCalling :: EpName -> forall epArg. NiceParameter epArg => epArg -> GenericCall 'Unchecked Source #

Unsafely call an entrypoint specified by the first argument with the provided parameter.

This is "unsafe" in the sense that there is no check that the contract indeed has the specified entrypoint or that the entrypoint in question accepts the argument provided.

Also, no compile-time checks are performed on the entrypoint name, so it can be malformed.

transfer addr $ unsafeCalling (ep @"Entrypoint") ()

Overloaded labels are supported with unsafeCalling, so you can specify the entrypoint as an overloaded label:

transfer addr $ unsafeCalling #entrypoint ()

Use DefEpName or def to call the default entrypoint.

Notice that the type variable for the entrypoint argument is specified after the entrypoint. This is done so more for readability. F. ex.:

transfer addr $ calling def @Integer 123

This does also marginally simplify type inference in the case of partial application.

data Large Source #

Mark a contract that doesn't fit into the origination size limit. This will execute multiple origination steps.

Such origination cannot be batched (it simply may not fit).

Constructors

Large 

Instances

Instances details
(OFConstraints ct 'PropLarge props r, GetLarge props ~ 'NotLarge) => OriginateFunc ct props (Large -> r) Source #

Set large origination.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

class (MonadOpsInternal m, forall ct props a. TerminatingOFConstraints ct props m a => OriginateFunc ct props (m a)) => MonadOriginate m Source #

A convenient synonym class to require the terminating instance for a given monad without leaking too much implementation detail.

Instances

Instances details
(MonadOpsInternal m, forall ct (props :: [Prop]) a. TerminatingOFConstraints ct props m a => OriginateFunc ct props (m a)) => MonadOriginate m Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

type TerminatingOFConstraints ct props m a = (Originator (GetLarge props) m, a ~ OriginationResult (ContractOriginateType ct)) Source #

Common constraints for terminating OriginateFunc cases.

type OFConstraints ct prop props r = (OriginateFunc ct (prop ': props) r, CheckDupProp prop props) Source #

Convenience synonym for constraints used in OriginateFunc instances.

type family CheckDupProp name props where ... Source #

Type family raising a type error if element is in list. Used to improve error reporting for OriginateFunc instances with equality constraints.

Equations

CheckDupProp name (name ': _) = TypeError ('Text (PropName name) :<>: 'Text " is specified more than once.") 
CheckDupProp name (_ ': xs) = CheckDupProp name xs 
CheckDupProp _ '[] = () 

type family GetLarge a where ... Source #

Convert a list of props into LargeOrigination.

Equations

GetLarge ('PropLarge ': _) = 'IsLarge 
GetLarge (_ ': xs) = GetLarge xs 
GetLarge '[] = 'NotLarge 

type family PropName a where ... Source #

Pretty prop name.

Equations

PropName 'PropBalance = "Balance" 
PropName 'PropDelegate = "Delegate" 
PropName 'PropLarge = "Large" 

data Prop Source #

Enum for props we track duplicates of.

class OriginateFunc contract (props :: [Prop]) r where Source #

The class implementing a guarded "printf trick" for the originate function.

If you see GHC asking for this constraint, you most likely need to add MonadOriginate constraint on the return monad instead.

Instances

Instances details
TerminatingOFConstraints ct props ClevelandOpsBatch a => OriginateFunc ct props (ClevelandOpsBatch a) Source #

The terminating case for batched transfer.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

(OFConstraints ct 'PropLarge props r, GetLarge props ~ 'NotLarge) => OriginateFunc ct props (Large -> r) Source #

Set large origination.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

OFConstraints ct 'PropBalance props r => OriginateFunc ct props (Mutez -> r) Source #

Set balance.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

OFConstraints ct 'PropDelegate props r => OriginateFunc ct props (KeyHash -> r) Source #

Set delegate.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

Methods

originate'r :: OriginateData (ContractOriginateType ct) (GetLarge props) -> KeyHash -> r Source #

(TypeError (('Text "Incorrect argument for the 'originate' function: " :<>: 'ShowType x) :$$: 'Text "If in doubt, try adding a type annotation.") :: Constraint, Bottom) => OriginateFunc ct props (x -> r) Source #

Catchall incoherent instance to report argument errors.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

TerminatingOFConstraints ct props (ReaderT cap base) a => OriginateFunc ct props (ReaderT cap base a) Source #

The terminating case for Cleveland monads.

Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

class ContractClass contract where Source #

Type class that abstracts different contract types for the purpose of origination.

Associated Types

type ContractOriginateType contract :: OriginationType Source #

Instances

Instances details
ContractClass Contract Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

Associated Types

type ContractOriginateType Contract :: OriginationType Source #

(NiceStorage st, NiceViewsDescriptor vd, NiceParameter cp) => ContractClass (TypedContract cp st vd) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

Associated Types

type ContractOriginateType (TypedContract cp st vd) :: OriginationType Source #

ContractClass (Contract cp st vd) Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.Originate

Associated Types

type ContractOriginateType (Contract cp st vd) :: OriginationType Source #

Methods

initialStorageAndContract :: ContractStorage (Contract cp st vd) -> Contract cp st vd -> ODContractAndStorage (ContractOriginateType (Contract cp st vd)) Source #

type family ContractStorage' contract where ... Source #

Equations

ContractStorage' 'OTUntyped = Value 
ContractStorage' ('OTTypedMorley _ st _) = st 
ContractStorage' ('OTTypedLorentz _ st _) = st 

class MonadOpsInternal m => Originator large m where Source #

Class doing actual origination.

originate :: forall contract r. (HasCallStack, ContractClass contract, OriginateFunc contract '[] r) => ContractAlias -> ContractStorage contract -> contract -> r Source #

Originate a new contract with given data.

Can accept untypted or Lorentz contracts as-is. With typed Michelson contracts, you need to wrap the contract in TypedContract specifying its Haskell-land parameter, storage types and view descriptors, e.g.

originate "typed contract" defaultStorage $ TypedContract @Param @Storage @() michelsonContract

Storage type can be auto-deduced in most cases, so you can skip it with @_.

After the mandatory arguments, you can add Large or a Mutez value, e.g. by using tz quasi-quoter:

originate "contract" initialStorage contract Large
originate "contract" initialStorage contract [tz|123micro|]
originate "contract" initialStorage contract [tz|123micro|] Large

The order is arbitrary, but each can be specified at most once.

originateFn :: (HasCallStack, Originator large m) => OriginateData ot large -> m (OriginationResult ot) Source #

Low-level polymorphic origination function. It takes arbitrary OriginateData, and, depending on whether the data is typed or not, returns respectively a ContractHandle, or a ContractAddress, in a suitable monad (or an applicative functor in case of batched originations).

class (MonadTransfer m, MonadOriginate m) => MonadOps m Source #

Synonym typeclass for monads where network operations can occur.

This has instances for MonadCleveland and ClevelandOpsBatch contexts.

Practically, if you want to use transfer or originate in a monad, add a MonadOps constraint on it, f. ex.:

callEp1 :: MonadOps m => ContractHandle MyParam () () -> Integer -> m ()
callEp1 ch = transfer ch . calling (ep @"Entrypoint1")

Instances

Instances details
(MonadTransfer m, MonadOriginate m) => MonadOps m Source # 
Instance details

Defined in Test.Cleveland.Internal.Actions.MonadOps

failure :: forall a caps m. (HasCallStack, MonadCleveland caps m) => Builder -> m a Source #

Fails the test with the given error message.

assert :: (HasCallStack, MonadCleveland caps m) => Bool -> Builder -> m () Source #

Fails the test with the given error message if the given condition is false.

(@==) infix 1 Source #

Arguments

:: (HasCallStack, MonadCleveland caps m, Eq a, Buildable a) 
=> a

The actual value.

-> a

The expected value.

-> m () 

x @== expected fails the test if x is not equal to expected.

(@/=) :: (HasCallStack, MonadCleveland caps m, Eq a, Buildable a) => a -> a -> m () infix 1 Source #

Fails the test if the two given values are equal.

(@@==) infix 1 Source #

Arguments

:: (HasCallStack, MonadCleveland caps m, Eq a, Buildable a) 
=> m a

The actual value.

-> a

The expected value.

-> m () 

Monadic version of @==.

getBalance addr @@== 10

(@@/=) :: (HasCallStack, MonadCleveland caps m, Eq a, Buildable a) => m a -> a -> m () infix 1 Source #

Monadic version of @/=.

getBalance addr @@/= 10

checkCompares :: forall a b caps m. (HasCallStack, MonadCleveland caps m, Buildable a, Buildable b) => a -> (a -> b -> Bool) -> b -> m () Source #

Fails the test if the comparison operator fails when applied to the given arguments. Prints an error message with both arguments.

Example:

checkCompares 2 (>) 1

checkComparesWith :: forall a b caps m. (HasCallStack, MonadCleveland caps m) => (a -> Text) -> a -> (a -> b -> Bool) -> (b -> Text) -> b -> m () Source #

Like checkCompares, but with an explicit show function. This function does not have any constraint on the type parameters a and b.

For example, to print with pretty:

checkComparesWith pretty a (<) pretty b

evalJust :: (HasCallStack, MonadCleveland caps m) => Builder -> Maybe a -> m a Source #

Fails the test if the Maybe is Nothing, otherwise returns the value in the Just.

evalRight :: (HasCallStack, MonadCleveland caps m) => (a -> Builder) -> Either a b -> m b Source #

Fails the test if the Either is Left, otherwise returns the value in the Right.

type EqBaseMonad a b = ClevelandBaseMonad a ~ ClevelandBaseMonad b Source #

A helper constraint synonym to make signatures below a bit shorter

withSender :: MonadCleveland caps m => ImplicitAddressWithAlias -> m a -> m a Source #

Update the current sender on whose behalf transfers and originations are invoked.

withMoneybag :: MonadCleveland caps m => ImplicitAddressWithAlias -> m a -> m a Source #

Update the current moneybag that transfers money on the newly created addresses. For the rare occasions when this is necessary.

runIO :: (HasCallStack, MonadCleveland caps m) => IO res -> m res Source #

Runs an IO action.

resolveAddress :: (HasCallStack, MonadCleveland caps m) => Alias kind -> m (KindedAddress kind) Source #

Get the address of the implicit account / contract associated with the given alias.

refillable :: (ToImplicitAddress addr, MonadCleveland caps m) => m addr -> m addr Source #

Simple combinator that marks address as "refillable".

If a refillable address lacks funds for the next operation, some funds will automatically be transferred to it.

refillables :: (ToImplicitAddress addr, Traversable f, MonadCleveland caps m) => m (f addr) -> m (f addr) Source #

Mark multiple addresses as refillable, useful with newAddresses &c.

newAddress :: (HasCallStack, MonadCleveland caps m) => SpecificOrDefaultAlias -> m ImplicitAddressWithAlias Source #

If the given alias is already associated with an existing address, that address will be reused and returned. Otherwise, generate a new secret key and record it with given alias.

If the account has too low of a balance, a small amount of XTZ will be transferred to it.

Notes:

  • By default, the XTZ is transferred from 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 withMoneybag.

newAddresses :: forall n n' caps m. (HasCallStack, MonadCleveland caps m, IsoNatPeano n n') => SizedList n SpecificOrDefaultAlias -> m (SizedList n ImplicitAddressWithAlias) Source #

Batched version of newAddress

newFreshAddress :: (HasCallStack, MonadCleveland caps m) => SpecificOrDefaultAlias -> m ImplicitAddressWithAlias Source #

Generate a new secret key and record it with given alias. If the alias is already known, the key will be overwritten. The address is guaranteed to be fresh, i. e. no operations on it have been made.

signBytes :: (HasCallStack, MonadCleveland caps m) => ByteString -> ImplicitAddressWithAlias -> m Signature Source #

Get the signature of the preapplied operation.

enumAliases :: forall n n'. (SingIPeano n, IsoNatPeano n n') => ImplicitAlias -> SizedList n SpecificOrDefaultAlias Source #

Create a list of similarly named SpecificAliases.

For example,

>>> enumAliases @2 "operator" `isEquivalentTo` "operator-0" :< "operator-1" :< Nil
True

signBinary :: (HasCallStack, BytesLike bs, MonadCleveland caps m) => bs -> ImplicitAddressWithAlias -> m (TSignature bs) Source #

Type-safer version of signBytes.

importUntypedContract :: (HasCallStack, MonadCleveland caps m) => FilePath -> m Contract Source #

Import an untyped contract from file.

importContract :: (HasCallStack, NiceParameter param, NiceStorage st, NiceViewsDescriptor vd, DemoteViewsDescriptor vd, MonadCleveland caps m) => FilePath -> m (Contract param st vd) Source #

Import a contract from file.

The compiler must be able to infer the types of parameter, storage and views. In case there are no views or you don't care, you can use noViews.

inBatch :: (HasCallStack, MonadCleveland caps m) => ClevelandOpsBatch a -> m a Source #

Run operations in a batch. Best used with the ApplicativeDo GHC extension.

Example:


contract <- inBatch $ do
  contract <- originate ...
  for_ [1..3] i ->
    transfer ...
  return contract

Batched operations should be applied to chain faster, but note that batches have their own limits. For instance, at the moment of writing, the gas limit on a batch is 10x of gas limit applied to a single operation.

A context of a batch is only Applicative, not Monad. This means that:

  • Return values of one function cannot be passed to another function in the same batch, it can only be returned;
  • Sometimes the compiler does not recognize that only Applicative context is required, in case of any issues with that - follow the error messages.

comment :: (HasCallStack, MonadCleveland caps m) => Text -> m () Source #

Print the given string verbatim as a comment. At the moment, this is a no-op in emulator tests.

getBalance :: (HasCallStack, MonadCleveland caps m, ToL1Address addr) => addr -> m Mutez Source #

Get the balance of the given address.

getDelegate :: (HasCallStack, MonadCleveland caps m, ToL1Address addr) => addr -> m (Maybe KeyHash) Source #

Get the delegate for the given contract/implicit address.

registerDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddressWithAlias -> m () Source #

Register the given implicit address as a delegate.

setDelegate :: (HasCallStack, MonadCleveland caps m) => ImplicitAddressWithAlias -> Maybe KeyHash -> m () Source #

Set/unset delegate

getStorage :: forall st addr caps m. (HasCallStack, MonadCleveland caps m, ToStorageType st addr, IsoValue (AsRPC st)) => addr -> m (AsRPC st) Source #

Retrieve a contract's storage in its "RPC representation" (i.e., all its big_maps will be replaced by big_map IDs).

If the storage is of a user-defined type, then deriveRPC / deriveManyRPC should be used to create an RPC representation of the storage type.

data MyStorage = MyStorage { field1 :: Natural, field2 :: BigMap Integer MText }
deriveRPC "MyStorage"

getFullStorage :: forall st addr caps m. (HasCallStack, MonadEmulated caps m, ToStorageType st addr) => addr -> m st Source #

Retrieve a contract's full storage, including the contents of its big_maps.

This function can only be used in emulator-only tests.

getSomeStorage :: forall addr caps m. (HasCallStack, MonadCleveland caps m, ToContractAddress addr) => addr -> m SomeAnnotatedValue Source #

Similar to getStorage, but doesn't require knowing the storage type in advance.

Use the optics in AnnotatedValue to read data from the storage.

getBigMapValueMaybe :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NicePackedValue k, NiceUnpackedValue v) => BigMapId k v -> k -> m (Maybe v) Source #

Retrieve a big_map value, given a big_map ID and a key. Returns Nothing when the big_map ID does not exist, or it exists but does not contain the given key.

getBigMapValue :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NicePackedValue k, NiceUnpackedValue v, Buildable k) => BigMapId k v -> k -> m v Source #

Like getBigMapValueMaybe, but fails the tests instead of returning Nothing.

getAllBigMapValuesMaybe :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m (Maybe [v]) Source #

Retrieve all big_map values, given a big_map ID. Returns Nothing when the big_map ID does not exist.

getAllBigMapValues :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m [v] Source #

Like getAllBigMapValuesMaybe, but fails the tests instead of returning Nothing.

getBigMapSizeMaybe :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m (Maybe Natural) Source #

Retrieve a big_map size, given a big_map ID. Returns Nothing when the big_map ID does not exist.

O(n), because it's implemented with getBigMapValues.

getBigMapSize :: forall k v caps m. (HasCallStack, MonadCleveland caps m, NiceComparable k, NiceUnpackedValue v) => BigMapId k v -> m Natural Source #

Like getBigMapSizeMaybe, but fails the tests instead of returning Nothing.

getPublicKey :: (HasCallStack, MonadCleveland caps m) => ImplicitAddressWithAlias -> m PublicKey Source #

Get the public key associated with given address. Fail if given address is not an implicit account.

getChainId :: (HasCallStack, MonadCleveland caps m) => m ChainId Source #

Get the chain's ChainId.

advanceTime :: forall unit caps m. (HasCallStack, MonadCleveland caps m, KnownDivRat unit Second) => Time unit -> m () Source #

Advance at least the given amount of time, or until a new block is baked, whichever happens last.

On a real network, this is implemented using threadDelay, so it's advisable to use small amounts of time only.

advanceLevel :: forall caps m. (HasCallStack, MonadCleveland caps m) => Natural -> m () Source #

Wait till the provided number of levels is past.

advanceToLevel :: forall caps m. (HasCallStack, MonadCleveland caps m) => Natural -> m () Source #

Wait till the provided level is reached.

getNow :: (HasCallStack, MonadCleveland caps m) => m Timestamp Source #

Get the timestamp observed by the last block to be baked.

getLevel :: (HasCallStack, MonadCleveland caps m) => m Natural Source #

Get the current level observed by the last block to be baked.

getApproximateBlockInterval :: (HasCallStack, MonadCleveland caps m) => m (Time Second) Source #

Get approximate block interval in seconds. Note, that this value is minimal bound and real intervals can be larger, see http://tezos.gitlab.io/active/consensus.html#minimal-block-delay-function for more information about block delays.

getMinBlockTime :: (HasCallStack, MonadCleveland caps m) => m Natural Source #

Get minimal block delay in seconds. This is essentially the same as getApproximateBlockInterval, but returns a Natural instead of Time Second.

Can be useful when testing code using MIN_BLOCK_TIME instruction.

runCode :: (HasCallStack, MonadCleveland caps m, HasRPCRepr st, IsoValue (AsRPC st)) => RunCode cp st vd -> m (AsRPC st) Source #

Execute a contract's code without originating it. The chain's state will not be modified.

Notes:

  • If the contract's code emits operations, they will not be executed.
  • The sender's account won't be debited.
  • When running an _originated_ contract, the BALANCE instruction returns the sum of the contract's balance before the transfer operation + the amount of tz being transferred. In other words, this invariant holds: BALANCE >= AMOUNT. However, since runCode allows overriding the BALANCE instruction, then this invariant no longer holds. It's possible that BALANCE < AMOUNT.

branchout :: forall caps m. MonadEmulated caps m => [(Text, m ())] -> m () Source #

Execute multiple testing scenarios independently.

  • Actions performed before branchout will be observed by all branches.
  • Actions performed in branches will _not_ be observed by any actions performed after branchout.
  • Actions performed in one branch will _not_ be observed by another branch.
  • The test succeeds IFF all branches succeed.
  • If any branch fails, the test ends immediately and the remaining branches won't be executed.

The following property holds:

pre >> branchout [a, b, c] = branchout [pre >> a, pre >> b, pre >> c]

The list of branches must be non-empty.

offshoot :: forall caps m. MonadEmulated caps m => Text -> m () -> m () Source #

Execute one or more actions and roll them back afterwards. Actions performed in offshoot will _not_ be observed by any actions performed after offshoot.

Similar to branchout, but accepts one single branch.

getMorleyLogs :: forall a caps m. MonadEmulated caps m => m a -> m (LogsInfo, a) Source #

Returns the result of the action with the logs it produced. Logs are messages printed by the Lorentz instruction printComment.

This function can be combined either with lens-based accessors or helper functions to get more specific information about logs.

Examples:

(logsInfo, _) <- getMorleyLogs scenario
logsInfo ^.. each . logsL == [MorleyLogs ["log"], MorleyLogs ["log2"]]
logsInfo ^.. each . filterLogsByAddrL addr == [MorleyLogs ["log"]]
(logsInfo, _) <- getMorleyLogs scenario
collectLogs logsInfo == MorleyLogs ["log", "log2"]
logsForAddress logsInfo == [MorleyLogs ["log"]]

getMorleyLogs_ :: MonadEmulated caps m => m () -> m LogsInfo Source #

Version of getMorleyLogs for actions that don't return a result.

setVotingPowers :: MonadEmulated caps m => VotingPowers -> m () Source #

Updates voting power accessible via VOTING_POWER and similar instructions.

whenEmulation :: MonadCleveland caps m => (forall caps1 m1. (EqBaseMonad caps caps1, MonadEmulated caps1 m1) => m1 ()) -> m () Source #

Perform an action if we are currently in emulation mode. See also ifEmulation note on constraints.

whenNetwork :: MonadCleveland caps m => (forall caps1 m1. (EqBaseMonad caps caps1, MonadNetwork caps1 m1) => m1 ()) -> m () Source #

Perform an action if we are currently in network mode. See also ifEmulation note on constraints.

ifEmulation :: forall a caps m. MonadCleveland caps m => (forall caps1 m1. (EqBaseMonad caps caps1, MonadEmulated caps1 m1) => m1 a) -> (forall caps1 m1. (EqBaseMonad caps caps1, MonadNetwork caps1 m1) => m1 a) -> m a Source #

Perform one action if we are currently in emulation mode, another otherwise

Functions passed as the first two arguments are universally quantified over the outer monad, so if additional constraints are required beyond MonadEmulated or MonadCleveland, those constraints have to go on the base monad, e.g.

someFunction :: (MonadCleveland caps m, MonadFail (ClevelandBaseMonad caps)) => m ()
someFunction = whenEmulation do
  Just x <- pure (Just 1 :: Maybe Int) -- this would error without MonadFail
  runIO $ print x

getMorleyClientEnv :: MonadNetwork caps m => m MorleyClientEnv Source #

Get a MorleyClientEnv when running a test on network. Useful to run 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.

getOnlyRpcEnv :: MonadNetwork caps m => [SecretKey] -> m MorleyOnlyRpcEnv Source #

Get a MorleyOnlyRpcEnv when running a test on network. Useful to run raw network actions inside a network test.

This is considered a pretty low-level function, so it's better to avoid it in most cases.

importSecretKey :: MonadCleveland caps m => SecretKey -> SpecificOrDefaultAlias -> m ImplicitAddressWithAlias Source #

Import an (unencrypted) secret key as an alias. Can be used to get an implicit address/alias with a specific key or key type. If you don't care about the key or key type, consider using newAddress or newAddresses instead.

getTicketBalance :: (MonadCleveland caps m, HasNoOpToT a, NiceComparable a, ToL1Address addr, ToContractAddress contractAddr) => addr -> contractAddr -> a -> m Natural Source #

Get balance for a particular ticket.

getAllTicketBalances :: (MonadCleveland caps m, ToContractAddress addr) => addr -> m [SomeTicket] Source #

Get balance for all contract's tickets.

callView Source #

Arguments

:: 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

Contract to call.

-> Label name

View name. Use OverloadedLabels syntax.

-> arg

Parameter to pass to the view.

-> m (AsRPC ret) 

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)

unsafeCallView Source #

Arguments

:: 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

Contract to call.

-> Label name

View name. Use OverloadedLabels syntax.

-> arg

Parameter to pass to the view.

-> m (AsRPC ret) 

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)

runnerContract :: forall name arg ret. (NiceParameter arg, NiceViewable ret, NiceStorage ret, KnownSymbol name) => ContractAddress -> Contract arg (Maybe ret) () Source #

Contract that calls a view and saves the result to storage.

attempt :: forall e caps m a. (HasCallStack, MonadCleveland caps m, Exception e) => m a -> m (Either e a) Source #

Attempt to run an action and return its result or, if interpretation fails, an error.

catchTransferFailure :: (HasCallStack, MonadCleveland caps m) => m a -> m TransferFailure Source #

Asserts that a transfer should fail, and returns the exception.

expectTransferFailure :: (HasCallStack, MonadCleveland caps m) => TransferFailurePredicate -> m a -> m () Source #

Asserts that a transfer should fail, and runs some TransferFailurePredicates over the exception.

expectTransferFailure (failedWith (constant @MText "NOT_ADMIN")) $
  call contractAddr (Call @"Ep") arg
call contractAddr (Call @"Ep") arg & expectTransferFailure
  ( failedWith (customError #tag 3) &&
    addressIs contractAddr
  )

checkTransferFailure :: (HasCallStack, MonadCleveland caps m) => TransferFailure -> TransferFailurePredicate -> m () Source #

Check whether a given predicate holds for a given TransferFailure.

expectFailedWith :: forall err a caps m. (HasCallStack, MonadCleveland caps m, NiceConstant err) => err -> m a -> m () Source #

Asserts that interpretation of a contract ended with FAILWITH, returning the given constant value.

expectError :: forall err a caps m. (HasCallStack, MonadCleveland caps m, IsError err) => err -> m a -> m () Source #

Asserts that interpretation of a contract ended with FAILWITH, returning the given lorentz error.

expectCustomError :: forall arg a tag caps m. (HasCallStack, MonadCleveland caps m, IsError (CustomError tag), MustHaveErrorArg tag (MText, arg)) => Label tag -> arg -> m a -> m () Source #

Asserts that interpretation of a contract ended with FAILWITH, returning the given custom lorentz error.

expectCustomError_ :: (HasCallStack, MonadCleveland caps m, IsError (CustomError tag), MustHaveErrorArg tag (MText, ())) => Label tag -> m a -> m () Source #

Version of expectCustomError for error with unit argument.

expectCustomErrorNoArg :: (HasCallStack, MonadCleveland caps m, IsError (CustomError tag), MustHaveErrorArg tag MText) => Label tag -> m a -> m () Source #

Version of expectCustomError specialized for expecting NoErrorArgs.

expectCustomErrorAnyArg :: (HasCallStack, MonadCleveland caps m) => Label tag -> m a -> m () Source #

Version of expectCustomError that ignores the argument (or whether it even exists) and only checks the tag.

expectNumericError :: forall err a caps m. (HasCallStack, MonadCleveland caps m, IsError err) => ErrorTagMap -> err -> m a -> m () Source #

Asserts that interpretation of a contract ended with FAILWITH, returning the given lorentz numeric error.

clarifyErrors :: forall caps m a. MonadCleveland caps m => Builder -> m a -> m a Source #

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 : .

This affects errors produced by functions like failure, assert, @==, etc. Errors related to events in the chain will not be touched.

Example:

for [1..10] \i -> clarifyErrors ("For i=" +| i |+ "") $
  askContract i @@== i * 2