cleveland-0.3.1: src/Test/Cleveland/Internal/Scenario.hs
-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA
{-# OPTIONS_HADDOCK not-home #-}
module Test.Cleveland.Internal.Scenario
( module Test.Cleveland.Internal.Scenario
) where
import Control.Monad.Reader (withReaderT)
import Morley.Michelson.Runtime.GState (gsChainIdL)
import Morley.Tezos.Core qualified as TC
import Test.Cleveland.Internal.Abstract
import Test.Cleveland.Internal.Client
import Test.Cleveland.Internal.Pure
-- | A convenience type synonym for `Scenario'` that has 'MonadScenario'
-- constraint baked in.
type Scenario m = MonadScenario m => Scenario' m
-- | A type representing a finalized scenario. Usually, when using this type
-- with a polymorphic argument, an additional 'MonadScenario' constraint on the
-- argument is required.
--
-- To avoid annotating with 'MonadScenario' everywhere, consider using
-- 'Scenario' instead when possible.
data Scenario' m where
ScenarioEmulated :: EmulatedT PureM () -> Scenario' PureM
ScenarioNetwork :: NetworkT ClientM () -> Scenario' ClientM
-- | Typeclass for base monads that can implement a scenario.
class MonadFail m => MonadScenario m where
-- | Finalize a generic cleveland scenario.
scenario :: ClevelandT m () -> Scenario' m
instance MonadScenario PureM where
scenario = ScenarioEmulated . withReaderT (view clevelandCapsL)
instance MonadScenario ClientM where
scenario = ScenarioNetwork . withReaderT (view clevelandCapsL)
-- | Finalize a scenario that needs emulator-only features.
scenarioEmulated :: EmulatedT PureM () -> Scenario' PureM
scenarioEmulated = ScenarioEmulated
-- | Finalize a scenario that needs network-only features.
scenarioNetwork :: NetworkT ClientM () -> Scenario' ClientM
scenarioNetwork = ScenarioNetwork
withModifiedState
:: (PureState -> PureState)
-> Scenario' PureM
-> Scenario' PureM
withModifiedState modfn (ScenarioEmulated emulated) =
ScenarioEmulated $ lift (modify modfn) >> emulated
-- | Use with an emulated 'Scenario' to configure the initial @now@ value in tests.
--
-- Example :
-- > testScenarioOnEmulator "Testname" $ withInitialNow (Timestamp 10000000) $ scenarioEmulated $ tests
-- > testScenarioOnEmulator "Testname" $ withInitialNow (Timestamp 10000000) $ scenario $ tests
withInitialNow
:: TC.Timestamp
-> Scenario' PureM
-> Scenario' PureM
withInitialNow = withModifiedState . set psNow
-- | Similar to 'withInitialNow' but for the initial level
withInitialLevel
:: Natural
-> Scenario' PureM
-> Scenario' PureM
withInitialLevel = withModifiedState . set psLevel
-- | Similar to 'withInitialNow' but for the @MINIMAL_BLOCK_DELAY@ protocol constant.
withMinBlockTime
:: Natural
-> Scenario' PureM
-> Scenario' PureM
withMinBlockTime = withModifiedState . set psMinBlockTime
-- | Similar to 'withInitialNow' but for the chain id
withChainId
:: TC.ChainId
-> Scenario' PureM
-> Scenario' PureM
withChainId = withModifiedState . set (psGState . gsChainIdL)