@@ -33,19 +33,20 @@ module Test.QuickCheck
3333
3434import Prelude
3535
36- import Control.Monad.Eff (Eff () )
37- import Control.Monad.Eff.Console (CONSOLE () , log )
36+ import Control.Monad.Eff (Eff )
37+ import Control.Monad.Eff.Console (CONSOLE , log )
3838import Control.Monad.Eff.Exception (EXCEPTION , throwException , error )
39- import Control.Monad.Eff.Random (RANDOM () )
40- import Control.Monad.Rec.Class (tailRecM )
41- import Data.Either ( Either (..))
39+ import Control.Monad.Eff.Random (RANDOM )
40+ import Control.Monad.Rec.Class (Step (..), tailRec )
41+
4242import Data.Foldable (for_ )
4343import Data.List (List )
4444import Data.Maybe (Maybe (..))
4545import Data.Maybe.First (First (..))
4646import Data.Monoid (mempty )
4747import Data.Tuple (Tuple (..))
4848import Data.Unfoldable (replicateA )
49+
4950import Test.QuickCheck.Arbitrary (class Arbitrary , arbitrary )
5051import Test.QuickCheck.Gen (Gen , evalGen , runGen )
5152import Test.QuickCheck.LCG (Seed , randomSeed )
@@ -64,31 +65,39 @@ quickCheck prop = quickCheck' 100 prop
6465-- | representing the number of tests which should be run.
6566quickCheck' :: forall eff prop . Testable prop => Int -> prop -> QC eff Unit
6667quickCheck' n prop = do
67- seed <- randomSeed
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
68+ seed <- randomSeed
69+ let result = tailRec loop { seed, index: 0 , successes: 0 , firstFailure: mempty }
70+ log $ show result. successes <> " /" <> show n <> " test(s) passed."
71+ for_ result. firstFailure \{ index, message } ->
72+ throwException $ error $ " Test " <> show (index + 1 ) <> " failed: \n " <> message
7273 where
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
74+ loop :: LoopState -> Step LoopState (LoopResult ())
75+ loop { seed, index, successes, firstFailure }
76+ | index == n = Done { successes, firstFailure }
77+ | otherwise =
7978 case runGen (test prop) { newSeed: seed, size: 10 } of
8079 Tuple Success s ->
81- pure (Left { seed: s.newSeed
82- , index: index + 1
83- , successes: successes + 1
84- , firstFailure
85- })
80+ Loop
81+ { seed: s.newSeed
82+ , index: index + 1
83+ , successes: successes + 1
84+ , firstFailure
85+ }
8686 Tuple (Failed message) s ->
87- pure (Left { seed: s.newSeed
88- , index: index + 1
89- , successes
90- , firstFailure: firstFailure <> First (Just { index, message })
91- })
87+ Loop
88+ { seed: s.newSeed
89+ , index: index + 1
90+ , successes
91+ , firstFailure: firstFailure <> First (Just { index, message })
92+ }
93+
94+ type LoopResult r =
95+ { successes :: Int
96+ , firstFailure :: First { index :: Int , message :: String }
97+ | r
98+ }
99+
100+ type LoopState = LoopResult (seed :: Seed , index :: Int )
92101
93102-- | Test a property, returning all test results as an array.
94103-- |
0 commit comments