Use the log operator to strengthen rules-engine fixtures#6957
Merged
Conversation
…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>
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
…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>
log operator to strengthen rules-engine fixtures
tonidero
approved these changes
Jun 9, 2026
tonidero
left a comment
Contributor
There was a problem hiding this comment.
Cool to be able with this now 🙌
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
…ules-fixture-log-assertions
rickvdl
approved these changes
Jun 9, 2026
rickvdl
left a comment
Member
There was a problem hiding this comment.
The new operator makes sense, no real code-level feedback.
Just one question about other operators being added in this PR.
Member
There was a problem hiding this comment.
Should these new operators be part of this PR?
Member
Author
Member
There was a problem hiding this comment.
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Improves Rules fixtures coverage to assert on intermediate evaluation, not just the final truthiness, using the
logoperator PR (#6945).Description
Wrap subexpressions in
logand assert exactly what the engine emits viaexpectedLogs:and/or/ifshort-circuiting: a skipped branch'slogmust 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
logoperator andexpectedLogs, not only final boolean outcomes.Many existing cases in arithmetic, min/max, reduce, missing_some, and evaluator now wrap edge-producing subexpressions in
logand pin emitted strings such asNaN,Infinity, and-Infinity. logic.json gains nine new fixtures that proveand/or/ifshort-circuiting:login skipped branches must not run (expectedLogs: []), with positive controls where logs should appear.PredicateFixtureTestsbumps 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.