{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE KindSignatures #-}

-- | This module contains MockT and SetupMockT state functions.
module Test.HMock.Internal.State where

import Control.Monad (forM_, unless, (<=<))
import Control.Monad.Base (MonadBase)
import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow)
import Control.Monad.Cont (MonadCont)
import Control.Monad.Except (MonadError)
import Control.Monad.Extra (maybeM)
import Control.Monad.IO.Class (liftIO)
import Control.Monad.RWS (MonadRWS)
import Control.Monad.Reader (MonadReader (..), ReaderT, mapReaderT, runReaderT)
import Control.Monad.State (MonadState)
import Control.Monad.Trans (MonadTrans, lift)
import Control.Monad.Writer (MonadWriter)
import Data.Proxy (Proxy (Proxy))
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Typeable (TypeRep, Typeable, typeRep)
import GHC.Stack (withFrozenCallStack, HasCallStack)
import GHC.TypeLits (KnownSymbol, symbolVal)
import System.IO (hPutStrLn, stderr)
import Test.HMock.ExpectContext (ExpectContext (..))
import Test.HMock.Internal.ExpectSet (ExpectSet (..), getSteps)
import Test.HMock.Internal.Step (SingleRule, Step (..), unwrapExpected)
import Test.HMock.Internal.Util (Located)
import Test.HMock.Mockable (Mockable (..))
import UnliftIO
  ( MonadIO,
    MonadUnliftIO(withRunInIO),
    STM,
    TVar,
    atomically,
    modifyTVar,
    newTVarIO,
    readTVar,
    readTVarIO,
  )
import Data.Kind (Type, Constraint)

#if !MIN_VERSION_base(4, 13, 0)
import Control.Monad.Fail (MonadFail)
#endif

-- | The severity for a possible problem.
data Severity
  = -- | Fail the test.
    Error
  | -- | Print a message, but continue the test.
    Warning
  | -- | Don't do anything.
    Ignore

-- | Full state of a mock.
data MockState m = MockState
  { forall (m :: * -> *). MockState m -> TVar (ExpectSet (Step m))
mockExpectSet :: TVar (ExpectSet (Step m)),
    forall (m :: * -> *). MockState m -> TVar [Step m]
mockDefaults :: TVar [Step m],
    forall (m :: * -> *). MockState m -> TVar [Step m]
mockAllowUnexpected :: TVar [Step m],
    forall (m :: * -> *). MockState m -> TVar [Step m]
mockSideEffects :: TVar [Step m],
    forall (m :: * -> *). MockState m -> TVar Severity
mockAmbiguitySeverity :: TVar Severity,
    forall (m :: * -> *). MockState m -> TVar Severity
mockUnexpectedSeverity :: TVar Severity,
    forall (m :: * -> *). MockState m -> TVar Severity
mockUninterestingSeverity :: TVar Severity,
    forall (m :: * -> *). MockState m -> TVar Severity
mockUnmetSeverity :: TVar Severity,
    forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses :: TVar (Set TypeRep),
    forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods :: TVar (Set (TypeRep, String)),
    forall (m :: * -> *). MockState m -> Maybe (MockState m)
mockParent :: Maybe (MockState m)
  }

-- | Initializes a new 'MockState' with the given parent.  If the parent is
-- 'Nothing', then a new root state is made.
initMockState :: MonadIO m => Maybe (MockState m) -> m (MockState m)
initMockState :: forall (m :: * -> *).
MonadIO m =>
Maybe (MockState m) -> m (MockState m)
initMockState Maybe (MockState m)
parent =
  forall (m :: * -> *).
TVar (ExpectSet (Step m))
-> TVar [Step m]
-> TVar [Step m]
-> TVar [Step m]
-> TVar Severity
-> TVar Severity
-> TVar Severity
-> TVar Severity
-> TVar (Set TypeRep)
-> TVar (Set (TypeRep, String))
-> Maybe (MockState m)
-> MockState m
MockState
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall step. ExpectSet step
ExpectNothing
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Ignore)
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar Severity
mockAmbiguitySeverity)
      (forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar Severity
mockUnexpectedSeverity)
      (forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar Severity
mockUninterestingSeverity)
      (forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar Severity
mockUnmetSeverity)
      (forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall a. Set a
Set.empty) (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses) Maybe (MockState m)
parent
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO forall a. Set a
Set.empty) (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods) Maybe (MockState m)
parent
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (MockState m)
parent

