{-# 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
  { MockState m -> TVar (ExpectSet (Step m))
mockExpectSet :: TVar (ExpectSet (Step m)),
    MockState m -> TVar [Step m]
mockDefaults :: TVar [Step m],
    MockState m -> TVar [Step m]
mockAllowUnexpected :: TVar [Step m],
    MockState m -> TVar [Step m]
mockSideEffects :: TVar [Step m],
    MockState m -> TVar Severity
mockAmbiguitySeverity :: TVar Severity,
    MockState m -> TVar Severity
mockUnexpectedSeverity :: TVar Severity,
    MockState m -> TVar Severity
mockUninterestingSeverity :: TVar Severity,
    MockState m -> TVar Severity
mockUnmetSeverity :: TVar Severity,
    MockState m -> TVar (Set TypeRep)
mockClasses :: TVar (Set TypeRep),
    MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods :: TVar (Set (TypeRep, String)),
    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 :: Maybe (MockState m) -> m (MockState m)
initMockState Maybe (MockState m)
parent =
  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
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
    (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)
-> m (TVar (ExpectSet (Step m)))
-> 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)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExpectSet (Step m) -> m (TVar (ExpectSet (Step m)))
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO ExpectSet (Step m)
forall step. ExpectSet step
ExpectNothing
    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)
-> m (TVar [Step m])
-> 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)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Step m] -> m (TVar [Step m])
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    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)
-> m (TVar [Step m])
-> m (TVar [Step m]
      -> TVar Severity
      -> TVar Severity
      -> TVar Severity
      -> TVar Severity
      -> TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Step m] -> m (TVar [Step m])
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    m (TVar [Step m]
   -> TVar Severity
   -> TVar Severity
   -> TVar Severity
   -> TVar Severity
   -> TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar [Step m])
-> m (TVar Severity
      -> TVar Severity
      -> TVar Severity
      -> TVar Severity
      -> TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [Step m] -> m (TVar [Step m])
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO []
    m (TVar Severity
   -> TVar Severity
   -> TVar Severity
   -> TVar Severity
   -> TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar Severity)
-> m (TVar Severity
      -> TVar Severity
      -> TVar Severity
      -> TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar Severity)
-> (MockState m -> m (TVar Severity))
-> m (Maybe (MockState m))
-> m (TVar Severity)
forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Ignore)
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO (Severity -> m (TVar Severity))
-> (MockState m -> m Severity) -> MockState m -> m (TVar Severity)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< TVar Severity -> m Severity
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar Severity -> m Severity)
-> (MockState m -> TVar Severity) -> MockState m -> m Severity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar Severity
forall (m :: * -> *). MockState m -> TVar Severity
mockAmbiguitySeverity)
      (Maybe (MockState m) -> m (Maybe (MockState m))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    m (TVar Severity
   -> TVar Severity
   -> TVar Severity
   -> TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar Severity)
-> m (TVar Severity
      -> TVar Severity
      -> TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar Severity)
-> (MockState m -> m (TVar Severity))
-> m (Maybe (MockState m))
-> m (TVar Severity)
forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO (Severity -> m (TVar Severity))
-> (MockState m -> m Severity) -> MockState m -> m (TVar Severity)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< TVar Severity -> m Severity
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar Severity -> m Severity)
-> (MockState m -> TVar Severity) -> MockState m -> m Severity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar Severity
forall (m :: * -> *). MockState m -> TVar Severity
mockUnexpectedSeverity)
      (Maybe (MockState m) -> m (Maybe (MockState m))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    m (TVar Severity
   -> TVar Severity
   -> TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar Severity)
-> m (TVar Severity
      -> TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar Severity)
-> (MockState m -> m (TVar Severity))
-> m (Maybe (MockState m))
-> m (TVar Severity)
forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO (Severity -> m (TVar Severity))
-> (MockState m -> m Severity) -> MockState m -> m (TVar Severity)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< TVar Severity -> m Severity
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar Severity -> m Severity)
-> (MockState m -> TVar Severity) -> MockState m -> m Severity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar Severity
forall (m :: * -> *). MockState m -> TVar Severity
mockUninterestingSeverity)
      (Maybe (MockState m) -> m (Maybe (MockState m))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    m (TVar Severity
   -> TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar Severity)
-> m (TVar (Set TypeRep)
      -> TVar (Set (TypeRep, String))
      -> Maybe (MockState m)
      -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar Severity)
-> (MockState m -> m (TVar Severity))
-> m (Maybe (MockState m))
-> m (TVar Severity)
forall (m :: * -> *) b a.
Monad m =>
m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Severity
Error)
      (Severity -> m (TVar Severity)
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO (Severity -> m (TVar Severity))
-> (MockState m -> m Severity) -> MockState m -> m (TVar Severity)
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< TVar Severity -> m Severity
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO (TVar Severity -> m Severity)
-> (MockState m -> TVar Severity) -> MockState m -> m Severity
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar Severity
forall (m :: * -> *). MockState m -> TVar Severity
mockUnmetSeverity)
      (Maybe (MockState m) -> m (Maybe (MockState m))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (MockState m)
parent)
    m (TVar (Set TypeRep)
   -> TVar (Set (TypeRep, String))
   -> Maybe (MockState m)
   -> MockState m)
