Skip to content

Use the log operator to strengthen rules-engine fixtures#6957

Merged
ajpallares merged 64 commits into
mainfrom
pallares/ios-rules-fixture-log-assertions
Jun 9, 2026
Merged

Use the log operator to strengthen rules-engine fixtures#6957
ajpallares merged 64 commits into
mainfrom
pallares/ios-rules-fixture-log-assertions

Conversation

@ajpallares

@ajpallares ajpallares commented Jun 9, 2026

Copy link
Copy Markdown
Member

Motivation

Improves Rules fixtures coverage to assert on intermediate evaluation, not just the final truthiness, using the log operator PR (#6945).

Description

Wrap subexpressions in log and assert exactly what the engine emits via expectedLogs:

  • pin edge-case intermediates (NaN, ±Infinity) across arithmetic, min, max, reduce, missing_some, and evaluator fixtures
  • verify and/or/if short-circuiting: a skipped branch's log must never fire (expectedLogs: []).

Companion Android PR: #3564


Note

Low Risk
Test-only JSON fixture and count-pin updates; no production rules-engine logic changes in this diff.

Overview
Strengthens rules-engine predicate conformance fixtures so tests assert intermediate evaluation via the log operator and expectedLogs, not only final boolean outcomes.

Many existing cases in arithmetic, min/max, reduce, missing_some, and evaluator now wrap edge-producing subexpressions in log and pin emitted strings such as NaN, Infinity, and -Infinity. logic.json gains nine new fixtures that prove and/or/if short-circuiting: log in skipped branches must not run (expectedLogs: []), with positive controls where logs should appear.

PredicateFixtureTests bumps the pinned total fixture count from 360 to 369 so the suite cannot shrink silently.

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

ajpallares and others added 30 commits June 2, 2026 14:56
…tures

Convert the hand-written operator unit tests for operators available at the
string+array level into declarative JSON predicate fixtures sharing khepri's
conformance format, run by a shared runner that auto-discovers every file in
PredicateFixtures/. `expected` is a khepri-compatible superset (Bool or
{ "error": ... }) plus optional `description` and `expectedWarnings`.

Adds a test-only Value: Decodable conformance so predicates and variables
decode straight into the engine's value model; production Value is unchanged.
Tests that can't be expressed as predicate->Bool stay in Swift; ValueTests
untouched. Test-only change.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 40901e5)
Load the in-repo fixtures once and feed the decoded cases straight into
the parameterized test, instead of collecting IDs and re-reading every
file to find the matching case per ID. PredicateConformanceFixtureCase
gains Identifiable + Sendable (for the arguments) and a
CustomTestStringConvertible extension so each case still displays by id.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Asserting an exact warning count coupled the fixtures to engine
internals. Match warnings by substring only (count-agnostic); an empty
`contains` now asserts that no warning is emitted, preserving the
"does not warn" cases. The three count-only fixtures gain the
"missing variable" substring they actually emit.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the khepri single-file plumbing (defaultFixtureURL, fixtureURL,
the no-arg loadCases(), the env var, and the unused fixtureNotFound
error). This PR only runs the in-repo PredicateFixtures/ directory; the
khepri conformance loader lands with its test in the conformance PR.

