{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE StandaloneDeriving #-} module Hedgehog.Extras.Test.MonadAssertion ( MonadAssertion(..) ) where import Control.Monad import Control.Monad.Trans.Class import Data.Either import Data.Function import Data.Monoid (mempty) import qualified Control.Monad.Trans.Except as E import qualified Control.Monad.Trans.Resource as IO import qualified Control.Monad.Trans.Resource.Internal as IO import qualified Hedgehog as H import qualified Hedgehog.Internal.Property as H class Monad m => MonadAssertion m where throwAssertion :: H.Failure -> m a catchAssertion :: m a -> (H.Failure -> m a) -> m a instance Monad m => MonadAssertion (H.TestT m) where throwAssertion :: forall a. Failure -> TestT m a throwAssertion Failure f = forall (m :: * -> *) a. MonadTest m => Test a -> m a H.liftTest forall a b. (a -> b) -> a -> b $ forall a. (Either Failure a, Journal) -> Test a H.mkTest (forall a b. a -> Either a b Left Failure f, forall a. Monoid a => a mempty) catchAssertion :: forall a. TestT m a -> (Failure -> TestT m a) -> TestT m a catchAssertion TestT m a g Failure -> TestT m a h = forall (m :: * -> *) a. ExceptT Failure (WriterT Journal m) a -> TestT m a H.TestT forall a b. (a -> b) -> a -> b $ forall (m :: * -> *) e a e'. Monad m => ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a E.catchE (forall (m :: * -> *) a. TestT m a -> ExceptT Failure (WriterT Journal m) a H.unTest TestT m a g) (forall (m :: * -> *) a. TestT m a -> ExceptT Failure (WriterT Journal m) a H.unTest forall b c a. (b -> c) -> (a -> b) -> a -> c . Failure -> TestT m a h) instance MonadAssertion m => MonadAssertion (IO.ResourceT m) where throwAssertion :: forall a. Failure -> ResourceT m a throwAssertion = 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 (m :: * -> *) a. MonadAssertion m => Failure -> m a throwAssertion catchAssertion :: forall a. ResourceT m a -> (Failure -> ResourceT m a) -> ResourceT m a catchAssertion ResourceT m a r Failure -> ResourceT m a h = forall (m :: * -> *) a. (IORef ReleaseMap -> m a) -> ResourceT m a IO.ResourceT forall a b. (a -> b) -> a -> b $ \IORef ReleaseMap i -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a IO.unResourceT ResourceT m a r IORef ReleaseMap i forall (m :: * -> *) a. MonadAssertion m => m a -> (Failure -> m a) -> m a `catchAssertion` \Failure e -> forall (m :: * -> *) a. ResourceT m a -> IORef ReleaseMap -> m a IO.unResourceT (Failure -> ResourceT m a h Failure e) IORef ReleaseMap i deriving instance Monad m => MonadAssertion (H.PropertyT m)