-- | Gets a list of all states, starting with the innermost.
allStates :: MockState m -> [MockState m]
allStates :: forall (m :: * -> *). MockState m -> [MockState m]
allStates MockState m
s
  | Just MockState m
s' <- forall (m :: * -> *). MockState m -> Maybe (MockState m)
mockParent MockState m
s = MockState m
s forall a. a -> [a] -> [a]
: forall (m :: * -> *). MockState m -> [MockState m]
allStates MockState m
s'
  | Bool
otherwise = [MockState m
s]

-- | Gets the root state.
rootState :: MockState m -> MockState m
rootState :: forall (m :: * -> *). MockState m -> MockState m
rootState = forall a. [a] -> a
last forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MockState m -> [MockState m]
allStates

-- | Monad for setting up a mockable class.  Note that even though the type
-- looks that way, this is *not* a monad transformer.  It's a very restricted
-- environment that can only be used to set up defaults for a class.
newtype MockSetup m a where
  MockSetup :: {forall (m :: * -> *) a.
MockSetup m a -> ReaderT (MockState m) STM a
unMockSetup :: ReaderT (MockState m) STM a} -> MockSetup m a
  deriving (forall a b. a -> MockSetup m b -> MockSetup m a
forall a b. (a -> b) -> MockSetup m a -> MockSetup m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (m :: * -> *) a b. a -> MockSetup m b -> MockSetup m a
forall (m :: * -> *) a b.
(a -> b) -> MockSetup m a -> MockSetup m b
<$ :: forall a b. a -> MockSetup m b -> MockSetup m a
$c<$ :: forall (m :: * -> *) a b. a -> MockSetup m b -> MockSetup m a
fmap :: forall a b. (a -> b) -> MockSetup m a -> MockSetup m b
$cfmap :: forall (m :: * -> *) a b.
(a -> b) -> MockSetup m a -> MockSetup m b
Functor, forall a. a -> MockSetup m a
forall a b. MockSetup m a -> MockSetup m b -> MockSetup m a
forall a b. MockSetup m a -> MockSetup m b -> MockSetup m b
forall a b. MockSetup m (a -> b) -> MockSetup m a -> MockSetup m b
forall a b c.
(a -> b -> c) -> MockSetup m a -> MockSetup m b -> MockSetup m c
forall (m :: * -> *). Functor (MockSetup m)
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *) a. a -> MockSetup m a
forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m a
forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m b
forall (m :: * -> *) a b.
MockSetup m (a -> b) -> MockSetup m a -> MockSetup m b
forall (m :: * -> *) a b c.
(a -> b -> c) -> MockSetup m a -> MockSetup m b -> MockSetup m c
<* :: forall a b. MockSetup m a -> MockSetup m b -> MockSetup m a
$c<* :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m a
*> :: forall a b. MockSetup m a -> MockSetup m b -> MockSetup m b
$c*> :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m b
liftA2 :: forall a b c.
(a -> b -> c) -> MockSetup m a -> MockSetup m b -> MockSetup m c
$cliftA2 :: forall (m :: * -> *) a b c.
(a -> b -> c) -> MockSetup m a -> MockSetup m b -> MockSetup m c
<*> :: forall a b. MockSetup m (a -> b) -> MockSetup m a -> MockSetup m b
$c<*> :: forall (m :: * -> *) a b.
MockSetup m (a -> b) -> MockSetup m a -> MockSetup m b
pure :: forall a. a -> MockSetup m a
$cpure :: forall (m :: * -> *) a. a -> MockSetup m a
Applicative, forall a. a -> MockSetup m a
forall a b. MockSetup m a -> MockSetup m b -> MockSetup m b
forall a b. MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b
forall (m :: * -> *). Applicative (MockSetup m)
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
forall (m :: * -> *) a. a -> MockSetup m a
forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m b
forall (m :: * -> *) a b.
MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b
return :: forall a. a -> MockSetup m a
$creturn :: forall (m :: * -> *) a. a -> MockSetup m a
>> :: forall a b. MockSetup m a -> MockSetup m b -> MockSetup m b
$c>> :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m b
>>= :: forall a b. MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b
$c>>= :: forall (m :: * -> *) a b.
MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b
Monad)

-- | Runs a setup action with the root state, rather than the current one.
runInRootState :: MockSetup m a -> MockSetup m a
runInRootState :: forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState = forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local forall (m :: * -> *). MockState m -> MockState m
rootState forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MockSetup m a -> ReaderT (MockState m) STM a
unMockSetup

