Skip to content

Migrate to property-testing-testo and pin the catalogue boundary - #13

Merged
rasuvaeff merged 1 commit into
masterfrom
test/property-testing-testo
Aug 15, 2026
Merged

Migrate to property-testing-testo and pin the catalogue boundary#13
rasuvaeff merged 1 commit into
masterfrom
test/property-testing-testo

Conversation

@rasuvaeff

Copy link
Copy Markdown
Owner

What

rasuvaeff/property-testing: ^2.4 rasuvaeff/property-testing-testo: ^0.4
rasuvaeff/rector-named-literals added and applied
CI property regression corpus + narrow mutation filter
Properties 4 → 5

Why ^0.4 and not ^0.1

MIGRATION.md still shows ^0.1; that line was written at 0.1.0. The adapter
chains to the engine by minor — -testo 0.3 requires core ^0.3 — so ^0.1
installs core 0.1 and leaves Gen::regex and the rest of 0.2/0.3 unreachable.

Nothing asked about names outside the catalogue

Both existing properties drew from Gen::oneOf(...) over names that are in the
catalogue, then checked case-insensitivity. Nothing said what happens to a name
that is not — and that boundary is the whole safety story of a rewriting rule:

  • a name it does not know, mapped, rewrites user code into a call that does not exist;
  • a name from another catalogue, answered yes, treats an already-immutable
    factory as needing the rewrite it is the target of.

eachLookupAnswersYesOnlyForItsOwnCatalogue checks all three lookups
(immutableEquivalent, isProceduralImmutableFactory, isSharedStaticFactory)
against all three catalogues, drawing catalogued names alongside near misses
built from the same alphabets via Gen::regex('date_[a-z_]{0,12}') and
Gen::regex('createFrom[A-Za-z]{0,10}') — so date_created and
createFromImmutable are ordinary draws rather than lucky ones.

Examples() pins createFromImmutable specifically: the source documents it as
deliberately absent ("it has no counterpart on DateTimeImmutable and marks
code that wants mutability"), and no test enforced that.

Case-insensitivity, gated

lookupsAreCaseInsensitive applies a random 16-bit case mask. A mask of zero
leaves the name as written and asserts nothing about case handling;
Classify::cover now requires at least 60% of runs to actually change it.

Checklist items deliberately skipped

Gen::commands/StateMachine — the map and the catalogue are lookup tables.
Gen::datetime — this package rewrites DateTime code, it does not compute
with dates.

Verification

composer build green locally.

Swap the frozen rasuvaeff/property-testing 2.x for the split family's Testo
adapter, pinned at ^0.4 (core ^0.3) — ^0.1, which MIGRATION.md still shows,
installs core 0.1 and leaves every 0.2/0.3 engine feature unreachable.

Both existing properties only ever asked about names that are in the catalogue,
so nothing said what happens to a name that is not. That boundary is the whole
safety story of this rule: a rewriter that mapped a name it does not know would
rewrite user code into a call that does not exist, and one that answered yes
across catalogues would treat an already-immutable factory as needing the
rewrite it is the target of.

eachLookupAnswersYesOnlyForItsOwnCatalogue checks all three lookups against all
three catalogues, generating catalogued names alongside near misses built from
the same alphabets through Gen::regex — so `date_created` and
`createFromImmutable` are ordinary draws rather than lucky ones. Examples()
pins createFromImmutable specifically: the source documents it as deliberately
absent, and nothing enforced that.

The case-insensitivity property gained a floor on runs where the mask actually
changes the name — a mask of zero asserts nothing about case handling.

Also wire rasuvaeff/rector-named-literals and apply it, carry the property
regression corpus across CI runs (restore and save split, because the combined
cache action's post-if: success() never saves on the red run that recorded the
counterexample), and give mutation its own narrow change filter.
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e4e452a-6e57-42f6-b79a-2e3099c1ac0b


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 fcce7d5 into master Aug 15, 2026
11 checks passed
@rasuvaeff
rasuvaeff deleted the test/property-testing-testo branch August 15, 2026 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant