{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Eta reduce" #-} module Fail ( tests , gen0 , test ) where import qualified Control.Carrier.Fail.Either as FailC import Control.Effect.Fail as Fail import Gen import Hedgehog.Range as Range import qualified Monad import qualified MonadFix import Test.Tasty import Test.Tasty.Hedgehog tests :: TestTree tests = testGroup "Fail" [ testGroup "FailC" $ [ testMonad , testMonadFix , testFail ] >>= ($ runL FailC.runFail) ] where testMonad run = Monad.test (m (gen0 e) (\ _ _ -> [])) a b c initial run testMonadFix run = MonadFix.test (m (gen0 e) (\ _ _ -> [])) a b initial run testFail run = Fail.test e (m (gen0 e) (\ _ _ -> [])) a b initial run initial = identity <*> unit e = string (Range.linear 0 50) unicode gen0 :: MonadFail m => GenTerm String -> GenTerm a -> [GenTerm (m a)] gen0 e _ = [ label "fail" Fail.fail <*> e ] test :: forall m a b f . (MonadFail m, Arg a, Eq b, Show a, Show b, Vary a, Functor f) => GenTerm String -> GenM m -> GenTerm a -> GenTerm b -> GenTerm (f ()) -> Run f (Either String) m -> [TestTree] test msg m _ b i (Run runFail) = [ testProperty "fail annihilates >>=" . forall (i :. msg :. fn @a (m b) :. Nil) $ \ i s k -> runFail ((Fail.fail s >>= k) <$ i) === runFail (Fail.fail s <$ i) ]