Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ACCEPTED_PROPOSALS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Define JSON Logic on the JSON Data Model | - Defines JSON Logic on the data mode
`val` and context replacements | - Deprecates `var`, `missing` and `missing_some` to the legacy extension <br/> <br/> - Defines `val`, `exists` and `??` | https://github.com/orgs/json-logic/discussions/18 | [`val.json`](tests/val.json), [`exists.json`](tests/exists.json), [`coalesce.json`](tests/coalesce.json) | 1
Amend Test Specification / Error Handling | - Defines that errors like `NaN` should bubble up the AST and halt execution, unless handled. <br/><br/> - Extends the test specification to be able to test for errors. <br/><br/> - Introduces two new operators, `throw` and `try` <br/><br/> - Defines that division by zero results in a `NaN` error. | https://github.com/orgs/json-logic/discussions/20 | [`throw.json`](tests/throw.json), [`try.json`](tests/try.json) | 1
Linear Time Ruling | - Establishes a guideline for selecting enabled by default JSON Logic operators. <br/><br/> - All JSON Logic Core operators must be definable to run in a worst case Linear Time; ≤ Θ(n).<br/><br/> - Community Extensions may be recognized with operators that exceed this, but they must not be recommended for enablement by default. <br /><br/> - This is not an implementation mandate, rather a guideline for TC and Organization members to select JSON Logic operators in a way that mitigates denial of service attacks when rules are executed from an untrusted source. | https://github.com/orgs/json-logic/discussions/24 | N/A | 3
Arithmetic Operators | - The first proposal of several to evaluate existing operators and define any ambiguous behavior / improve consistency of the operators. <br/><br/> - Defined various `NaN` error states (invalid string coercions, divisions by zero) <br/><br/> - Defined Zero Argument and Single Argument and Variadic behavior for each operator (`+`, `-`, `*`, `/`, `%`) <br/><br/> - The variadic operators are treated as `foldLeft` <br/> <br/> - Defined numeric coercion rules. | https://github.com/orgs/json-logic/discussions/21 | [plus.json](tests/plus.json), [minus.json](tests/minus.json), [multiply.json](tests/multiply.json), [divide.json](tests/divide.json), [modulo.json](tests/modulo.json) | 1
193 changes: 193 additions & 0 deletions tests/divide.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
[
"# Collection of Divide Operator Tests",
{
"description": "Divide",
"rule": { "/": [4, 2] },
"result": 2,
"data": null
},
{
"description": "Divide to Decimal",
"rule": { "/": [2, 4] },
"result": 0.5,
"data": null,
"decimal": true
},
{
"description": "Divide with Multiple Operands",
"rule": { "/": [8, 2, 2] },
"result": 2,
"data": null
},
{
"description": "Divide with Multiple Operands (2)",
"rule": { "/": [2, 2, 1] },
"result": 1,
"data": null
},
{
"description": "Divide with Negative Numbers",
"rule": { "/": [-1, 2] },
"result": -0.5,
"data": null,
"decimal": true
},
{
"description": "Divide with Strings",
"rule": { "/": ["8", "2", "2"] },
"result": 2,
"data": null
},
{
"description": "Divide with Booleans",
"rule": { "/": [false, true] },
"result": 0,
"data": null
},
{
"description": "Divide with Multiple Value Types",
"rule": { "/": ["8", true, 2] },
"result": 4,
"data": null
},
{
"description": "Divide with Multiple Value Types (2)",
"rule": { "/": ["1", 1] },
"result": 1,
"data": null
},
{
"description": "Divide with Single Operand (Number)",
"rule": { "/": [1] },
"result": 1,
"data": null
},
{
"description": "Divide with zero operands is an error",
"rule": { "/": [] },
"error": { "type": "Invalid Arguments" },
"data": null
},
{
"description": "Divide with Single Operand, Direct (Number)",
"rule": { "/": 1 },
"result": 1,
"data": null
},
{
"description": "Divide with Single Operand, Direct (0)",
"rule": { "/": 0 },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide Operator with Single Operand (Number)",
"rule": { "/": [1] },
"result": 1,
"data": null
},
{
"description": "Divide Operator with Single Operand (Negative Number)",
"rule": { "/": [-1] },
"result": -1,
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (Number)",
"rule": { "/": 1 },
"result": 1,
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (2)",
"rule": { "/": 2 },
"result": 0.5,
"decimal": true,
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (0)",
"rule": { "/": 0 },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide Operator with Single Operand (String)",
"rule": { "/": ["1"] },
"result": 1,
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (Negative Number String)",
"rule": { "/": "-1" },
"result": -1,
"data": null
},

{
"description": "Divide Operator with Single Operand, Direct (String 0)",
"rule": { "/": "0" },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (true)",
"rule": { "/": true },
"result": 1,
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (false)",
"rule": { "/": false },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide Operator with Single Operand, Direct (Empty String)",
"rule": { "/": "" },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide Operator with a Single Operand, Direct (null)",
"rule": { "/": null },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide with val",
"rule": { "/": [{ "val": "x" }, { "val": "y" }] },
"data": { "x": 8, "y": 2 },
"result": 4
},
{
"description": "Divide by Zero",
"rule": { "/": [0, 0] },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide with String produces NaN",
"rule": { "/": [1, "a"] },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Divide with Array produces NaN",
"rule": { "/": [1, [1]] },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Any division by zero should return NaN",
"rule": { "/": [1, 0] },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Any division by zero should return NaN (2)",
"rule": { "/": [8, 2, 0] },
"error": { "type": "NaN" },
"data": null
}
]
136 changes: 136 additions & 0 deletions tests/minus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
[
"# Collection of Minus Operator Tests",
{
"description": "Subtraction",
"rule": { "-": [1, 2] },
"result": -1,
"data": null
},
{
"description": "Subtraction (2)",
"rule": { "-": [5, 12] },
"result": -7,
"data": null
},
{
"description": "Subtraction with Multiple Operands",
"rule": { "-": [1, 2, 3, 4] },
"result": -8,
"data": null
},
{
"description": "Subtraction with Negative Numbers",
"rule": { "-": [-1, 0, 5] },
"result": -6,
"data": null
},
{
"description": "Subtraction with Strings",
"rule": { "-": ["1", "2", "3"] },
"result": -4,
"data": null
},
{
"description": "Subtraction with Booleans",
"rule": { "-": [true, false, true] },
"result": 0,
"data": null
},
{
"description": "Subtraction with Multiple Value Types",
"rule": { "-": [1, "2", 3, "4", "", true, false, null] },
"result": -9,
"data": null
},
{
"description": "Minus Operator with Single Operand (Number)",
"rule": { "-": [1] },
"result": -1,
"data": null
},
{
"description": "Minus Operator with Single Operand (Negative Number)",
"rule": { "-": [-1] },
"result": 1,
"data": null
},
{
"description": "Minus with zero operands is an error",
"rule": { "-": [] },
"error": { "type": "Invalid Arguments" },
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (Number)",
"rule": { "-": 1 },
"result": -1,
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (0)",
"rule": { "-": 0 },
"result": 0,
"data": null
},
{
"description": "Minus Operator with Single Operand (String)",
"rule": { "-": ["1"] },
"result": -1,
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (Negative Number String)",
"rule": { "-": "-1" },
"result": 1,
"data": null
},

{
"description": "Minus Operator with Single Operand, Direct (String 0)",
"rule": { "-": "0" },
"result": 0,
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (true)",
"rule": { "-": true },
"result": -1,
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (false)",
"rule": { "-": false },
"result": 0,
"data": null
},
{
"description": "Minus Operator with Single Operand, Direct (Empty String)",
"rule": { "-": "" },
"result": 0,
"data": null
},
{
"description": "Minus Operator with a Single Operand, Direct (null)",
"rule": { "-": null },
"result": 0,
"data": null
},
{
"description": "Subtraction with val",
"rule": { "-": [{ "val": "x" }, { "val": "y" }] },
"data": { "x": 1, "y": 2 },
"result": -1
},
{
"description": "Subtraction with string produces NaN",
"rule": { "-": ["Hey", 1] },
"error": { "type": "NaN" },
"data": null
},
{
"description": "Subtraction with Array produces NaN",
"rule": { "-": [[1], 1] },
"error": { "type": "NaN" },
"data": null
}
]
Loading