Skip to content

Classify ​

Rasuvaeff\PropertyTesting\Classify

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

Records distribution labels for the current property run so the runner can report how often each case occurred. Use it to confirm a property is not passing vacuously — that the generators actually exercise the interesting inputs.

php
#[Property(runs: 500)]
public function holds(int $n): void
{
    Classify::when($n === 0, 'zero');
    Classify::when($n < 0, 'negative');
    Classify::label($n % 2 === 0 ? 'even' : 'odd');
    // ... assertions ...
}

After a fully passing property the runner prints the share of runs that hit each label. A label recorded several times within one run still counts once for that run.

State is per-run and process-local: the runner clears it before each run via beginRun() and drains it via flushRun(). Property runs are sequential, so the static buffer is never shared concurrently.

Methods ​

label() ​

php
static label(string $label): void

Record $label for the current run.

when() ​

php
static when(bool $condition, string $label): void

Record $label for the current run only when $condition holds.

cover() ​

php
static cover(
    bool $condition,
    string $label,
    float $minPercent,
): void

Like when(), but additionally REQUIRES the label to occur in at least $minPercent of the property's passing runs. When the requirement is not met the property fails with a CoverageViolationException even though every run passed — turning "the distribution looks wrong" from a printed hint into a CI failure.

php
Classify::cover($n % 2 === 0, 'even', 30.0);

The threshold belongs to the label, not to the call: covering the same label twice in one run with different percentages leaves the last one standing.

tabulate() ​

php
static tabulate(string $table, string|list<string> $tags): void

Record one or more tags of $table for the current run: the categories a run belongs to at once, aggregated into a per-table tally with the pairwise intersections of tags that were hit together. Observability only — no minimum share, no verdict; cover() stays the one enforcement tool:

  • $table — The table the tags belong to.
  • $tags — One tag, or every tag the run hits at once.

Classify::tabulate('payload', $size < 1024 ? 'small' : 'large'); Classify::tabulate('features', array_keys(array_filter([ 'compressed' => $compressed, 'retried' => $attempt > 1, ])));

A tag recorded several times within one run counts once for that run, like a label. An empty tag list records nothing.

beginRun() ​

php
static beginRun(): void

Clear the labels and tables of the previous run.

flushRun() ​

php
static flushRun(): array

Return the labels recorded during the current run and clear the buffer.

flushTables() ​

php
static flushTables(): array

Return the tables recorded during the current run — table name to the tags hit, as the strings the body recorded — and clear them.

flushRequirements() ​

php
static flushRequirements(): array

Return the coverage requirements registered during the property and clear them. The runner drains this once after the run loop (and defensively before it, in case a previous property aborted mid-flight).