-- | Run an STM action in 'MockSetup'
mockSetupSTM :: STM a -> MockSetup m a
mockSetupSTM :: forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM STM a
m = forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup (forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift STM a
m)

-- | Runs class initialization for a 'Mockable' class, if it hasn't been run
-- yet.
initClassIfNeeded ::
  forall cls m proxy.
  (Mockable cls, Typeable m, MonadIO m) =>
  proxy cls ->
  MockSetup m ()
initClassIfNeeded :: forall (cls :: (* -> *) -> Constraint) (m :: * -> *)
       (proxy :: ((* -> *) -> Constraint) -> *).
(Mockable cls, Typeable m, MonadIO m) =>
proxy cls -> MockSetup m ()
initClassIfNeeded proxy cls
proxy = forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup forall r (m :: * -> *). MonadReader r m => m r
ask
  Set TypeRep
classes <- forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> STM a
readTVar (forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses MockState m
state)
  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall a. Ord a => a -> Set a -> Bool
Set.member TypeRep
t Set TypeRep
classes) forall a b. (a -> b) -> a -> b
$ do
    forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> (a -> a) -> STM ()
modifyTVar (forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses MockState m
state) (forall a. Ord a => a -> Set a -> Set a
Set.insert TypeRep
t)
    forall (cls :: (* -> *) -> Constraint) (m :: * -> *)
       (proxy :: ((* -> *) -> Constraint) -> *).
(Mockable cls, MonadIO m, Typeable m) =>
proxy cls -> MockSetup m ()
setupMockable (forall {k} (t :: k). Proxy t
Proxy :: Proxy cls)
  where
    t :: TypeRep
t = forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep proxy cls
proxy

-- | Marks a method as "interesting".  This can have implications for what
-- happens to calls to that method.
markInteresting ::
  forall (cls :: (Type -> Type) -> Constraint) name m proxy1 proxy2.
  (Typeable cls, KnownSymbol name) =>
  proxy1 cls ->
  proxy2 name ->
  MockSetup m ()
markInteresting :: forall (cls :: (* -> *) -> Constraint) (name :: Symbol)
       (m :: * -> *) (proxy1 :: ((* -> *) -> Constraint) -> *)
       (proxy2 :: Symbol -> *).
(Typeable cls, KnownSymbol name) =>
proxy1 cls -> proxy2 name -> MockSetup m ()
markInteresting proxy1 cls
proxyCls proxy2 name
proxyName = forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup forall r (m :: * -> *). MonadReader r m => m r
ask
  forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM forall a b. (a -> b) -> a -> b
$
    forall a. TVar a -> (a -> a) -> STM ()
modifyTVar
      (forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods MockState m
state)
      (forall a. Ord a => a -> Set a -> Set a
Set.insert (forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep proxy1 cls
proxyCls, forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal proxy2 name
proxyName))

-- | Determines whether a method is "interesting".
isInteresting :: 
  forall (cls :: (Type -> Type) -> Constraint) name m proxy1 proxy2.
  (Typeable cls, KnownSymbol name) =>
  proxy1 cls ->
  proxy2 name ->
  MockSetup m Bool
isInteresting :: forall (cls :: (* -> *) -> Constraint) (name :: Symbol)
       (m :: * -> *) (proxy1 :: ((* -> *) -> Constraint) -> *)
       (proxy2 :: Symbol -> *).
(Typeable cls, KnownSymbol name) =>
proxy1 cls -> proxy2 name -> MockSetup m Bool
isInteresting proxy1 cls
proxyCls proxy2 name
proxyName = forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup forall r (m :: * -> *). MonadReader r m => m r
ask
  Set (TypeRep, String)
interesting <- forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> STM a
readTVar (forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods MockState m
state)
  forall (m :: * -> *) a. Monad m => a -> m a
return ((forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep proxy1 cls
proxyCls, forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal proxy2 name
proxyName) forall a. Ord a => a -> Set a -> Bool
`Set.member` Set (TypeRep, String)
interesting)

-- | Runs class initialization for all uninitialized 'Mockable' classes in the
-- given 'ExpectSet'.
initClassesAsNeeded :: MonadIO m => ExpectSet (Step m) -> MockSetup m ()
initClassesAsNeeded :: forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
initClassesAsNeeded ExpectSet (Step m)
es = forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState forall a b. (a -> b) -> a -> b
$
  forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall step. ExpectSet step -> [step]
