Skip to content

PropertyConfig ​

Rasuvaeff\PropertyTesting\Runner\PropertyConfig

Class — Package: property-testing-core — Source — Version: v1.0.0-1-g88fdee2

Resolved knobs of one property run. The engine never reads the process environment: an adapter resolves its attribute/env/defaults into this value and hands it over, so a direct PropertyRunner call has no hidden process state.

Constructor ​

php
__construct(
    int $runs = 100,
    ?int $seed = NULL,
    ?int $maxShrinks = NULL,
    ?int $maxDiscards = NULL,
    ?int $timeoutMs = NULL,
    ?int $budgetMs = NULL,
    ?\Runner\ShrinkMode $shrink = NULL,
    ?int $shrinkBudgetMs = NULL,
    ?list<\Runner\Phase> $phases = NULL,
    bool $derandomize = false,
    ?string $path = NULL,
    \Runner\EdgeCases $edgeCases = Rasuvaeff\PropertyTesting\Runner\EdgeCases::Mixin,
    bool $exhaustive = false,
    int $exhaustiveBudget = 10000,
    int $flakyReplays = 2,
    int $searchRuns = 0,
)
ParameterTypeDefaultDescription
$runsint100Number of successful checks to complete. Discarded runs do not count.
$seed?intNULLSeed of the random phase. Null lets the runner draw a random one.
$maxShrinks?intNULLCap on accepted shrink steps. Null means no cap, 0 disables shrinking.
$maxDiscards?intNULLMaximum discarded runs before giving up. Null uses ten times $runs (saturating to PHP_INT_MAX).
$timeoutMs?intNULLWall-clock deadline for a single run in milliseconds; null disables it.
$budgetMs?intNULLWall-clock budget for the whole random phase in milliseconds; null disables it.
$shrink?\Runner\ShrinkModeNULLHow hard to minimise a counterexample. Null means Runner\ShrinkMode::Full unless $shrinkBudgetMs or $phases say otherwise.
$shrinkBudgetMs?intNULLWall-clock budget for the shrink descent in milliseconds, which implies Runner\ShrinkMode::Bounded; null disables it. Unlike every other knob this one costs determinism: the same seed can minimise to different counterexamples on a fast and a slow machine, because how far the descent gets depends on how long the body takes. It answers "the descent hung", not "reproduce this exactly" — the corpus and an explicit seed remain the reproducible paths. A budget large enough to overflow its own nanosecond deadline is a configuration error.
$phases?list<\Runner\Phase>NULLStages to perform; null means Runner\Phase::all(). An empty list is a configuration error — a run with no phases has nothing to report — and so is a list holding anything other than a Runner\Phase: an unrecognised stage is not run, which would report green having checked nothing.
$derandomizeboolfalseWhether an unset $seed is derived from the property's id instead of drawn at random, so the same property on the same code always selects the same inputs. An explicit $seed always wins. The derivation lives in Runner\PropertyRunner because only it knows the id — and because a config that called random_int() would stop being a plain value.
$path?stringNULLThe shrink descent of an earlier failure, as reported by CounterExample::$path: the runner follows those steps instead of searching for them again, executing the body once per recorded step instead of once per candidate tried. Null searches as usual. It needs an explicit $seed (the steps only mean anything against the run that produced them), and it refuses every configuration that would leave it a silent no-op: a descent switched off, capped below the path's own length, or bounded by a wall clock — the last one because a path exists to be deterministic and a budget exists not to be.
$edgeCasesRunner\EdgeCasesRasuvaeff\PropertyTesting\Runner\EdgeCases::MixinWhether the numeric generators keep biasing toward their boundary values (Runner\EdgeCases::Mixin, the default) or generate uniformly (Runner\EdgeCases::None). Turn them off when the edges are what the property cannot use — a body discarding 0, a range end that violates a precondition — so the discard budget stops paying for one run in five. A parameter added anywhere before this one moves the ones after it, and every caller passing $path positionally would silently mean something else — later parameters are appended after it.
$exhaustiveboolfalseWhether the random phase enumerates the whole parameter domain instead of sampling it, when it can: every parameter's generator must implement Enumerable with a finite domain, and the product of the sizes must not exceed $exhaustiveBudget. When it cannot, the phase samples as usual and the Runner\DistributionReport says why. A pass over an enumerated domain is a proof over the parameters — in-body draws stay random inside each input — and the walk is seed-independent, so $runs is ignored in favour of the domain size.
$exhaustiveBudgetint10000The largest domain $exhaustive will enumerate; above it the phase samples. At least 1.
$flakyReplaysint2How many times the minimised counterexample is re-executed after a falsification to tell a real counterexample from nondeterminism in the body or the code under test. A replay that passes marks the counterexample flaky (CounterExample::$flaky); 0 disables the check. Charged to wall clock only, never to $runs.
$searchRunsint0How many bodies the targeted search may execute after the random phase when the body reports a Target: the best-scoring inputs are mutated one parameter at a time and kept when they score better. 0 (the default) performs no search; a property that targets nothing is unaffected either way. Search runs are checks like any other — a failing one falsifies the property — and count toward the same discard and time budgets.

Properties ​

PropertyTypeReadonlyDescription
phasesnon-empty-list<\Runner\Phase>yesWhich stages this run performs, in run order. Never empty.
shrinkRunner\ShrinkModeyesThe resolved shrink mode: what $shrink, $shrinkBudgetMs and $phases amount to together, so the runner reads one field instead of re-deriving a three-way interaction.

Methods ​

runs() ​

php
runs(\Runner\Phase $phase): bool

True when this run performs $phase.

  • $phase — The stage to test for.