-> m (TVar (Set TypeRep))
-> m (TVar (Set (TypeRep, String))
      -> Maybe (MockState m) -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar (Set TypeRep))
-> (MockState m -> m (TVar (Set TypeRep)))
-> Maybe (MockState m)
-> m (TVar (Set TypeRep))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Set TypeRep -> m (TVar (Set TypeRep))
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Set TypeRep
forall a. Set a
Set.empty) (TVar (Set TypeRep) -> m (TVar (Set TypeRep))
forall (m :: * -> *) a. Monad m => a -> m a
return (TVar (Set TypeRep) -> m (TVar (Set TypeRep)))
-> (MockState m -> TVar (Set TypeRep))
-> MockState m
-> m (TVar (Set TypeRep))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar (Set TypeRep)
forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses) Maybe (MockState m)
parent
    m (TVar (Set (TypeRep, String))
   -> Maybe (MockState m) -> MockState m)
-> m (TVar (Set (TypeRep, String)))
-> m (Maybe (MockState m) -> MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m (TVar (Set (TypeRep, String)))
-> (MockState m -> m (TVar (Set (TypeRep, String))))
-> Maybe (MockState m)
-> m (TVar (Set (TypeRep, String)))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Set (TypeRep, String) -> m (TVar (Set (TypeRep, String)))
forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
newTVarIO Set (TypeRep, String)
forall a. Set a
Set.empty) (TVar (Set (TypeRep, String)) -> m (TVar (Set (TypeRep, String)))
forall (m :: * -> *) a. Monad m => a -> m a
return (TVar (Set (TypeRep, String)) -> m (TVar (Set (TypeRep, String))))
-> (MockState m -> TVar (Set (TypeRep, String)))
-> MockState m
-> m (TVar (Set (TypeRep, String)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> TVar (Set (TypeRep, String))
forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods) Maybe (MockState m)
parent
    m (Maybe (MockState m) -> MockState m)
-> m (Maybe (MockState m)) -> m (MockState m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (MockState m) -> m (Maybe (MockState m))
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 :: MockState m -> [MockState m]
allStates MockState m
s
  | Just MockState m
s' <- MockState m -> Maybe (MockState m)
forall (m :: * -> *). MockState m -> Maybe (MockState m)
mockParent MockState m
s = MockState m
s MockState m -> [MockState m] -> [MockState m]
forall a. a -> [a] -> [a]
: MockState m -> [MockState m]
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 :: MockState m -> MockState m
rootState = [MockState m] -> MockState m
forall a. [a] -> a
last ([MockState m] -> MockState m)
-> (MockState m -> [MockState m]) -> MockState m -> MockState m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockState m -> [MockState m]
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 :: {MockSetup m a -> ReaderT (MockState m) STM a
unMockSetup :: ReaderT (MockState m) STM a} -> MockSetup m a
  deriving (a -> MockSetup m b -> MockSetup m a
(a -> b) -> MockSetup m a -> MockSetup m b
(forall a b. (a -> b) -> MockSetup m a -> MockSetup m b)
-> (forall a b. a -> MockSetup m b -> MockSetup m a)
-> Functor (MockSetup m)
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
<$ :: a -> MockSetup m b -> MockSetup m a
$c<$ :: forall (m :: * -> *) a b. a -> MockSetup m b -> MockSetup m a
fmap :: (a -> b) -> MockSetup m a -> MockSetup m b
$cfmap :: forall (m :: * -> *) a b.
(a -> b) -> MockSetup m a -> MockSetup m b
Functor, Functor (MockSetup m)
a -> MockSetup m a
Functor (MockSetup m)
-> (forall a. a -> MockSetup m a)
-> (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 a b. MockSetup m a -> MockSetup m b -> MockSetup m b)
-> (forall a b. MockSetup m a -> MockSetup m b -> MockSetup m a)
-> Applicative (MockSetup m)
MockSetup m a -> MockSetup m b -> MockSetup m b
MockSetup m a -> MockSetup m b -> MockSetup m a
MockSetup m (a -> b) -> MockSetup m a -> MockSetup m b
(a -> b -> c) -> MockSetup m a -> MockSetup m b -> MockSetup m c
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
<* :: MockSetup m a -> MockSetup m b -> MockSetup m a
$c<* :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m a
*> :: MockSetup m a -> MockSetup m b -> MockSetup m b
$c*> :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m b
liftA2 :: (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
<*> :: 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 :: a -> MockSetup m a
$cpure :: forall (m :: * -> *) a. a -> MockSetup m a
$cp1Applicative :: forall (m :: * -> *). Functor (MockSetup m)
Applicative, Applicative (MockSetup m)
a -> MockSetup m a
Applicative (MockSetup m)
-> (forall a b.
    MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b)
-> (forall a b. MockSetup m a -> MockSetup m b -> MockSetup m b)
-> (forall a. a -> MockSetup m a)
-> Monad (MockSetup m)
MockSetup m a -> (a -> MockSetup m b) -> MockSetup m b
MockSetup m a -> MockSetup m b -> MockSetup m b
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 :: a -> MockSetup m a
$creturn :: forall (m :: * -> *) a. a -> MockSetup m a
>> :: MockSetup m a -> MockSetup m b -> MockSetup m b
$c>> :: forall (m :: * -> *) a b.
MockSetup m a -> MockSetup m b -> MockSetup m 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
$cp1Monad :: forall (m :: * -> *). Applicative (MockSetup m)
Monad)

-- | Runs a setup action with the root state, rather than the current one.
runInRootState :: MockSetup m a -> MockSetup m a
runInRootState :: MockSetup m a -> MockSetup m a
runInRootState = ReaderT (MockState m) STM a -> MockSetup m a
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup (ReaderT (MockState m) STM a -> MockSetup m a)
-> (MockSetup m a -> ReaderT (MockState m) STM a)
-> MockSetup m a
-> MockSetup m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (MockState m -> MockState m)
-> ReaderT (MockState m) STM a -> ReaderT (MockState m) STM a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local MockState m -> MockState m
forall (m :: * -> *). MockState m -> MockState m
rootState (ReaderT (MockState m) STM a -> ReaderT (MockState m) STM a)
-> (MockSetup m a -> ReaderT (MockState m) STM a)
-> MockSetup m a
-> ReaderT (MockState m) STM a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockSetup m a -> ReaderT (MockState m) STM a
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 :: STM a -> MockSetup m a
mockSetupSTM STM a
m = ReaderT (MockState m) STM a -> MockSetup m a
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup (STM a -> ReaderT (MockState m) STM a
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 :: proxy cls -> MockSetup m ()
initClassIfNeeded proxy cls
proxy = MockSetup m () -> MockSetup m ()
forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState (MockSetup m () -> MockSetup m ())
-> MockSetup m () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- ReaderT (MockState m) STM (MockState m)
-> MockSetup m (MockState m)
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup ReaderT (MockState m) STM (MockState m)
forall r (m :: * -> *). MonadReader r m => m r
ask
  Set TypeRep
classes <- STM (Set TypeRep) -> MockSetup m (Set TypeRep)
forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM (STM (Set TypeRep) -> MockSetup m (Set TypeRep))
-> STM (Set TypeRep) -> MockSetup m (Set TypeRep)
forall a b. (a -> b) -> a -> b
$ TVar (Set TypeRep) -> STM (Set TypeRep)
forall a. TVar a -> STM a
readTVar (MockState m -> TVar (Set TypeRep)
forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses MockState m
state)
  Bool -> MockSetup m () -> MockSetup m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member TypeRep
t Set TypeRep
classes) (MockSetup m () -> MockSetup m ())
-> MockSetup m () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ do
    STM () -> MockSetup m ()
forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM (STM () -> MockSetup m ()) -> STM () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ TVar (Set TypeRep) -> (Set TypeRep -> Set TypeRep) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar (MockState m -> TVar (Set TypeRep)
forall (m :: * -> *). MockState m -> TVar (Set TypeRep)
mockClasses MockState m
state) (TypeRep -> Set TypeRep -> Set TypeRep
forall a. Ord a => a -> Set a -> Set a
Set.insert TypeRep
t)
    Proxy cls -> MockSetup m ()
forall (cls :: (* -> *) -> Constraint) (m :: * -> *)
       (proxy :: ((* -> *) -> Constraint) -> *).
(Mockable cls, MonadIO m, Typeable m) =>
proxy cls -> MockSetup m ()
setupMockable (Proxy cls
forall k (t :: k). Proxy t
Proxy :: Proxy cls)
  where
    t :: TypeRep
t = proxy cls -> TypeRep
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 :: proxy1 cls -> proxy2 name -> MockSetup m ()
markInteresting proxy1 cls
proxyCls proxy2 name
proxyName = MockSetup m () -> MockSetup m ()
forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState (MockSetup m () -> MockSetup m ())
-> MockSetup m () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- ReaderT (MockState m) STM (MockState m)
-> MockSetup m (MockState m)
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup ReaderT (MockState m) STM (MockState m)
forall r (m :: * -> *). MonadReader r m => m r
ask
  STM () -> MockSetup m ()
forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM (STM () -> MockSetup m ()) -> STM () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$
    TVar (Set (TypeRep, String))
-> (Set (TypeRep, String) -> Set (TypeRep, String)) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar
      (MockState m -> TVar (Set (TypeRep, String))
forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods MockState m
state)
      ((TypeRep, String) -> Set (TypeRep, String) -> Set (TypeRep, String)
forall a. Ord a => a -> Set a -> Set a
Set.insert (proxy1 cls -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep proxy1 cls
proxyCls, proxy2 name -> String
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 :: proxy1 cls -> proxy2 name -> MockSetup m Bool
isInteresting proxy1 cls
proxyCls proxy2 name
proxyName = MockSetup m Bool -> MockSetup m Bool
forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState (MockSetup m Bool -> MockSetup m Bool)
-> MockSetup m Bool -> MockSetup m Bool
forall a b. (a -> b) -> a -> b
$ do
  MockState m
state <- ReaderT (MockState m) STM (MockState m)
-> MockSetup m (MockState m)
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup ReaderT (MockState m) STM (MockState m)
forall r (m :: * -> *). MonadReader r m => m r
ask
  Set (TypeRep, String)
interesting <- STM (Set (TypeRep, String)) -> MockSetup m (Set (TypeRep, String))
forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM (STM (Set (TypeRep, String))
 -> MockSetup m (Set (TypeRep, String)))
-> STM (Set (TypeRep, String))
-> MockSetup m (Set (TypeRep, String))
forall a b. (a -> b) -> a -> b
$ TVar (Set (TypeRep, String)) -> STM (Set (TypeRep, String))
forall a. TVar a -> STM a
readTVar (MockState m -> TVar (Set (TypeRep, String))
forall (m :: * -> *). MockState m -> TVar (Set (TypeRep, String))
mockInterestingMethods MockState m
state)
  Bool -> MockSetup m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return ((proxy1 cls -> TypeRep
forall k (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep proxy1 cls
proxyCls, proxy2 name -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal proxy2 name
proxyName) (TypeRep, String) -> Set (TypeRep, String) -> Bool
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 :: ExpectSet (Step m) -> MockSetup m ()
initClassesAsNeeded ExpectSet (Step m)
es = MockSetup m () -> MockSetup m ()
forall (m :: * -> *) a. MockSetup m a -> MockSetup m a
runInRootState (MockSetup m () -> MockSetup m ())
-> MockSetup m () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$
  [Step m] -> (Step m -> MockSetup m ()) -> MockSetup m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (ExpectSet (Step m) -> [Step m]
forall step. ExpectSet step -> [step]
getSteps ExpectSet (Step m)
es) ((Step m -> MockSetup m ()) -> MockSetup m ())
-> (Step m -> MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$
    \(Step (Located (SingleRule cls name m r)
_ :: Located (SingleRule cls name m r))) -> do
      Proxy cls -> MockSetup m ()
forall (cls :: (* -> *) -> Constraint) (m :: * -> *)
       (proxy :: ((* -> *) -> Constraint) -> *).
(Mockable cls, Typeable m, MonadIO m) =>
proxy cls -> MockSetup m ()
initClassIfNeeded (Proxy cls
forall k (t :: k). Proxy t
Proxy :: Proxy cls)
      Proxy cls -> Proxy name -> MockSetup m ()
forall (cls :: (* -> *) -> Constraint) (name :: Symbol)
       (m :: * -> *) (proxy1 :: ((* -> *) -> Constraint) -> *)
       (proxy2 :: Symbol -> *).
(Typeable cls, KnownSymbol name) =>
proxy1 cls -> proxy2 name -> MockSetup m ()
markInteresting (Proxy cls
forall k (t :: k). Proxy t
Proxy :: Proxy cls) (Proxy name
forall k (t :: k). Proxy t
Proxy :: Proxy name)

-- | Monad transformer for running mocks.
newtype MockT m a where
  MockT :: {MockT m a -> ReaderT (MockState m) m a
unMockT :: ReaderT (MockState m) m a} -> MockT m a
  deriving
    ( a -> MockT m b -> MockT m a
(a -> b) -> MockT m a -> MockT m b
(forall a b. (a -> b) -> MockT m a -> MockT m b)
-> (forall a b. a -> MockT m b -> MockT m a) -> Functor (MockT m)
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
<$ :: a -> MockT m b -> MockT m a
$c<$ :: forall (m :: * -> *) a b. Functor m => a -> MockT m b -> MockT m a
fmap :: (a -> b) -> MockT m a -> MockT m b
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> MockT m a -> MockT m b
Functor,
      Functor (MockT m)
a -> MockT m a
Functor (MockT m)
-> (forall a. a -> MockT m a)
-> (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 a b. MockT m a -> MockT m b -> MockT m b)
-> (forall a b. MockT m a -> MockT m b -> MockT m a)
-> Applicative (MockT m)
MockT m a -> MockT m b -> MockT m b
MockT m a -> MockT m b -> MockT m a
MockT m (a -> b) -> MockT m a -> MockT m b
(a -> b -> c) -> MockT m a -> MockT m b -> MockT m c
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
<* :: 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
*> :: 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 :: (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
<*> :: 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 :: a -> MockT m a
$cpure :: forall (m :: * -> *) a. Applicative m => a -> MockT m a
$cp1Applicative :: forall (m :: * -> *). Applicative m => Functor (MockT m)
Applicative,
      Applicative (MockT m)
a -> MockT m a
Applicative (MockT m)
-> (forall a b. MockT m a -> (a -> MockT m b) -> MockT m b)
-> (forall a b. MockT m a -> MockT m b -> MockT m b)
-> (forall a. a -> MockT m a)
-> Monad (MockT m)
MockT m a -> (a -> MockT m b) -> MockT m b
MockT m a -> MockT m b -> MockT m b
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 :: a -> MockT m a
$creturn :: forall (m :: * -> *) a. Monad m => a -> MockT m a
>> :: 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
>>= :: 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
$cp1Monad :: forall (m :: * -> *). Monad m => Applicative (MockT m)
Monad,
      Monad (MockT m)
Monad (MockT m)
-> (forall a. String -> MockT m a) -> MonadFail (MockT m)
String -> MockT m a
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 :: String -> MockT m a
$cfail :: forall (m :: * -> *) a. MonadFail m => String -> MockT m a
$cp1MonadFail :: forall (m :: * -> *). MonadFail m => Monad (MockT m)
MonadFail,
      Monad (MockT m)
Monad (MockT m)
-> (forall a. IO a -> MockT m a) -> MonadIO (MockT m)
IO a -> MockT m a
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 :: IO a -> MockT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> MockT m a
$cp1MonadIO :: forall (m :: * -> *). MonadIO m => Monad (MockT m)
MonadIO,
      MonadState s,
      MonadWriter w,
      MonadRWS r w s,
      MonadError e,
      Monad (MockT m)
Monad (MockT m)
-> (forall a b. ((a -> MockT m b) -> MockT m a) -> MockT m a)
-> MonadCont (MockT m)
((a -> MockT m b) -> MockT m a) -> MockT m a
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 :: ((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
$cp1MonadCont :: forall (m :: * -> *). MonadCont m => Monad (MockT m)
MonadCont,
      MonadBase b,
      MonadThrow (MockT m)
MonadThrow (MockT m)
-> (forall e a.
    Exception e =>
    MockT m a -> (e -> MockT m a) -> MockT m a)
-> MonadCatch (MockT m)
MockT m a -> (e -> MockT m a) -> MockT m a
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 :: 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
$cp1MonadCatch :: forall (m :: * -> *). MonadCatch m => MonadThrow (MockT m)
MonadCatch,
      MonadCatch (MockT m)
MonadCatch (MockT m)
-> (forall b.
    ((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b)
-> (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))
-> MonadMask (MockT m)
MockT m a
-> (a -> ExitCase b -> MockT m c)
-> (a -> MockT m b)
-> MockT m (b, c)
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
((forall a. MockT m a -> MockT m a) -> MockT m b) -> MockT m b
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 :: * -> *).
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
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)
generalBracket :: 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 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 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
$cp1MonadMask :: forall (m :: * -> *). MonadMask m => MonadCatch (MockT m)
MonadMask,
      Monad (MockT m)
e -> MockT m a
Monad (MockT m)
-> (forall e a. Exception e => e -> MockT m a)
-> MonadThrow (MockT m)
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 :: e -> MockT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
e -> MockT m a
$cp1MonadThrow :: forall (m :: * -> *). MonadThrow m => Monad (MockT m)
MonadThrow
    )

instance MonadTrans MockT where
  lift :: m a -> MockT m a
lift = ReaderT (MockState m) m a -> MockT m a
forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT (ReaderT (MockState m) m a -> MockT m a)
-> (m a -> ReaderT (MockState m) m a) -> m a -> MockT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> ReaderT (MockState m) m a
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 a. MockT m a -> IO a) -> IO b) -> MockT m b
withRunInIO (forall a. MockT m a -> IO a) -> IO b
inner = ReaderT (MockState m) m b -> MockT m b
forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT (ReaderT (MockState m) m b -> MockT m b)
-> ReaderT (MockState m) m b -> MockT m b
forall a b. (a -> b) -> a -> b
$ ((forall a. ReaderT (MockState m) m a -> IO a) -> IO b)
-> ReaderT (MockState m) m b
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. ReaderT (MockState m) m a -> IO a) -> IO b)
 -> ReaderT (MockState m) m b)
-> ((forall a. ReaderT (MockState m) m a -> IO a) -> IO b)
-> ReaderT (MockState m) m b
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 (ReaderT (MockState m) m a -> IO a
forall a. ReaderT (MockState m) m a -> IO a
run (ReaderT (MockState m) m a -> IO a)
-> (MockT m a -> ReaderT (MockState m) m a) -> MockT m a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockT m a -> ReaderT (MockState m) m a
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 :: (m a -> m b) -> MockT m a -> MockT m b
mapMockT m a -> m b
f = ReaderT (MockState m) m b -> MockT m b
forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT (ReaderT (MockState m) m b -> MockT m b)
-> (MockT m a -> ReaderT (MockState m) m b)
-> MockT m a
-> MockT m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (m a -> m b)
-> ReaderT (MockState m) m a -> ReaderT (MockState m) m b
forall (m :: * -> *) a (n :: * -> *) b r.
(m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT m a -> m b
f (ReaderT (MockState m) m a -> ReaderT (MockState m) m b)
-> (MockT m a -> ReaderT (MockState m) m a)
-> MockT m a
-> ReaderT (MockState m) m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockT m a -> ReaderT (MockState m) m a
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 = m r -> MockT m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m r
forall r (m :: * -> *). MonadReader r m => m r
ask
  local :: (r -> r) -> MockT m a -> MockT m a
local = (m a -> m a) -> MockT m a -> MockT m a
forall (m :: * -> *) a b. (m a -> m b) -> MockT m a -> MockT m b
mapMockT ((m a -> m a) -> MockT m a -> MockT m a)
-> ((r -> r) -> m a -> m a) -> (r -> r) -> MockT m a -> MockT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> r) -> m a -> m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local
  reader :: (r -> a) -> MockT m a
reader = m a -> MockT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> MockT m a) -> ((r -> a) -> m a) -> (r -> a) -> MockT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> a) -> m a
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 :: MockSetup m a -> MockSetup m a
fromMockSetup = MockSetup m a -> MockSetup m a
forall a. a -> a
id

instance MockContext MockT where
  fromMockSetup :: MockSetup m a -> MockT m a
fromMockSetup MockSetup m a
m = do
    MockState m
state <- ReaderT (MockState m) m (MockState m) -> MockT m (MockState m)
forall (m :: * -> *) a. ReaderT (MockState m) m a -> MockT m a
MockT ReaderT (MockState m) m (MockState m)
forall r (m :: * -> *). MonadReader r m => m r
ask
    STM a -> MockT m a
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM a -> MockT m a) -> STM a -> MockT m a
forall a b. (a -> b) -> a -> b
$ ReaderT (MockState m) STM a -> MockState m -> STM a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (MockSetup m a -> ReaderT (MockState m) STM a
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 :: ExpectSet (Step m) -> MockSetup m ()
expectThisSet ExpectSet (Step m)
e = do
  ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
initClassesAsNeeded ExpectSet (Step m)
e
  MockState m
state <- ReaderT (MockState m) STM (MockState m)
-> MockSetup m (MockState m)
forall (m :: * -> *) a.
ReaderT (MockState m) STM a -> MockSetup m a
MockSetup ReaderT (MockState m) STM (MockState m)
forall r (m :: * -> *). MonadReader r m => m r
ask
  STM () -> MockSetup m ()
forall a (m :: * -> *). STM a -> MockSetup m a
mockSetupSTM (STM () -> MockSetup m ()) -> STM () -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ TVar (ExpectSet (Step m))
-> (ExpectSet (Step m) -> ExpectSet (Step m)) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
modifyTVar (MockState m -> TVar (ExpectSet (Step m))
forall (m :: * -> *). MockState m -> TVar (ExpectSet (Step m))
mockExpectSet MockState m
state) (ExpectSet (Step m)
e ExpectSet (Step m) -> ExpectSet (Step m) -> ExpectSet (Step m)
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 :: expectable -> MockSetup m ()
expect expectable
e =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ expectable -> Expected m ()
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 :: Multiplicity -> expectable -> MockSetup m ()
expectN Multiplicity
mult expectable
e =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity -> expectable -> Expected m ()
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 :: expectable -> MockSetup m ()
expectAny expectable
e =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ expectable -> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockSetup m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  times :: Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockSetup m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> Expected m ()
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 :: Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockSetup m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockSetup m ()) -> MockSetup m ())
-> (HasCallStack => MockSetup m ()) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$
      ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> Expected m ()
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 :: expectable -> MockT m ()
expect expectable
e =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ expectable -> Expected m ()
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 :: Multiplicity -> expectable -> MockT m ()
expectN Multiplicity
mult expectable
e =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity -> expectable -> Expected m ()
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 :: expectable -> MockT m ()
expectAny expectable
e =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ expectable -> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
inSequence forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
inAnyOrder forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
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 (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> MockT m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ (forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> Expected m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *).
(ExpectContext ctx, MonadIO m) =>
(forall (ctx' :: (* -> *) -> * -> *).
 ExpectContext ctx' =>
 [ctx' m ()])
-> ctx m ()
anyOf forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
[ctx' m ()]
es
  times :: Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockT m ()
times Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> Expected m ()
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 :: Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> MockT m ()
consecutiveTimes Multiplicity
mult forall (ctx' :: (* -> *) -> * -> *).
ExpectContext ctx' =>
ctx' m ()
es =
    (HasCallStack => MockT m ()) -> MockT m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => MockT m ()) -> MockT m ())
-> (HasCallStack => MockT m ()) -> MockT m ()
forall a b. (a -> b) -> a -> b
$
      MockSetup m () -> MockT m ()
forall (ctx :: (* -> *) -> * -> *) (m :: * -> *) a.
(MockContext ctx, MonadIO m) =>
MockSetup m a -> ctx m a
fromMockSetup (MockSetup m () -> MockT m ()) -> MockSetup m () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ ExpectSet (Step m) -> MockSetup m ()
forall (m :: * -> *).
MonadIO m =>
ExpectSet (Step m) -> MockSetup m ()
expectThisSet (ExpectSet (Step m) -> MockSetup m ())
-> ExpectSet (Step m) -> MockSetup m ()
forall a b. (a -> b) -> a -> b
$ Expected m () -> ExpectSet (Step m)
forall (m :: * -> *) a. Expected m a -> ExpectSet (Step m)
unwrapExpected (Expected m () -> ExpectSet (Step m))
-> Expected m () -> ExpectSet (Step m)
forall a b. (a -> b) -> a -> b
$ Multiplicity
-> (forall (ctx' :: (* -> *) -> * -> *).
    ExpectContext ctx' =>
    ctx' m ())
-> Expected m ()
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 :: Severity -> String -> MockT m ()
reportFault Severity
severity String
msg = case Severity
severity of
  Severity
Ignore -> () -> MockT m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Severity
Warning -> IO () -> MockT m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> MockT m ()) -> IO () -> MockT m ()
forall a b. (a -> b) -> a -> b
$ Handle -> String -> IO ()
hPutStrLn Handle
stderr String
msg
  Severity
Error -> String -> MockT m ()
forall a. HasCallStack => String -> a
error String
msg