Skip to content

Commit 6289a80

Browse files
authored
Merge pull request #100 from purescript/better-pure-reporting
Better reporting abilities for pure quickCheck runs
2 parents c703061 + 270f8fa commit 6289a80

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

src/Test/QuickCheck.purs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ module Test.QuickCheck
2323
, quickCheckWithSeed
2424
, quickCheckGenWithSeed
2525
, quickCheckPure
26+
, quickCheckPure'
2627
, quickCheckGenPure
28+
, quickCheckGenPure'
29+
, ResultSummary
30+
, checkResults
31+
, printSummary
2732
, class Testable
2833
, test
2934
, Result(..)
@@ -51,7 +56,9 @@ import Prelude
5156

5257
import Control.Monad.Rec.Class (Step(..), tailRec)
5358
import Data.Foldable (for_)
59+
import Data.FoldableWithIndex (foldlWithIndex)
5460
import Data.List (List)
61+
import Data.List as List
5562
import Data.Maybe (Maybe(..))
5663
import Data.Maybe.First (First(..))
5764
import Data.Tuple (Tuple(..))
@@ -61,7 +68,7 @@ import Effect.Console (log)
6168
import Effect.Exception (throwException, error)
6269
import Random.LCG (Seed, mkSeed, unSeed, randomSeed)
6370
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary, class Coarbitrary, coarbitrary)
64-
import Test.QuickCheck.Gen (Gen, evalGen, runGen)
71+
import Test.QuickCheck.Gen (Gen, evalGen, runGen, stateful)
6572

6673
-- | Test a property.
6774
-- |
@@ -144,10 +151,49 @@ type LoopState =
144151
quickCheckPure :: forall prop. Testable prop => Seed -> Int -> prop -> List Result
145152
quickCheckPure s n prop = evalGen (replicateA n (test prop)) { newSeed: s, size: 10 }
146153

154+
-- | Test a property, returning all test results as a List, with the Seed that
155+
-- | was used for each result.
156+
-- |
157+
-- | The first argument is the _random seed_ to be passed to the random generator.
158+
-- | The second argument is the number of tests to run.
159+
quickCheckPure' :: forall prop. Testable prop => Seed -> Int -> prop -> List (Tuple Seed Result)
160+
quickCheckPure' s n prop = evalGen (replicateA n (go prop)) { newSeed: s, size: 10 }
161+
where
162+
go p = stateful \gs -> Tuple gs.newSeed <$> test p
163+
147164
-- | A version of `quickCheckPure` with the property specialized to `Gen`.
148165
quickCheckGenPure :: forall prop. Testable prop => Seed -> Int -> Gen prop -> List Result
149166
quickCheckGenPure = quickCheckPure
150167

168+
-- | A version of `quickCheckPure'` with the property specialized to `Gen`.
169+
quickCheckGenPure' :: forall prop. Testable prop => Seed -> Int -> Gen prop -> List (Tuple Seed Result)
170+
quickCheckGenPure' = quickCheckPure'
171+
172+
-- | A type used to summarise the results from `quickCheckPure'`
173+
type ResultSummary =
174+
{ total :: Int
175+
, successes :: Int
176+
, failures :: List { index :: Int, seed :: Seed, message :: String }
177+
}
178+
179+
-- | Processes the results from `quickCheckPure'` to produce a `ResultSummary`.
180+
checkResults :: List (Tuple Seed Result) -> ResultSummary
181+
checkResults = foldlWithIndex go { total: 0, successes: 0, failures: List.Nil }
182+
where
183+
go :: Int -> ResultSummary -> Tuple Seed Result -> ResultSummary
184+
go index st (Tuple seed result) =
185+
case result of
186+
Success ->
187+
st { total = st.total + 1, successes = st.successes + 1 }
188+
Failed message ->
189+
st { total = st.total + 1, failures = List.Cons { index, seed, message } st.failures }
190+
191+
-- | Print a one-line summary in the form "x/y test(s) passed."
192+
printSummary :: ResultSummary -> String
193+
printSummary summary =
194+
show summary.successes <> "/" <> show summary.total
195+
<> if summary.total == 1 then " test passed." else " tests passed."
196+
151197
-- | The `Testable` class represents _testable properties_.
152198
-- |
153199
-- | A testable property is a function of zero or more `Arbitrary` arguments,

0 commit comments

Comments
 (0)