getSteps ExpectSet (Step m)
es) forall a b. (a -> b) -> a -> b
$
    \(Step (Located (SingleRule cls name m r)
_ :: Located (SingleRule cls name m r))) -> do
      forall (cls :: (* -> *) -> Constraint) (m :: * -> *)
       (proxy :: ((* -> *) -> Constraint) -> *).
(Mockable cls, Typeable m, MonadIO m) =>
proxy cls -> MockSetup m ()
initClassIfNeeded (forall {k} (t :: k). Proxy t
Proxy :: Proxy cls)
      forall (cls :: (* -> *) -> Constraint) (name :: Symbol)
       (m :: * -> *) (proxy1 :: ((* -> *) -> Constraint) -> *)
       (proxy2 :: Symbol -> *).
(Typeable cls, KnownSymbol name) =>
proxy1 cls -> proxy2 name -> MockSetup m ()
markInteresting (forall {k} (t :: k). Proxy t
Proxy :: Proxy cls) (forall {k} (t :: k). Proxy t
Proxy :: Proxy name)

-- | Monad transformer for running mocks.
newtype MockT m a where
  MockT :: {forall (m :: * -> *) a. MockT m a -> ReaderT (MockState m) m a
unMockT :: ReaderT (MockState m) m a} -> MockT m a
  deriving
    ( forall a b. a -> MockT m b -> MockT m a
forall a b. (a -> b) -> MockT m a -> MockT m b
forall (m :: * -> *) a b. Functor m => a -> MockT m b -> MockT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> MockT m a -> MockT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> MockT m b -> MockT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> MockT m b -> MockT m a
fmap :: forall a b. (a -> b) -> MockT m a -> MockT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> MockT m a -> MockT m b
Functor,
      forall a. a -> MockT m a
forall a b. MockT m a -> MockT m b -> MockT m a
forall a b. MockT m a -> MockT m b -> MockT m b
forall a b. MockT m (a -> b) -> MockT m a -> MockT m b
forall a b c. (a -> b -> c) -> MockT m a -> MockT m b -> MockT m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall {m :: * -> *}. Applicative m => Functor (MockT m)
forall (m :: * -> *) a. Applicative m => a -> MockT m a
forall (m :: * -> *) a b.
Applicative m =>
MockT m a -> MockT m b -> MockT m a
forall (m :: * -> *) a b.
Applicative m =>
MockT m a -> MockT m b -> MockT m b
forall (m :: * -> *) a b.
Applicative m =>
MockT m (a -> b) -> MockT m a -> MockT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> MockT m a -> MockT m b -> MockT m c
<* :: forall a b. MockT m a -> MockT m b -> MockT m a
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
MockT m a -> MockT m b -> MockT m a
*> :: forall a b. MockT m a -> MockT m b -> MockT m b
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
MockT m a -> MockT m b -> MockT m b
liftA2 :: forall a b c. (a -> b -> c) -> MockT m a -> MockT m b -> MockT m c
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> MockT m a -> MockT m b -> MockT m c
<*> :: forall a b. MockT m (a -> b) -> MockT m a -> MockT m b
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
MockT m (a -> b) -> MockT m a -> MockT m b
pure :: forall a. a -> MockT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> MockT m a
Applicative,
      forall a. a -> MockT m a
forall a b. MockT m a -> MockT m b -> MockT m b
forall a b. MockT m a -> (a -> MockT m b) -> MockT m b
forall {m :: * -> *}. Monad m => Applicative (MockT m)
forall (m :: * -> *) a. Monad m => a -> MockT m a
forall (m :: * -> *) a b.
Monad m =>
MockT m a -> MockT m b -> MockT m b
forall (m :: * -> *) a b.
Monad m =>
MockT m a -> (a -> MockT m b) -> MockT m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> MockT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> MockT m a
>> :: forall a b. MockT m a -> MockT m b -> MockT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
MockT m a -> MockT m b -> MockT m b
>>= :: forall a b. MockT m a -> (a -> MockT m b) -> MockT m b
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
MockT m a -> (a -> MockT m b) -> MockT m b
Monad,
      forall a. String -> MockT m a
forall (m :: * -> *).
Monad m -> (forall a. String -> m a) -> MonadFail m
forall {m :: * -> *}. MonadFail m => Monad (MockT m)
forall (m :: * -> *) a. MonadFail m => String -> MockT m a
fail :: forall a. String -> MockT m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> MockT m a
MonadFail,
      forall a. IO a -> MockT m a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
forall {m :: * -> *}. MonadIO m => Monad (MockT m)
forall (m :: * -> *) a. MonadIO m => IO a -> MockT m a
liftIO :: forall a. IO a -> MockT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> MockT m a
MonadIO,
      MonadState s,
      MonadWriter w,
      MonadRWS r w s,
      MonadError e,
      forall a b. ((a -> MockT m b) -> MockT m a) -> MockT m a
forall (m :: * -> *).
Monad m -> (forall a b. ((a -> m b) -> m a) -> m a) -> MonadCont m
forall {m :: * -> *}. MonadCont m => Monad (MockT m)
forall (m :: * -> *) a b.
MonadCont m =>
((a -> MockT m b) -> MockT m a) -> MockT m a
callCC :: forall a b. ((a -> MockT m b) -> MockT m a) -> MockT m a
$ccallCC :: forall (m :: * -> *) a b.
MonadCont m =>
((a -> MockT m b) -> MockT m a) -> MockT m a
MonadCont,
      MonadBase b,
      forall e a.
Exception e =>
MockT m a -> (e -> MockT m a) -> MockT m a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
forall {m :: * -> *}. MonadCatch m => MonadThrow (MockT m)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
MockT m a -> (e -> MockT m a) -> MockT m a
catch :: forall e a.
Exception e =>
MockT m a -> (e -> MockT m a) -> MockT m a
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
MockT m a -> (e -> MockT m a) -> MockT m a
MonadCatch,
      forall b.
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
forall a b c.
MockT m a
-> (a -> ExitCase b -> MockT m c)
-> (a -> MockT m b)
-> MockT m (b, c)
forall {m :: * -> *}. MonadMask m => MonadCatch (MockT m)
forall (m :: * -> *) b.
MonadMask m =>
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
forall (m :: * -> *) a b c.
MonadMask m =>
MockT m a
-> (a -> ExitCase b -> MockT m c)
-> (a -> MockT m b)
-> MockT m (b, c)
forall (m :: * -> *).
MonadCatch m
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b. ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
generalBracket :: forall a b c.
MockT m a
-> (a -> ExitCase b -> MockT m c)
-> (a -> MockT m b)
-> MockT m (b, c)
$cgeneralBracket :: forall (m :: * -> *) a b c.
MonadMask m =>
MockT m a
-> (a -> ExitCase b -> MockT m c)
-> (a -> MockT m b)
-> MockT m (b, c)
uninterruptibleMask :: forall b.
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
mask :: forall b.
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
$cmask :: forall (m :: * -> *) b.
MonadMask m =>
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
MonadMask,
      forall e a. Exception e => e -> MockT m a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
forall {m :: * -> *}. MonadThrow m => Monad (MockT m)
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> MockT m a
throwM :: forall e a. Exception e => e -> MockT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> MockT m a
MonadThrow
    )

