Skip to content

1.0 readiness: validate the forAll() map and the chain, one assertion per outcome, diagnostics on their own line - #51

Merged
rasuvaeff merged 3 commits into
masterfrom
fix/1-0-readiness
Sep 18, 2026
Merged

rasuvaeff merged 3 commits into
masterfrom
fix/1-0-readiness

Conversation

@rasuvaeff

Copy link
Copy Markdown
Owner

Closes the property-testing-phpunit section of the family's 1.0-readiness review (2026-09-18): P1–P6 plus the adapter-parity items.

Fixes #49
Fixes #50

What changed

  • forAll() map validated at check() (forAll() crashes inside the engine on a non-ArbitraryInterface value and silently ignores a key that is not a parameter #49): a value that is not an ArbitraryInterface throws Property "<name>": forAll() expects array<string, ArbitraryInterface>, got int for key "x" instead of failing inside the runner as a method call on a non-object; a key that is not a parameter of the closure is rejected with or without auto() (Property "<name>": forAll() covers "x", which is not a parameter of the property) — before, only auto() checked it. Message shapes follow the Testo adapter's.
  • One assertion per outcome (A failing property is reported both Failed and Risky when the body performs no PHPUnit assertion #50): addToAssertionCount(1) moves before the verdict, so a falsified property whose body asserted nothing is reported once (Failed), not Failed + Risky. An all-runs-skipped property still registers none.
  • Setters validate at the call, naming the property: runs ≥ 1, maxShrinks/maxDiscards ≥ 0, timeoutMs/budgetMs/shrinkBudgetMs ≥ 1 (Property "<name>": runs must be greater than or equal to 1). A path()/PROPERTY_PATH without seed()/PROPERTY_SEED is refused by check() the same way (the setters may come in either order). Upper bounds stay with the engine.
  • Diagnostics start on their own line: the distribution, the discard warning and the unstable-id warnings are written as "\n" . $line . "\n" so they no longer glue to PHPUnit's progress dots. Line content is unchanged and byte-identical to Testo's; the leading newline is recorded in AGENTS.md as a PHPUnit-only asymmetry. VerboseListener untouched.
  • Docs caught up with core 0.10 (README ×2, llms.txt, AGENTS.md): PROPERTY_VERBOSE/PROPERTY_DERANDOMIZE off words (0/false/off/no), GenerationExhaustedException, no more "auto() requires core ^0.5". EnvironmentParityTest pins the off words and skips under core 0.9.
  • psalm.xml lists TestCase::dataName() next to TestCase::name(), with the finding that Psalm 6.17 resolves neither call from inside the trait (removing either entry reports nothing).

Core constraint stays ^0.9 || ^0.10. No BC break per roave; CHANGELOG.md gets an ## Unreleased section.

Validation

composer build      → psalm: No errors found! / PHPUnit: OK (122 tests, 3202 assertions)
composer rector     → [OK] Rector is done!
composer bc-check   → Detected last version: v0.8.0
                      Comparing from 43e4c5a…c22a485 to fc9ad33…
                      No backwards-incompatible changes detected
make mutation       → 168 mutations: 164 killed, 4 escaped (equivalent), Covered Code MSI: 97% (minMsi 95)
vendor/bin/phpunit examples/SortPropertyTest.php → OK (5 tests)

…very outcome

check() rejects a forAll() value that is not an ArbitraryInterface and a key
that is not a parameter of the closure — with or without auto() — naming the
property, the key and the type, before the engine fails on a method call on
a non-object or silently ignores the typo (#49). Numeric setters validate
their lower bound at the call, and check() refuses a path without a seed,
with the property's name in every message.

The check's assertion is registered before the verdict, so a falsified
property whose body asserted nothing is reported once, as a failure, rather
than Failed and Risky; an all-runs-skipped property still registers none
(#50).

The distribution report, the discard warning and the unstable-id warnings
start on a line of their own, so they no longer glue to PHPUnit's progress
dots.
…environment words

README (both languages), llms.txt and AGENTS.md describe the setter and
forAll() validation messages, the assertion registered on every outcome, the
leading newline on diagnostic lines as a PHPUnit-only asymmetry, and the
off words PROPERTY_VERBOSE/PROPERTY_DERANDOMIZE read since core 0.10.
llms.txt names GenerationExhaustedException and drops the stale
"auto() requires core ^0.5". psalm.xml lists TestCase::dataName() next to
TestCase::name(), with the finding that Psalm resolves neither from inside
the trait.
@coderabbitai

coderabbitai Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: a4baf09c-5269-4073-a24c-1b37b082accd


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@rasuvaeff
rasuvaeff merged commit 001cb8a into master Sep 18, 2026
12 checks passed
@rasuvaeff
rasuvaeff deleted the fix/1-0-readiness branch September 18, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant