Skip to content

Represent ±Infinity in test fixtures via test-only variables#3556

Merged
ajpallares merged 25 commits into
mainfrom
pallares/json-logic-infinity-fixture-vars
Jun 8, 2026
Merged

Represent ±Infinity in test fixtures via test-only variables#3556
ajpallares merged 25 commits into
mainfrom
pallares/json-logic-infinity-fixture-vars

Conversation

@ajpallares

@ajpallares ajpallares commented Jun 8, 2026

Copy link
Copy Markdown
Member

Motivation

JSON has no Infinity literal, so test fixtures previously created non-finite values by dividing by zero (e.g. {"/": [-10, 0]}), which is obscure and fragile. Suggested in #3552 (comment).

iOS counterpart: purchases-ios/pull/6936

Description

  • When the tests run, the test code makes two special values available to every fixture by name — +Infinity and -Infinity, so a fixture can simply look them up. These exist only while tests run; they are never part of the real rules engine or real rule data.
  • Fixtures that need a non-finite value now read { "var": "-Infinity" } instead of a division-by-zero expression.
  • NaN intentionally keeps the x != x self-comparison strategy, since any equality against NaN is always false (adding a similar strategy for NaN could lead to false positives)

Note

Low Risk
Changes are confined to the predicate conformance test runner and JSON fixtures; production evaluator behavior is untouched.

Overview
Adds test-only +Infinity and -Infinity bindings in PredicateConformanceRunner (merged into each fixture’s evaluation scope; fixture variables win on name clashes) so JSON conformance tests can reference non-finite floats without division-by-zero workarounds.

Predicate fixtures for max, min, missing_some, and substr now use { "var": "±Infinity" } in expectations and inputs where they previously relied on {"/": [n, 0]}. NaN cases are unchanged and still use 0/0 because equality against NaN would be unreliable with a reserved variable.

Reviewed by Cursor Bugbot for commit 1186a8a. Bugbot is set up for automated code reviews on this repo. Configure here.

ajpallares and others added 22 commits June 5, 2026 14:11
…e fixtures

Adds per-operator JSON predicate fixtures (exact copies of the iOS #6885
corpus) under src/test/resources/predicate-fixtures, run by a shared
parameterized runner. Deletes the migrated arithmetic/comparison/equality/
logic suites and trims the accessor/evaluator/string-array suites to the
cases not expressible as predicate->boolean. Test-only change.

Co-authored-by: Cursor <cursoragent@cursor.com>
Expresses the "empty-string key resolves to the whole scope and is not
missing" case as a `{"!!":{"missing":[""]}}` -> false fixture (the string
coercion the other missing fixtures use can't distinguish [] from [""]).
Removes the now-covered Kotlin test and bumps the fixture count to 237.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adds fixtures for the empty-segment dot-path splits, var default-vs-null-leaf
behavior, and the non-numeric missing_some threshold (7 new cases), and drops
the now-redundant Kotlin tests. AccessorOperatorsTest keeps only the cases
that cannot be a predicate->boolean fixture (top-level array scope or a
whole-object return). Fixture count is now 244.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Mirror the iOS rules-engine implementation: Kotlin some/all operators
matching json-logic-js semantics, shared JSON predicate fixtures, and
pinned fixture count bumped to 271.

Co-authored-by: Cursor <cursoragent@cursor.com>
place operator docs on each op instead of duplicating at the type level; drop "not vacuous truth" wording

Co-authored-by: Cursor <cursoragent@cursor.com>
Implement variadic min/max with JS Math.min/Math.max semantics: operands
coerce via Number() (toNumberOrNull), empty input yields ±∞, and NaN
operands poison the result. Wire into the operator dispatcher and add
byte-identical min.json/max.json fixtures from purchases-ios, bumping
the pinned fixture count to 305.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Label each operator grouping in Operators.dispatch per PR review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move the string/array group after comparison so the Android dispatcher
mirrors the iOS Operators.dispatch grouping order.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rename the all-match fixture and add cases where only the first or only
the middle item matches, addressing PR review feedback that the existing
some coverage was order dependent. Fixtures kept byte-identical with iOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
khepri guards all with notEmpty, so it returns false for an empty array
like json-logic-js; drop the inaccurate claim that khepri returns true.
Fixture kept byte-identical with iOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
…teration-operators

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	rules-engine-internal/src/test/kotlin/com/revenuecat/purchases/rules/PredicateFixtureLoaderTest.kt
…erators' into pallares/json-logic-min-max-operators

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	rules-engine-internal/src/main/kotlin/com/revenuecat/purchases/rules/operators/Operators.kt
#	rules-engine-internal/src/test/kotlin/com/revenuecat/purchases/rules/PredicateFixtureLoaderTest.kt
…in-max-operators

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	rules-engine-internal/src/main/kotlin/com/revenuecat/purchases/rules/operators/Operators.kt
#	rules-engine-internal/src/test/kotlin/com/revenuecat/purchases/rules/PredicateFixtureLoaderTest.kt
Add a dedicated "Min and max" grouping comment so the min/max cases are not
lumped under arithmetic, matching the iOS dispatcher.

Co-authored-by: Cursor <cursoragent@cursor.com>
Self-documenting replacement for the {"/": [-10,0]} workaround; constants
seeded only by the conformance harness (reservedConstants), engine untouched;
NaN still uses x != x; fixtures kept byte-identical with iOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
substr.json and missing_some.json now use the seeded "+Infinity" and
"-Infinity" variables instead of division-by-zero operands. NaN cases
and evaluator.json are unchanged. Fixtures are byte-identical to iOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
Base automatically changed from pallares/json-logic-min-max-operators to main June 8, 2026 14:03
@ajpallares ajpallares changed the title Use test-only ±Infinity vars in min/max empty-args fixtures Represent ±Infinity in test fixtures via test-only variables Jun 8, 2026
ajpallares and others added 2 commits June 8, 2026 16:10
Mirror iOS predicate fixture updates: remove the redundant
"comes from the test-only" clause from 7 fixture descriptions
across min, max, substr, and missing_some. Fixtures kept
byte-identical with iOS.

Co-authored-by: Cursor <cursoragent@cursor.com>
…nfinity-fixture-vars

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	rules-engine-internal/src/test/resources/predicate-fixtures/max.json
#	rules-engine-internal/src/test/resources/predicate-fixtures/min.json
@ajpallares ajpallares marked this pull request as ready for review June 8, 2026 14:22
@ajpallares ajpallares enabled auto-merge June 8, 2026 14:34
@ajpallares ajpallares added this pull request to the merge queue Jun 8, 2026
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.15%. Comparing base (cad9ffe) to head (1186a8a).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3556   +/-   ##
=======================================
  Coverage   80.15%   80.15%           
=======================================
  Files         371      371           
  Lines       15210    15210           
  Branches     2110     2110           
=======================================
  Hits        12192    12192           
  Misses       2168     2168           
  Partials      850      850           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Merged via the queue into main with commit c56aa0b Jun 8, 2026
39 checks passed
@ajpallares ajpallares deleted the pallares/json-logic-infinity-fixture-vars branch June 8, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants