Skip to content

Commit 5a74d78

Browse files
committed
Add full compat options with mainline json-logic-js; so that 100% of the checks pass.
1 parent 939c227 commit 5a74d78

11 files changed

+273
-211
lines changed

asyncLogic.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,22 @@ import declareSync from './utilities/declareSync.js'
99
import { buildAsync } from './compiler.js'
1010
import omitUndefined from './utilities/omitUndefined.js'
1111
import { optimize } from './async_optimizer.js'
12+
import { applyPatches } from './compatibility.js'
1213

1314
/**
1415
* An engine capable of running asynchronous JSON Logic.
1516
*/
1617
class AsyncLogicEngine {
1718
/**
19+
* Creates a new instance of the Logic Engine.
20+
*
21+
* "compatible" applies a few patches to make it compatible with the preferences of mainline JSON Logic.
22+
* The main changes are:
23+
* - In mainline: "all" will return false if the array is empty; by default, we return true.
24+
* - In mainline: empty arrays are falsey; in our implementation, they are truthy.
1825
*
1926
* @param {Object} methods An object that stores key-value pairs between the names of the commands & the functions they execute.
20-
* @param {{ disableInline?: Boolean, disableInterpretedOptimization?: boolean, permissive?: boolean }} options
27+
* @param {{ disableInline?: Boolean, disableInterpretedOptimization?: boolean, permissive?: boolean, compatible?: boolean }} options
2128
*/
2229
constructor (
2330
methods = defaultMethods,
@@ -30,6 +37,9 @@ class AsyncLogicEngine {
3037
this.disableInterpretedOptimization = options.disableInterpretedOptimization
3138
this.async = true
3239
this.fallback = new LogicEngine(methods, options)
40+
41+
if (options.compatible) applyPatches(this)
42+
3343
this.optimizedMap = new WeakMap()
3444
this.missesSinceSeen = 0
3545

@@ -41,6 +51,16 @@ class AsyncLogicEngine {
4151
this.fallback.isData = this.isData
4252
}
4353

54+
/**
55+
* Determines the truthiness of a value.
56+
* You can override this method to change the way truthiness is determined.
57+
* @param {*} value
58+
* @returns
59+
*/
60+
truthy (value) {
61+
return value
62+
}
63+
4464
/**
4565
* An internal method used to parse through the JSON Logic at a lower level.
4666
* @param {*} logic The logic being executed.
@@ -189,6 +209,7 @@ class AsyncLogicEngine {
189209
*/
190210
async build (logic, options = {}) {
191211
const { above = [], max = 100, top = true } = options
212+
this.fallback.truthy = this.truthy
192213
if (top) {
193214
const constructedFunction = await buildAsync(logic, {
194215
engine: this,
@@ -237,5 +258,5 @@ class AsyncLogicEngine {
237258
return logic
238259
}
239260
}
240-
261+
Object.assign(AsyncLogicEngine.prototype.truthy, { IDENTITY: true })
241262
export default AsyncLogicEngine

bench/compatible.json

+140
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,40 @@
12681268
2
12691269
]
12701270
],
1271+
[
1272+
{
1273+
"if": []
1274+
},
1275+
null,
1276+
null
1277+
],
1278+
[
1279+
{
1280+
"if": [
1281+
true
1282+
]
1283+
},
1284+
null,
1285+
true
1286+
],
1287+
[
1288+
{
1289+
"if": [
1290+
false
1291+
]
1292+
},
1293+
null,
1294+
false
1295+
],
1296+
[
1297+
{
1298+
"if": [
1299+
"apple"
1300+
]
1301+
},
1302+
null,
1303+
"apple"
1304+
],
12711305
[
12721306
{
12731307
"if": [
@@ -1310,6 +1344,17 @@
13101344
null,
13111345
"banana"
13121346
],
1347+
[
1348+
{
1349+
"if": [
1350+
[],
1351+
"apple",
1352+
"banana"
1353+
]
1354+
},
1355+
null,
1356+
"banana"
1357+
],
13131358
[
13141359
{
13151360
"if": [
@@ -1464,6 +1509,44 @@
14641509
null,
14651510
"apple"
14661511
],
1512+
[
1513+
{
1514+
"!": [
1515+
[]
1516+
]
1517+
},
1518+
{},
1519+
true
1520+
],
1521+
[
1522+
{
1523+
"!!": [
1524+
[]
1525+
]
1526+
},
1527+
{},
1528+
false
1529+
],
1530+
[
1531+
{
1532+
"and": [
1533+
[],
1534+
true
1535+
]
1536+
},
1537+
{},
1538+
[]
1539+
],
1540+
[
1541+
{
1542+
"or": [
1543+
[],
1544+
true
1545+
]
1546+
},
1547+
{},
1548+
true
1549+
],
14671550
[
14681551
{
14691552
"!": [
@@ -2618,6 +2701,21 @@
26182701
"c"
26192702
]
26202703
],
2704+
[
2705+
{
2706+
"if": [
2707+
{
2708+
"missing": "a"
2709+
},
2710+
"missed it",
2711+
"found it"
2712+
]
2713+
},
2714+
{
2715+
"a": "apple"
2716+
},
2717+
"found it"
2718+
],
26212719
[
26222720
{
26232721
"if": [
@@ -3116,6 +3214,27 @@
31163214
},
31173215
false
31183216
],
3217+
[
3218+
{
3219+
"all": [
3220+
{
3221+
"var": "integers"
3222+
},
3223+
{
3224+
"<": [
3225+
{
3226+
"var": ""
3227+
},
3228+
1
3229+
]
3230+
}
3231+
]
3232+
},
3233+
{
3234+
"integers": []
3235+
},
3236+
false
3237+
],
31193238
[
31203239
{
31213240
"all": [
@@ -3206,6 +3325,27 @@
32063325
},
32073326
false
32083327
],
3328+
[
3329+
{
3330+
"all": [
3331+
{
3332+
"var": "items"
3333+
},
3334+
{
3335+
">=": [
3336+
{
3337+
"var": "qty"
3338+
},
3339+
1
3340+
]
3341+
}
3342+
]
3343+
},
3344+
{
3345+
"items": []
3346+
},
3347+
false
3348+
],
32093349
[
32103350
{
32113351
"none": [

bench/incompatible.json

+1-142
Original file line numberDiff line numberDiff line change
@@ -1,142 +1 @@
1-
[
2-
[
3-
{
4-
"if": []
5-
},
6-
null,
7-
null
8-
],
9-
[
10-
{
11-
"if": [
12-
true
13-
]
14-
},
15-
null,
16-
true
17-
],
18-
[
19-
{
20-
"if": [
21-
false
22-
]
23-
},
24-
null,
25-
false
26-
],
27-
[
28-
{
29-
"if": [
30-
"apple"
31-
]
32-
},
33-
null,
34-
"apple"
35-
],
36-
[
37-
{
38-
"if": [
39-
[],
40-
"apple",
41-
"banana"
42-
]
43-
},
44-
null,
45-
"banana"
46-
],
47-
[
48-
{
49-
"!": [
50-
[]
51-
]
52-
},
53-
{},
54-
true
55-
],
56-
[
57-
{
58-
"!!": [
59-
[]
60-
]
61-
},
62-
{},
63-
false
64-
],
65-
[
66-
{
67-
"and": [
68-
[],
69-
true
70-
]
71-
},
72-
{},
73-
[]
74-
],
75-
[
76-
{
77-
"or": [
78-
[],
79-
true
80-
]
81-
},
82-
{},
83-
true
84-
],
85-
[
86-
{
87-
"if": [
88-
{
89-
"missing": "a"
90-
},
91-
"missed it",
92-
"found it"
93-
]
94-
},
95-
{
96-
"a": "apple"
97-
},
98-
"found it"
99-
],
100-
[
101-
{
102-
"all": [
103-
{
104-
"var": "integers"
105-
},
106-
{
107-
"<": [
108-
{
109-
"var": ""
110-
},
111-
1
112-
]
113-
}
114-
]
115-
},
116-
{
117-
"integers": []
118-
},
119-
false
120-
],
121-
[
122-
{
123-
"all": [
124-
{
125-
"var": "items"
126-
},
127-
{
128-
">=": [
129-
{
130-
"var": "qty"
131-
},
132-
1
133-
]
134-
}
135-
]
136-
},
137-
{
138-
"items": []
139-
},
140-
false
141-
]
142-
]
1+
[]

0 commit comments

Comments
 (0)