instance MonadTrans MockT where
  lift :: forall (m :: * -> *) a. Monad m => m a -> MockT m a
lift = forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

-- Note: The 'MonadUnliftIO' instance is implemented manually because deriving
-- it causes compilation failure in GHC 8.6 and 8.8.  (See issue #23.)
instance MonadUnliftIO m => MonadUnliftIO (MockT m) where
  withRunInIO :: forall b. ((forall a. MockT m a -> IO a) -> IO b) -> MockT m b
withRunInIO (forall a. MockT m a -> IO a) -> IO b
inner = forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. ReaderT (MockState m) m a -> IO a
run -> (forall a. MockT m a -> IO a) -> IO b
inner (forall a. ReaderT (MockState m) m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MockT m a -> ReaderT (MockState m) m a
unMockT)

-- | Applies a function to the base monad of 'MockT'.
mapMockT :: (m a -> m b) -> MockT m a -> MockT m b
mapMockT :: forall (m :: * -> *) a b. (m a -> m b) -> MockT m a -> MockT m b
mapMockT m a -> m b
f = forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT m a -> m b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MockT m a -> ReaderT (MockState m) m a
unMockT

instance MonadReader r m => MonadReader r (MockT m) where
  ask :: MockT m r
ask = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall r (m :: * -> *). MonadReader r m => m r
ask
  local :: forall a. (r -> r) -> MockT m a -> MockT m a
local = forall (m :: * -> *) a b. (m a -> m b) -> MockT m a -> MockT m b
mapMockT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local
  reader :: forall a. (r -> a) -> MockT m a
reader = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
reader

-- | This type class defines a shared API between the 'MockT' and 'MockSetup'
-- monads.
class MockContext ctx where
  -- | Runs a 'MockSetup' action in this monad.
  fromMockSetup :: MonadIO m => MockSetup m a -> ctx m a

instance MockContext MockSetup where
  fromMockSetup :: forall (m :: * -> *) a. MonadIO m => MockSetup m a -> MockSetup m a
fromMockSetup = forall a. a -> a
id

instance MockContext MockT where
  fromMockSetup :: forall (m :: * -> *) a. MonadIO m => MockSetup m a -> MockT m a
fromMockSetup MockSetup m a
m = do
    MockState m
state <- forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT forall r (m :: * -> *). MonadReader r m => m r
ask
    forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically forall a b. (a -> b) -> a -> b
$ forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall (m :: * -> *) a.
MockSetup m a -> ReaderT (MockState m) STM a
unMockSetup MockSetup m a
m) MockState m
state

