data Trace = MkTrace (List String) (List String) (Maybe Int) -- inputs, labels, trials asked
import Data.TestData.Test — the Property monad (do-style property tests)
Synopsis
data Trace = MkTrace (List String) (List String) (Maybe Int) -- inputs, labels, trials askeddata Outcome adata Property a = MkProp (Gen (Pair Trace (Outcome a)))forAll : Show a => Gen a -> Property awithTests : Int -> Property ()(===) : Eq a => Show a => a -> a -> Property ()(/==) : Eq a => Show a => a -> a -> Property ()assert : Bool -> Property ()claimHolds : String -> a -> a -> Property ()claimInput : Gen a -> Property asameSet : Ord a => Eq a => Show a => List a -> List a -> Property ()withinAbs : Double -> Double -> Double -> Property ()withinRel : Double -> Double -> Double -> Property ()satisfies : Show a => a -> (a -> Bool) -> Property ()classify : String -> Bool -> Property ()label : String -> Property ()collect : Show a => a -> Property ()data CheckResult =data Check =checkStart : CheckcheckStep : Int -> Int -> Int -> Property a -> Check -> CheckcheckProperty : Int -> Int -> Int -> Property a -> CheckResult
data Outcome a
= Done a
| Failed String
The result of running a property's assertions: a value, or the first failure.
Donethe trial finished with a value
Failedan assertion failed, with its message
data Property a = MkProp (Gen (Pair Trace (Outcome a)))
Property a = Gen (Trace, Outcome a): a generator (carrying the shrink tree) of a traced outcome.
forAll : Show a => Gen a -> Property a
Draw a value from a generator, recording it (via show) for the failure report. The generator's shrink tree becomes the property's, so the drawn value shrinks toward its generator's origin on failure.
withTests : Int -> Property ()
Ask for n trials of this property, whatever the suite's default (oppi test --tests, [test] property_tests, or the pinned 100). A statement anywhere in the block; the last one written wins. n must be at least 1: a property is checked by running it.
(===) : Eq a => Show a => a -> a -> Property ()
Assert two values equal; on failure the report shows both sides.
(/==) : Eq a => Show a => a -> a -> Property ()
assert : Bool -> Property ()
Assert a boolean holds.
claimHolds : String -> a -> a -> Property ()
Judge the claim x ≡ y of a specification (conn: the connector as written, quoted when the two sides cannot be compared). On failure the report shows both sides, printed by the runner.
claimInput : Gen a -> Property a
sameSet : Ord a => Eq a => Show a => List a -> List a -> Property ()
Equal up to permutation ("à permutation près"): same elements, same multiplicities, order ignored. Use when a function's result order is unspecified (e.g. the set of colours / vertices of a graph).
withinAbs : Double -> Double -> Double -> Property ()
Equal within an ABSOLUTE tolerance ε: |a - b| ≤ ε.
withinRel : Double -> Double -> Double -> Property ()
Equal within a RELATIVE tolerance p of the reference: |a - b| ≤ p·|b| (so withinRel 0.01 is "within 1 %").
satisfies : Show a => a -> (a -> Bool) -> Property ()
The value satisfies a predicate (for specs with no unique answer). Reads well infix: result satisfies isSorted.
classify : String -> Bool -> Property ()
Tag this run with lbl when cond holds — the summary reports the % of runs so tagged (so you can see the distribution your generators produce).
label : String -> Property ()
Always tag this run with lbl.
collect : Show a => a -> Property ()
Tag this run with show x — collect a distribution of values.
data CheckResult =
Passed Int (List (Pair String Int))
| Falsified Int (List String) String (List (Pair String Int))
The outcome of checking a property numTests times.
Passedall trials passed: tests run, label tally
Falsifieda counterexample: trial number, shrunk inputs, message, tally
data Check =
Running Int (List (Pair String Int)) (Maybe Int)
| Finished CheckResult
The state of a check between two trials: how many trials have passed, the label tally so far, and the number of trials the property asked for (Nothing until a trial says, via withTests) — or the final result.
Runningtrials passed so far, label tally, trials asked
Finishedthe check is over
checkStart : Check
Where every check starts.
checkStep : Int -> Int -> Int -> Property a -> Check -> Check
ONE trial of prop — the single authority for what a trial is: draw the inputs at size from the seed of trial t (mixed from base), run the assertions, tally the labels, and on the first falsifying trial shrink it to a minimal failing input. checkProperty below is nothing but the iteration of this step; the test runner (oppi test, the browser engine) iterates the SAME step from outside, one evaluation per trial, so the evaluator's divergence guard (step and time budgets) applies PER TRIAL: a trial that loops costs one budget, never the budget of all the trials.
numTests is the SUITE's count (the runner's cascade); a property that asks for its own (withTests) is heard from its first trial on, and its count replaces the suite's for the rest of the check.
checkProperty : Int -> Int -> Int -> Property a -> CheckResult
Run prop up to numTests times at size, deterministically seeded from base. On the first falsifying trial, shrink it to a minimal failing input and stop; otherwise report how the labels were distributed.