Co-authored-by: Cursor <cursoragent@cursor.com>
Implements the json-logic-js some/all iteration predicates. Operator coverage
is expressed as JSON predicate fixtures (some.json / all.json) run by the
shared fixture runner introduced downstack, replacing hand-written unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit d11529c)
Implements the json-logic-js min/max operators (variadic flat list, ±∞ for
empty input, NaN propagation for non-numeric operands). Coverage is expressed
as JSON predicate fixtures (min.json / max.json) run by the shared fixture
runner, replacing hand-written unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit e73eabe)
Completes the json-logic-js iteration family (none/map/filter/reduce) on top
of some/all. Coverage is expressed as JSON predicate fixtures
(none.json / map.json / filter.json / reduce.json) run by the shared fixture
runner, replacing hand-written unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 46d6925)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	RevenueCat.xcodeproj/project.pbxproj
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	RevenueCat.xcodeproj/project.pbxproj
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	RevenueCat.xcodeproj/project.pbxproj
Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	RevenueCat.xcodeproj/project.pbxproj
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 [""].
Bumps the pinned fixture count to 237. Keeps the corpus in sync with the
purchases-android counterpart.

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), bumping
the pinned count to 244. Also adds the var-null-path Swift test so the
non-fixturizable cases match the purchases-android counterpart. Keeps the
fixture corpus byte-identical across both repos.

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

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
…json-logic-min-max-operators

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
…on-logic-iteration-mapping-operators

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
ajpallares and others added 13 commits June 8, 2026 12:24
…erators' into pallares/json-logic-min-max-operators

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
Remove the duplicate WorkflowsCacheTests.swift PBXFileReference introduced
during a merge, and add a dedicated "Min and max" grouping comment so the
min/max cases are no longer lumped under arithmetic.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ators' into pallares/json-logic-iteration-mapping-operators

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
…teration-mapping-operators

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
#	Tests/RulesEngineInternalTests/PredicateFixtures/max.json
#	Tests/RulesEngineInternalTests/PredicateFixtures/min.json
Co-authored-by: Cursor <cursoragent@cursor.com>
…ument)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cover logging ±Infinity, NaN, empty object, and empty array. Empty
array and empty args were indistinguishable under substring matching
(they log "" and "null"), so `expectedLogs` now asserts the exact,
ordered list of emitted messages. `expectedWarnings` is unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
The tag was always the single `[RulesEngine]` constant and never varied
at any call site, so it added protocol surface without flexibility. For
the `log` channel a prefix also defeats the verbatim passthrough. Hosts
that bridge the logger prepend their own identifier when they need one.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Wrap NaN- and infinity-producing subexpressions in `log` and assert the
exact emitted string via `expectedLogs`, so these fixtures verify the
intermediate value, not just the final truthiness. Covers arithmetic,
min, max, reduce, missing_some, and evaluator edge cases.

Co-authored-by: Cursor <cursoragent@cursor.com>
Place a `log` in a branch that should be skipped and assert it never
fires (`expectedLogs: []`), with positive controls that log when the
branch is evaluated — verifying and/or/if laziness.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ajpallares ajpallares changed the title Assert intermediate NaN/±Infinity values in rules-engine fixtures Use the log operator to strengthen rules-engine fixtures Jun 9, 2026
@ajpallares ajpallares marked this pull request as ready for review June 9, 2026 08:21
@ajpallares ajpallares requested a review from a team as a code owner June 9, 2026 08:21

@tonidero tonidero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool to be able with this now 🙌

ajpallares and others added 2 commits June 9, 2026 12:08
Co-authored-by: Cursor <cursoragent@cursor.com>
…-log-operator

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

# Conflicts:
#	RulesEngineInternal/Operators/Operators.swift
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
Base automatically changed from pallares/sdk-4367-ios-log-operator to main June 9, 2026 12:03

@rickvdl rickvdl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new operator makes sense, no real code-level feedback.

Just one question about other operators being added in this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these new operators be part of this PR?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean exactly? Probably the diff of this PR was temporarily polluted because I just merged #6945 and still needed to update the base branch + resolve conflicts (which I did in 248db43)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, yep that appears to be it. Seems fixed now :)

…xture-log-assertions

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

# Conflicts:
#	Tests/RulesEngineInternalTests/PredicateFixtureTests.swift
@ajpallares ajpallares enabled auto-merge (squash) June 9, 2026 12:22
@ajpallares ajpallares merged commit 80dab87 into main Jun 9, 2026
18 of 20 checks passed
@ajpallares ajpallares deleted the pallares/ios-rules-fixture-log-assertions branch June 9, 2026 12:33
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