CounterExample
Rasuvaeff\PropertyTesting\CounterExample
Class — Package: property-testing-core — Source — Version: v1.0.0-1-g88fdee2
Minimal failing input for a property, captured at falsification time.
Carries both the original (randomly generated) counterexample and the shrunk (minimised) one, plus the seed needed to reproduce the run.
Constructor
__construct(
int $seed,
int $runsBeforeFailure,
array<string,mixed> $originalArguments,
array<string,mixed> $shrunkArguments,
int $shrinkSteps = 0,
?\Throwable $failure = NULL,
int $discards = 0,
int $shrinkTrials = 0,
string $path = '',
\Runner\EdgeCases $edgeCases = Rasuvaeff\PropertyTesting\Runner\EdgeCases::Mixin,
int $skips = 0,
array<string,mixed> $originalNotes = [],
array<string,mixed> $shrunkNotes = [],
int $replays = 0,
?int $passedOnReplay = NULL,
)| Parameter | Type | Default | Description |
|---|---|---|---|
$seed | int | required | Seed of the run that first failed (replay it as Runner\PropertyConfig::$seed). |
$runsBeforeFailure | int | required | Number of successful (non-discarded) runs before the failure. |
$originalArguments | array<string,mixed> | required | Randomly generated arguments that first failed. |
$shrunkArguments | array<string,mixed> | required | Minimised arguments that still fail. |
$shrinkSteps | int | 0 | Number of accepted shrink steps between the original and the minimised arguments. |
$failure | ?\Throwable | NULL | The assertion or exception reported by the failing run. |
$discards | int | 0 | Number of runs discarded via Assume::that() before the failure. |
$shrinkTrials | int | 0 | Total number of shrink candidates tried (accepted and rejected). |
$path | string | '' | The accepted shrink steps that lead from the original arguments to the minimised ones, as name:index segments joined by /. Passed back through Runner\PropertyConfig::$path (together with the seed) it replays this descent instead of searching for it again. Empty when nothing shrank. A debugging aid, not a durable identifier: it indexes into each node's shrink candidates, so editing a generator orphans it — the regression corpus is what survives a refactor. |
$edgeCases | Runner\EdgeCases | Rasuvaeff\PropertyTesting\Runner\EdgeCases::Mixin | The boundary-value mode the failing run was generated under. The seed reproduces the failure only under the same mode (the modes share the roll but not the values it selects), so a seed replay — the corpus above all — carries it along. |
$skips | int | 0 | Number of runs the environment refused (a skipped hook or body) before the failure. Counted apart from $discards: a discard says the generated input left the property's domain, a skip says nothing about the input at all. |
$originalNotes | array<string,mixed> | [] | What Gen::note() attached during the run that first failed, by label. |
$shrunkNotes | array<string,mixed> | [] | What Gen::note() attached during the run of the minimised arguments — the original notes when nothing shrank. |
$replays | int | 0 | How many times the minimised input was re-executed after the descent (Runner\PropertyConfig::$flakyReplays) to tell a counterexample from nondeterminism — up to the configured count, stopping at the first replay that passed. |
$passedOnReplay | ?int | NULL | The one-based replay that did not fail, when one did: the counterexample is flaky — the body or the code under test is nondeterministic, and the input is not by itself what falsifies the property. Null when every replay failed again (or none ran). |
Methods
isFlaky()
isFlaky(): boolWhether a replay of the minimised input passed: the failure is not a function of the input alone.
toArray()
toArray(): arrayMachine-readable representation suitable for reporters and serialization.
toJson()
toJson(bool $pretty = false): stringtoExamplesCode()
toExamplesCode(string $methodName = 'propertyExamples'): stringThe shrunk counterexample as a ready-to-paste <method>Examples() method.
Refuses when the counterexample cannot actually replay as an example: a value ValueRenderer::exportPhp() cannot render, or a draw#N pseudo-argument — an in-body draw is not a parameter, so an example cannot carry it and the failure replays only through the seed.