mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-09 22:35:56 +05:45
* refactor: move rules engine into core SDK as internal Move the RulesEngineInternal sources and tests into the RevenueCat target under Sources/RulesEngine and Tests/UnitTests/RulesEngine. The moved symbols are marked internal so no new public API is exposed, and the standalone RulesEngineInternal target is removed from Package manifests, Tuist, the Xcode project, and CI. No usages yet. Co-authored-by: Cursor <cursoragent@cursor.com> * Document why the rules engine owns its own logging abstraction Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
3.9 KiB
JSON
90 lines
3.9 KiB
JSON
{
|
|
"fixtures": [
|
|
{
|
|
"id": "missing_returns_keys_not_present",
|
|
"description": "missing is a check, not a read, so it does not warn; the result array is compared via its JS string coercion",
|
|
"predicate": { "==": [{ "missing": ["a", "b", "c"] }, "c"] },
|
|
"variables": { "a": 1, "b": 2 },
|
|
"expected": true,
|
|
"expectedWarnings": { "contains": [] }
|
|
},
|
|
{
|
|
"id": "missing_returns_empty_array_when_all_present",
|
|
"description": "the empty result is compared via its JS string coercion (\"\")",
|
|
"predicate": { "==": [{ "missing": ["a"] }, ""] },
|
|
"variables": { "a": 1 },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_supports_dot_path_keys",
|
|
"description": "single-element result compared via its JS string coercion",
|
|
"predicate": { "==": [{ "missing": ["user.name", "user.email"] }, "user.email"] },
|
|
"variables": { "user": { "name": "ada" } },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_singleton_shorthand",
|
|
"description": "{\"missing\": \"a\"} is shorthand for {\"missing\": [\"a\"]}; result compared via its JS string coercion",
|
|
"predicate": { "==": [{ "missing": "a" }, "a"] },
|
|
"variables": {},
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_recursively_evaluates_dynamic_keys",
|
|
"description": "each key arg is recursively evaluated before lookup; the inner var resolves to \"absent\"",
|
|
"predicate": { "==": [{ "missing": [{ "var": "key_name" }] }, "absent"] },
|
|
"variables": { "key_name": "absent", "present_only": 1 },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_unpacks_first_arg_when_resolves_to_array",
|
|
"description": "if the first evaluated arg is itself an array, its elements are the full key list",
|
|
"predicate": { "==": [{ "missing": { "if": [true, ["a", "c"], []] } }, "c"] },
|
|
"variables": { "a": 1 },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_reports_key_whose_leaf_value_is_null",
|
|
"description": "missing routes through var, so a present-but-null leaf is reported as missing",
|
|
"predicate": { "==": [{ "missing": ["a", "b"] }, "a"] },
|
|
"variables": { "a": null, "b": 1 },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_reports_key_whose_leaf_value_is_empty_string",
|
|
"description": "value === \"\" also counts as missing",
|
|
"predicate": { "==": [{ "missing": ["a", "b"] }, "a"] },
|
|
"variables": { "a": "", "b": "x" },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_does_not_report_falsy_non_empty_values",
|
|
"description": "only null or empty-string leaves are missing; 0, false, and [] are not; the empty result is compared via string coercion",
|
|
"predicate": { "==": [{ "missing": ["zero", "flag", "empty_array"] }, ""] },
|
|
"variables": { "zero": 0, "flag": false, "empty_array": [] },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_reports_dot_path_leaf_that_is_null",
|
|
"description": "the null-leaf rule applies through dot-paths too",
|
|
"predicate": { "==": [{ "missing": ["user.name", "user.email"] }, "user.name"] },
|
|
"variables": { "user": { "name": null, "email": "a@b.com" } },
|
|
"expected": true
|
|
},
|
|
{
|
|
"id": "missing_empty_string_key_resolves_to_scope",
|
|
"description": "missing routes through var; var with an empty path returns the whole scope (neither null nor empty string), so the empty key is not missing and the result is empty (falsy)",
|
|
"predicate": { "!!": { "missing": [""] } },
|
|
"variables": { "a": 1 },
|
|
"expected": false
|
|
},
|
|
{
|
|
"id": "missing_undefined_key_resolves_to_scope",
|
|
"description": "missing routes through var; an undefined key (here {\"and\": []}) makes var return the whole scope (neither null nor empty string), so the key is not missing and the result is empty (falsy)",
|
|
"predicate": { "!!": { "missing": [{ "and": [] }] } },
|
|
"variables": { "a": 1 },
|
|
"expected": false
|
|
}
|
|
]
|
|
}
|