Check
Check module: property-test runner with integrated shrinking.
Runs a Gen.Generator(a)-produced value through a user-supplied property function a configurable number of times. When a property fails — whether by returning false, raising an assert failure, or crashing with any other runtime exception — the runner walks the failing input's shrink tree (integrated into the generator per Hedgehog's design) to find a minimal counterexample, then panics with a report that includes the shrunk value, the number of runs, and the seed for replay.
The existing test ... do ... end runner catches the panic and reports the property as a failing test. No compiler changes required beyond the __try_call builtin that catches runtime exceptions.
Typical use:
test "reverse is involution" do
Check.all(Gen.list(Gen.int(-100, 100)), fn xs ->
List.reverse(List.reverse(xs)) == xs
)
endSeed sources (highest priority first):
CheckConfig.seedpassed toCheck.all_withMARCH_PROP_SEEDenvironment variable (set byforge test --seed=N)- current Unix time
Types
Functions
Run a property with default_config() (100 runs). Returns () when the property holds on every generated value; otherwise shrinks the failing input and panics with a report (counterexample, reason, shrink steps, seed), which the test runner catches and reports. Does nothing when MARCH_SKIP_PROPERTIES=1. Random (seeded from MARCH_PROP_SEED or the clock), so not a REPL example:
Check.all(Gen.list(Gen.int(-100, 100)), fn xs ->
List.reverse(List.reverse(xs)) == xs
)Run a property with an explicit config. Use to override the run count, seed, size cap or shrink budget. Run i (0-based) gets size hint i * max_size / (num_runs - 1) (just max_size when num_runs <= 1). On the first failing run the input's shrink tree is walked greedily (first failing child at each level, at most max_shrink_steps steps) and the call panics with the report described in all. Returns () if every run passes, or immediately if MARCH_SKIP_PROPERTIES=1. Seed: config.seed, else MARCH_PROP_SEED (falling back to the clock when unset or not an integer), else the current Unix time in seconds.
Check.all_with(gen, prop, { Check.default_config() with seed: Some(42) })Sensible defaults: 100 runs, a size hint growing linearly from 0 to 100 across the runs, up to 1000 shrink steps, and seed: None (so the seed comes from MARCH_PROP_SEED or the clock). Override fields with a record update.
Examples
march> let cfg = Check.default_config()
march> cfg.num_runs
100
march> let cfg = Check.default_config()
march> cfg.seed
None
march> let cfg = Check.default_config()
march> { cfg with num_runs: 10 }.num_runs
10Run a property on one value, catching any runtime failure. Returns: Ok(true) — property held Ok(false) — property returned false Err(msg) — property raised (assert, panic, match failure, etc.); msg is the runtime error text
Examples
march> Result.unwrap_or(Check.try_prop(fn x -> x > 0, 5), false)
true
march> Check.try_prop(fn x -> 10 / x > 0, 0)
Err("division by zero")