@@ -35,22 +35,19 @@ import Prelude
3535
3636import Control.Monad.Eff (Eff ())
3737import Control.Monad.Eff.Console (CONSOLE (), log )
38- import Control.Monad.Eff.Exception (EXCEPTION () , throwException , error )
38+ import Control.Monad.Eff.Exception (EXCEPTION , throwException , error )
3939import Control.Monad.Eff.Random (RANDOM ())
40- import Control.Monad.Except.Trans (ExceptT , runExceptT , throwError )
41- import Control.Monad.State (State )
42- import Control.Monad.Trans (lift )
43- import Control.Monad.Writer.Trans (WriterT , runWriterT , tell )
4440import Control.Monad.Rec.Class (tailRecM )
45-
4641import Data.Either (Either (..))
47- import Data.List (List (..))
48- import Data.Monoid.Additive (Additive (..))
42+ import Data.Foldable (for_ )
43+ import Data.List (List )
44+ import Data.Maybe (Maybe (..))
45+ import Data.Maybe.First (First (..))
46+ import Data.Monoid (mempty )
4947import Data.Tuple (Tuple (..))
5048import Data.Unfoldable (replicateA )
51-
5249import Test.QuickCheck.Arbitrary (class Arbitrary , arbitrary )
53- import Test.QuickCheck.Gen (Gen , GenState , evalGen )
50+ import Test.QuickCheck.Gen (Gen , evalGen , runGen )
5451import Test.QuickCheck.LCG (Seed , randomSeed )
5552
5653-- | A type synonym which represents the effects used by the `quickCheck` function.
@@ -68,23 +65,30 @@ quickCheck prop = quickCheck' 100 prop
6865quickCheck' :: forall eff prop . Testable prop => Int -> prop -> QC eff Unit
6966quickCheck' n prop = do
7067 seed <- randomSeed
71- case evalGen (runExceptT (runWriterT ( tailRecM loop 0 ))) { newSeed: seed, size: 10 } of
72- Left err -> throwException $ error $ " Test " <> show (err.index + 1 ) <> " failed: \n " <> err.msg
73- Right ( Tuple _ ( Additive successes)) -> do
74- log $ show successes <> " / " <> show n <> " test(s) passed. "
68+ { successes, firstFailure } <- tailRecM loop { seed, index: 0 , successes: 0 , firstFailure: mempty }
69+ log $ show successes <> " / " <> show n <> " test(s) passed. "
70+ for_ firstFailure \{ index, message } ->
71+ throwException $ error $ " Test " <> show (index + 1 ) <> " failed: \n " <> message
7572 where
76- loop :: Int
77- -> WriterT (Additive Int )
78- (ExceptT { index :: Int , msg :: String }
79- (State GenState )) (Either Int Unit )
80- loop index | index == n = pure (Right unit)
81- loop index = do
82- result <- lift (lift (test prop))
83- case result of
84- Success -> do
85- tell (Additive 1 )
86- pure (Left (index + 1 ))
87- Failed msg -> throwError { index, msg }
73+ loop :: { seed :: Seed , index :: Int , successes :: Int , firstFailure :: First { index :: Int , message :: String } }
74+ -> QC eff (Either { seed :: Seed , index :: Int , successes :: Int , firstFailure :: First { index :: Int , message :: String } }
75+ { successes :: Int , firstFailure :: First { index :: Int , message :: String } } )
76+ loop { seed, index, successes, firstFailure }
77+ | index == n = pure (Right { successes, firstFailure })
78+ | otherwise = do
79+ case runGen (test prop) { newSeed: seed, size: 10 } of
80+ Tuple Success s ->
81+ pure (Left { seed: s.newSeed
82+ , index: index + 1
83+ , successes: successes + 1
84+ , firstFailure
85+ })
86+ Tuple (Failed message) s ->
87+ pure (Left { seed: s.newSeed
88+ , index: index + 1
89+ , successes
90+ , firstFailure: firstFailure <> First (Just { index, message })
91+ })
8892
8993-- | Test a property, returning all test results as an array.
9094-- |
0 commit comments