Skip to content

Make the ordering assertions reject operands PHP can only compare by coercion - #366

Open
lenamonj wants to merge 1 commit into
webmozarts:masterfrom
lenamonj:fix-ordering-incomparable-operands
Open

Make the ordering assertions reject operands PHP can only compare by coercion#366
lenamonj wants to merge 1 commit into
webmozarts:masterfrom
lenamonj:fix-ordering-incomparable-operands

Conversation

@lenamonj

@lenamonj lenamonj commented Sep 1, 2026

Copy link
Copy Markdown

Assert::lessThan(new stdClass(), 10), Assert::lessThan(null, 10), Assert::lessThan(false, 10) and Assert::range(new stdClass(), 1, 10) all pass. greaterThan([1, 2], 10) and greaterThan('abc', 10) pass too.

Cause: the five ordering assertions hand their operands straight to <, <=, >, >=, which answer for any pair by coercing: an object compares as 1, an array outranks any scalar, and null or bool against a number is compared as bool.

Change: a comparable() helper that accepts two numerics, two strings, two bools, two arrays or two objects; anything else is reported through the method's existing message path, so messages and placeholders are unchanged. Pairs the suite already exercised keep their verdicts ('5' vs 10, DateTimeImmutable vs DateTimeImmutable, [1] vs [1, 2], true vs false are pinned in the provider). NAN is deliberately left alone per #302.

This does narrow what the five methods accept, which is the point of an assertion, but if you would rather draw the line differently (for example keep bool against int) I am happy to adjust.

Verified: composer run test 4997 tests green on PHP 8.5 (the 8 new rejection rows fail before the fix), cs-check and static-analysis clean.

Found by an automated code-review loop I run; the fix and this description were prepared with Claude and verified by hand.

…coercion

greaterThan, greaterThanEq, lessThan, lessThanEq and range handed their
operands straight to the relational operators, so lessThan(new stdClass(), 10)
and lessThan(null, 10) passed: an object compares as 1, and null or bool
against a number is compared as bool. Ask first whether the pair can be
ordered (two numerics, two strings, two bools, two arrays or two objects) and
report anything else as the failed assertion it is.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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