-- | Adds an expectation to the 'MockState' for the given 'ExpectSet',
-- interleaved with any existing expectations.
expectThisSet :: MonadIO m => ExpectSet (Step m) -> MockSetup m ()
expectThisSet :: forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet ExpectSet (Step m)
e = do
  forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
initClassesAsNeeded ExpectSet (Step m)
e
  MockState m
state <- forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup forall r (m :: * -> *). MonadReader r m => m r
ask
  forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> (a -> a) -> STM ()
modifyTVar (forall (m :: * -> *). MockState m -> TVar (ExpectSet (Step m))
mockExpectSet MockState m
state) (ExpectSet (Step m)
e forall step. ExpectSet step -> ExpectSet step -> ExpectSet step
`ExpectInterleave`)

-- | This instance allows you to add expectations from 'MockSetup' actions.
-- This is an unusual thing to do.  Consider using
-- 'Test.HMock.MockT.allowUnexpected', instead.
instance ExpectContext MockSetup where
  expect :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
expectable -> MockSetup m ()
expect expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
expectable -> ctx m ()
expect expectable
e
  expectN :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
Multiplicity -> expectable -> MockSetup m ()
expectN Multiplicity
mult expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
Multiplicity -> expectable -> ctx m ()
expectN Multiplicity
mult expectable
e
  expectAny :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
expectable -> MockSetup m ()
expectAny expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
expectable -> ctx m ()
expectAny expectable
e
  inSequence :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  inAnyOrder :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  anyOf :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  times :: forall (m :: * -> *).
MonadIO m =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockSetup m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> ctx m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es
  consecutiveTimes :: forall (m :: * -> *).
MonadIO m =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockSetup m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> ctx m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es

instance ExpectContext MockT where
  expect :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
expectable -> MockT m ()
expect expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
expectable -> ctx m ()
expect expectable
e
  expectN :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
Multiplicity -> expectable -> MockT m ()
expectN Multiplicity
mult expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
Multiplicity -> expectable -> ctx m ()
expectN Multiplicity
mult expectable
e
  expectAny :: forall (m :: * -> *) (cls :: (* -> *) -> Constraint)
       (name :: Symbol) r expectable.
(HasCallStack, MonadIO m, MockableMethod cls name m r,
 Expectable cls name m r expectable) =>
expectable -> MockT m ()
expectAny expectable
e =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *)
       (cls :: (* -> *) -> Constraint) (name :: Symbol) r expectable.
(ExpectContext ctx, HasCallStack, MonadIO m,
 MockableMethod cls name m r, Expectable cls name m r expectable) =>
expectable -> ctx m ()
expectAny expectable
e
  inSequence :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  inAnyOrder :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  anyOf :: forall (m :: * -> *).
MonadIO m =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  times :: forall (m :: * -> *).
MonadIO m =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockT m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> ctx m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es
  consecutiveTimes :: forall (m :: * -> *).
MonadIO m =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockT m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack forall a b. (a -> b) -> a -> b
$
      forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected forall a b. (a -> b) -> a -> b
$ forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> ctx m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es

-- | Reports a potential problem with the given 'Severity'.
reportFault :: (HasCallStack, MonadIO m) => Severity -> String -> MockT m ()
reportFault :: forall (m :: * -> *).
(HasCallStack, MonadIO m) =>
Severity -> String -> MockT m ()
reportFault Severity
severity String
msg = case Severity
severity of
  Severity
Ignore -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Severity
Warning -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr String
msg
  Severity
Error -> forall a. HasCallStack => String -> a
error String
msg