@legalplace/lplogic 2.3.1 → 2.3.2-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-automator +7 -0
- package/.gitlab-ci.yml +1 -0
- package/.vscode/settings.json +4 -5
- package/dist/LpLogic.js +148 -35
- package/dist/Parser.js +6 -6
- package/dist/definitions/model-v1-schema.d.ts +4 -4
- package/jest.config.js +9 -12
- package/package.json +12 -9
- package/tests/LpLogic.test.ts +266 -27
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
GITLAB_PRIVATE_TOKEN=glpat-BOv5W1i6MoAAvHjzkmc5nW86MQp1OjkH.01.0w119catf
|
|
2
|
+
GITLAB_BASE_URL=https://git.legalplace.eu
|
|
3
|
+
GITLAB_API_PROJECT_ID=28
|
|
4
|
+
GITLAB_USER_ID=9
|
|
5
|
+
CURRENT_PROJECT_ID=39
|
|
6
|
+
SLACK_USER_ID=U0B3SNBV3
|
|
7
|
+
CLICKUP_PRIVATE_TOKEN=pk_32519579_K5W4L4KEVXY03A3D2WFA46D07HVGTL5L
|
package/.gitlab-ci.yml
CHANGED
package/.vscode/settings.json
CHANGED
|
@@ -14,10 +14,9 @@
|
|
|
14
14
|
"files.autoSave": "onFocusChange",
|
|
15
15
|
"editor.formatOnSave": false,
|
|
16
16
|
"editor.formatOnType": true,
|
|
17
|
-
"prettier.singleQuote": true,
|
|
18
|
-
"eslint.packageManager": "yarn",
|
|
19
17
|
"eslint.quiet": true,
|
|
20
18
|
"editor.codeActionsOnSave": {
|
|
21
|
-
"source.fixAll.eslint":
|
|
22
|
-
}
|
|
23
|
-
|
|
19
|
+
"source.fixAll.eslint": "explicit"
|
|
20
|
+
},
|
|
21
|
+
"typescript.tsdk": "node_modules/typescript/lib"
|
|
22
|
+
}
|
package/dist/LpLogic.js
CHANGED
|
@@ -6,9 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
var json_logic_js_1 = __importDefault(require("@legalplace/json-logic-js"));
|
|
7
7
|
var reduceParents = function (parents, length) {
|
|
8
8
|
var reducedParents = [];
|
|
9
|
-
parents.
|
|
9
|
+
var safeParents = parents.filter(function (entry) { return Array.isArray(entry); });
|
|
10
|
+
safeParents.sort(function (a, b) { return b.length - a.length; });
|
|
10
11
|
var _loop_1 = function (index) {
|
|
11
|
-
var currentIndexResult =
|
|
12
|
+
var currentIndexResult = safeParents.reduce(function (previousValue, currentValue) {
|
|
12
13
|
if (currentValue.length === 1)
|
|
13
14
|
return previousValue && currentValue[0];
|
|
14
15
|
if (currentValue[index] === undefined)
|
|
@@ -23,7 +24,7 @@ var reduceParents = function (parents, length) {
|
|
|
23
24
|
return reducedParents;
|
|
24
25
|
};
|
|
25
26
|
var reduceValues = function (values, parents, compareFunction) {
|
|
26
|
-
if (parents
|
|
27
|
+
if (!Array.isArray(parents) || parents.length === 0) {
|
|
27
28
|
return values.map(function (currentValue) {
|
|
28
29
|
return compareFunction(currentValue, true);
|
|
29
30
|
});
|
|
@@ -40,10 +41,25 @@ var parseNumber = function (value) {
|
|
|
40
41
|
return parseFloat(value.replace(",", "."));
|
|
41
42
|
return value;
|
|
42
43
|
};
|
|
44
|
+
var cleanString = function (value) {
|
|
45
|
+
var raw = typeof value === "number" ? value.toString() : value.trim();
|
|
46
|
+
return raw
|
|
47
|
+
.normalize("NFD")
|
|
48
|
+
.replace(/[\u0300-\u036f]/g, "")
|
|
49
|
+
.replace(/œ/g, "oe")
|
|
50
|
+
.replace(/Œ/g, "oe")
|
|
51
|
+
.replace(/æ/g, "ae")
|
|
52
|
+
.replace(/Æ/g, "ae")
|
|
53
|
+
.toLowerCase();
|
|
54
|
+
};
|
|
43
55
|
var safeEqual = function (value, comparator) {
|
|
44
56
|
var parsedValue = typeof value === "number" ? value : parseNumber(value);
|
|
45
57
|
var parsedComparator = typeof comparator === "number" ? comparator : parseNumber(comparator);
|
|
46
|
-
|
|
58
|
+
if (typeof parsedValue === "number" &&
|
|
59
|
+
typeof parsedComparator === "number") {
|
|
60
|
+
return parsedValue === parsedComparator;
|
|
61
|
+
}
|
|
62
|
+
return cleanString(value) === cleanString(comparator);
|
|
47
63
|
};
|
|
48
64
|
json_logic_js_1.default.add_operation("=", function (values, comparator, parents) {
|
|
49
65
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
@@ -129,34 +145,44 @@ json_logic_js_1.default.add_operation("has-many", function (values, comparator,
|
|
|
129
145
|
});
|
|
130
146
|
var is = function (values, comparator, parents) {
|
|
131
147
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
132
|
-
|
|
133
|
-
? value.toString()
|
|
134
|
-
: value.trim()).toLowerCase();
|
|
135
|
-
var cleanComparator = (typeof comparator === "number"
|
|
136
|
-
? comparator.toString()
|
|
137
|
-
: comparator.trim()).toLowerCase();
|
|
138
|
-
return cleanValue === cleanComparator && parent;
|
|
148
|
+
return cleanString(value) === cleanString(comparator) && parent;
|
|
139
149
|
});
|
|
140
150
|
var filter = reducedValues.filter(function (_value) { return _value === true; });
|
|
141
151
|
return reducedValues.length === filter.length;
|
|
142
152
|
};
|
|
143
153
|
json_logic_js_1.default.add_operation("is", is);
|
|
144
|
-
json_logic_js_1.default.add_operation("contains", is);
|
|
145
154
|
var not = function (values, comparator, parents) {
|
|
146
155
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
147
|
-
|
|
148
|
-
? value.toString()
|
|
149
|
-
: value.trim()).toLowerCase();
|
|
150
|
-
var cleanComparator = (typeof comparator === "number"
|
|
151
|
-
? comparator.toString()
|
|
152
|
-
: comparator.trim()).toLowerCase();
|
|
153
|
-
return cleanValue !== cleanComparator && parent;
|
|
156
|
+
return cleanString(value) !== cleanString(comparator) && parent;
|
|
154
157
|
});
|
|
155
158
|
var filter = reducedValues.filter(function (_value) { return _value === true; });
|
|
156
159
|
return reducedValues.length === filter.length;
|
|
157
160
|
};
|
|
158
161
|
json_logic_js_1.default.add_operation("not", not);
|
|
159
|
-
|
|
162
|
+
var contains = function (values, comparator, parents) {
|
|
163
|
+
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
164
|
+
if (Array.isArray(value)) {
|
|
165
|
+
return (value.some(function (val) {
|
|
166
|
+
return cleanString(val).includes(cleanString(comparator));
|
|
167
|
+
}) && parent);
|
|
168
|
+
}
|
|
169
|
+
return (cleanString(value).includes(cleanString(comparator)) && parent);
|
|
170
|
+
});
|
|
171
|
+
var filter = reducedValues.filter(function (value) { return value === true; });
|
|
172
|
+
return reducedValues.length === filter.length;
|
|
173
|
+
};
|
|
174
|
+
json_logic_js_1.default.add_operation("contains", contains);
|
|
175
|
+
var doesNotContain = function (values, comparator, parents) {
|
|
176
|
+
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
177
|
+
if (Array.isArray(value)) {
|
|
178
|
+
return (value.every(function (val) { return !cleanString(val).includes(cleanString(comparator)); }) && parent);
|
|
179
|
+
}
|
|
180
|
+
return (!cleanString(value).includes(cleanString(comparator)) && parent);
|
|
181
|
+
});
|
|
182
|
+
var filter = reducedValues.filter(function (value) { return value === true; });
|
|
183
|
+
return reducedValues.length === filter.length;
|
|
184
|
+
};
|
|
185
|
+
json_logic_js_1.default.add_operation("does-not-contain", doesNotContain);
|
|
160
186
|
json_logic_js_1.default.add_operation("empty", function (values, comparator, parents) {
|
|
161
187
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
162
188
|
var stringValue = typeof value === "number" ? value.toString() : value;
|
|
@@ -175,13 +201,7 @@ json_logic_js_1.default.add_operation("not-empty", function (values, comparator,
|
|
|
175
201
|
});
|
|
176
202
|
var like = function (values, comparator, parents) {
|
|
177
203
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
178
|
-
|
|
179
|
-
? value.toString()
|
|
180
|
-
: value.trim()).toLowerCase();
|
|
181
|
-
var cleanComparator = (typeof comparator === "number"
|
|
182
|
-
? comparator.toString()
|
|
183
|
-
: comparator.trim()).toLowerCase();
|
|
184
|
-
return (new RegExp("( |^)" + cleanComparator + "( |$)", "i").test(cleanValue) && parent);
|
|
204
|
+
return (new RegExp("( |^)".concat(cleanString(comparator), "( |$)"), "i").test(cleanString(value)) && parent);
|
|
185
205
|
});
|
|
186
206
|
var filter = reducedValues.filter(function (_value) { return _value === true; });
|
|
187
207
|
return reducedValues.length === filter.length;
|
|
@@ -189,14 +209,7 @@ var like = function (values, comparator, parents) {
|
|
|
189
209
|
json_logic_js_1.default.add_operation("like", like);
|
|
190
210
|
var notLike = function (values, comparator, parents) {
|
|
191
211
|
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
192
|
-
|
|
193
|
-
? value.toString()
|
|
194
|
-
: value.trim()).toLowerCase();
|
|
195
|
-
var cleanComparator = (typeof comparator === "number"
|
|
196
|
-
? comparator.toString()
|
|
197
|
-
: comparator.trim()).toLowerCase();
|
|
198
|
-
return (!new RegExp("( |^)" + cleanComparator + "( |$)", "i").test(cleanValue) &&
|
|
199
|
-
parent);
|
|
212
|
+
return (!new RegExp("( |^)".concat(cleanString(comparator), "( |$)"), "i").test(cleanString(value)) && parent);
|
|
200
213
|
});
|
|
201
214
|
var filter = reducedValues.filter(function (_value) { return _value === true; });
|
|
202
215
|
return reducedValues.length === filter.length;
|
|
@@ -226,5 +239,105 @@ var regexMatch = function (values, comparator, parents) {
|
|
|
226
239
|
return reducedValues.length === filter.length;
|
|
227
240
|
};
|
|
228
241
|
json_logic_js_1.default.add_operation("regex-match", regexMatch);
|
|
242
|
+
var aggregateAny = function (reducedValues) {
|
|
243
|
+
return reducedValues.includes(true);
|
|
244
|
+
};
|
|
245
|
+
var aggregateFirst = function (reducedValues) {
|
|
246
|
+
return reducedValues[0] === true;
|
|
247
|
+
};
|
|
248
|
+
var registerScopedBooleanOp = function (baseName, compareFn) {
|
|
249
|
+
json_logic_js_1.default.add_operation("".concat(baseName, "-first"), function (values, _comparator, parents) {
|
|
250
|
+
var reducedValue = reduceValues(values, parents, compareFn);
|
|
251
|
+
return aggregateFirst(reducedValue);
|
|
252
|
+
});
|
|
253
|
+
json_logic_js_1.default.add_operation("".concat(baseName, "-any"), function (values, _comparator, parents) {
|
|
254
|
+
var reducedValue = reduceValues(values, parents, compareFn);
|
|
255
|
+
return aggregateAny(reducedValue);
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
registerScopedBooleanOp("selected", function (value, parent) { return value && parent; });
|
|
259
|
+
registerScopedBooleanOp("not-selected", function (value, parent) { return !value && parent; });
|
|
260
|
+
var conditionMet = function (value, parent) {
|
|
261
|
+
return value === true && parent;
|
|
262
|
+
};
|
|
263
|
+
var conditionNotMet = function (value, parent) {
|
|
264
|
+
return value !== true && parent;
|
|
265
|
+
};
|
|
266
|
+
json_logic_js_1.default.add_operation("conditions-met", function (values, comparator, parents) {
|
|
267
|
+
return reduceValues(values, parents, conditionMet).every(function (value) { return value === true; });
|
|
268
|
+
});
|
|
269
|
+
json_logic_js_1.default.add_operation("conditions-not-met", function (values, comparator, parents) {
|
|
270
|
+
return reduceValues(values, parents, conditionNotMet).every(function (value) { return value === true; });
|
|
271
|
+
});
|
|
272
|
+
registerScopedBooleanOp("conditions-met", conditionMet);
|
|
273
|
+
registerScopedBooleanOp("conditions-not-met", conditionNotMet);
|
|
274
|
+
var registerScopedComparisonOp = function (baseName, compareFn) {
|
|
275
|
+
json_logic_js_1.default.add_operation("".concat(baseName, "-any"), function (values, comparator, parents) {
|
|
276
|
+
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
277
|
+
return compareFn(value, comparator, parent);
|
|
278
|
+
});
|
|
279
|
+
return aggregateAny(reducedValues);
|
|
280
|
+
});
|
|
281
|
+
json_logic_js_1.default.add_operation("".concat(baseName, "-first"), function (values, comparator, parents) {
|
|
282
|
+
var reducedValues = reduceValues(values, parents, function (value, parent) {
|
|
283
|
+
return compareFn(value, comparator, parent);
|
|
284
|
+
});
|
|
285
|
+
return aggregateFirst(reducedValues);
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
registerScopedComparisonOp("=", function (value, comparator, parent) {
|
|
289
|
+
return safeEqual(value, comparator) && parent;
|
|
290
|
+
});
|
|
291
|
+
registerScopedComparisonOp("<>", function (value, comparator, parent) {
|
|
292
|
+
return !safeEqual(value, comparator) && parent;
|
|
293
|
+
});
|
|
294
|
+
registerScopedComparisonOp("==", function (value, comparator, parent) {
|
|
295
|
+
return parseNumber(value) === parseNumber(comparator) && parent;
|
|
296
|
+
});
|
|
297
|
+
registerScopedComparisonOp(">=", function (value, comparator, parent) {
|
|
298
|
+
return parseNumber(value) >= parseNumber(comparator) && parent;
|
|
299
|
+
});
|
|
300
|
+
registerScopedComparisonOp("<=", function (value, comparator, parent) {
|
|
301
|
+
return parseNumber(value) <= parseNumber(comparator) && parent;
|
|
302
|
+
});
|
|
303
|
+
registerScopedComparisonOp(">", function (value, comparator, parent) {
|
|
304
|
+
return parseNumber(value) > parseNumber(comparator) && parent;
|
|
305
|
+
});
|
|
306
|
+
registerScopedComparisonOp("<", function (value, comparator, parent) {
|
|
307
|
+
return parseNumber(value) < parseNumber(comparator) && parent;
|
|
308
|
+
});
|
|
309
|
+
registerScopedComparisonOp("is", function (value, comparator, parent) {
|
|
310
|
+
return cleanString(value) === cleanString(comparator) && parent;
|
|
311
|
+
});
|
|
312
|
+
registerScopedComparisonOp("not", function (value, comparator, parent) {
|
|
313
|
+
return cleanString(value) !== cleanString(comparator) && parent;
|
|
314
|
+
});
|
|
315
|
+
registerScopedComparisonOp("contains", function (value, comparator, parent) {
|
|
316
|
+
return cleanString(value).includes(cleanString(comparator)) && parent;
|
|
317
|
+
});
|
|
318
|
+
registerScopedComparisonOp("does-not-contain", function (value, comparator, parent) {
|
|
319
|
+
return !cleanString(value).includes(cleanString(comparator)) && parent;
|
|
320
|
+
});
|
|
321
|
+
registerScopedComparisonOp("like", function (value, comparator, parent) {
|
|
322
|
+
return new RegExp("( |^)".concat(cleanString(comparator), "( |$)"), "i").test(cleanString(value)) && parent;
|
|
323
|
+
});
|
|
324
|
+
registerScopedComparisonOp("not-like", function (value, comparator, parent) {
|
|
325
|
+
return !new RegExp("( |^)".concat(cleanString(comparator), "( |$)"), "i").test(cleanString(value)) && parent;
|
|
326
|
+
});
|
|
327
|
+
registerScopedComparisonOp("regex-match", function (value, comparator, parent) {
|
|
328
|
+
if (typeof comparator !== "string")
|
|
329
|
+
return false;
|
|
330
|
+
var regex;
|
|
331
|
+
try {
|
|
332
|
+
regex = new RegExp(comparator);
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
var stringValue = typeof value === "number" ? value.toString() : value;
|
|
338
|
+
return regex.test(stringValue) && parent;
|
|
339
|
+
});
|
|
340
|
+
registerScopedComparisonOp("empty", function (value, _comparator, parent) { return cleanString(value).length === 0 && parent; });
|
|
341
|
+
registerScopedComparisonOp("not-empty", function (value, _comparator, parent) { return cleanString(value).length > 0 && parent; });
|
|
229
342
|
var LpLogic = json_logic_js_1.default.apply;
|
|
230
343
|
exports.default = LpLogic;
|
package/dist/Parser.js
CHANGED
|
@@ -16,7 +16,7 @@ var Parser = (function () {
|
|
|
16
16
|
Parser.prototype.validateCondition = function (condition) {
|
|
17
17
|
var result = (0, jsonschema_1.validate)(condition, condition_v1_schema_1.default);
|
|
18
18
|
if (result.errors.length > 0) {
|
|
19
|
-
throw new Error(JSON.stringify(condition)
|
|
19
|
+
throw new Error("".concat(JSON.stringify(condition), " is not a valid condition"));
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
22
|
Parser.prototype.convertConditions = function (conditions) {
|
|
@@ -31,7 +31,7 @@ var Parser = (function () {
|
|
|
31
31
|
operator = value.t;
|
|
32
32
|
}
|
|
33
33
|
else if (value.t !== operator) {
|
|
34
|
-
throw new Error("Conditions object is not valid, "
|
|
34
|
+
throw new Error("Conditions object is not valid, ".concat(operator, " is not equal to ").concat(value.t, " at index ").concat(index, " in ").concat(JSON.stringify(conditions)));
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -57,7 +57,7 @@ var Parser = (function () {
|
|
|
57
57
|
logic = logicConditions[0];
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
|
-
throw new Error("Invalid condition "
|
|
60
|
+
throw new Error("Invalid condition ".concat(conditions));
|
|
61
61
|
}
|
|
62
62
|
return logic;
|
|
63
63
|
};
|
|
@@ -70,18 +70,18 @@ var Parser = (function () {
|
|
|
70
70
|
var dataReference;
|
|
71
71
|
if (condition.o !== false && condition.o !== undefined) {
|
|
72
72
|
dataReference = {
|
|
73
|
-
var: "o."
|
|
73
|
+
var: "o.".concat(condition.o)
|
|
74
74
|
};
|
|
75
75
|
rule[operation] = [dataReference];
|
|
76
76
|
}
|
|
77
77
|
else if (condition.v !== false && condition.v !== undefined) {
|
|
78
78
|
dataReference = {
|
|
79
|
-
var: "v."
|
|
79
|
+
var: "v.".concat(condition.v)
|
|
80
80
|
};
|
|
81
81
|
rule[operation] = [dataReference, condition.value];
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
|
-
throw new Error("Invalid condition "
|
|
84
|
+
throw new Error("Invalid condition ".concat(condition));
|
|
85
85
|
}
|
|
86
86
|
return rule;
|
|
87
87
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type ConditionV1Single = {
|
|
2
2
|
c?: "selected" | "not-selected" | "has-one" | "at-least-one" | "has-many" | "contains" | "does-not-contain" | "=" | ">" | "<" | "!=" | ">=" | "<=" | "<>";
|
|
3
3
|
o?: false | number | string;
|
|
4
4
|
p?: string | number;
|
|
@@ -8,11 +8,11 @@ export declare type ConditionV1Single = {
|
|
|
8
8
|
m?: boolean;
|
|
9
9
|
t?: "and" | "or";
|
|
10
10
|
};
|
|
11
|
-
export
|
|
11
|
+
export type ConditionV1Array = {
|
|
12
12
|
condition_array?: ConditionV1Compose[];
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
export
|
|
14
|
+
type ConditionV1Compose = ConditionV1Array & ConditionV1Single;
|
|
15
|
+
export type CompiledConditionV1 = ConditionV1Compose[];
|
|
16
16
|
export interface ModelV1 {
|
|
17
17
|
contract_name: string;
|
|
18
18
|
sections: SectionV1[];
|
package/jest.config.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
2
|
+
roots: [
|
|
3
|
+
"./tests"
|
|
4
|
+
],
|
|
5
|
+
transform: {
|
|
6
|
+
"^.+\\.tsx?$": ['ts-jest', {
|
|
7
|
+
tsconfig: "tsconfig.json"
|
|
8
|
+
}],
|
|
9
|
+
},
|
|
10
|
+
};
|
package/package.json
CHANGED
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@legalplace/lplogic",
|
|
3
|
-
"version": "2.3.1",
|
|
3
|
+
"version": "2.3.2-staging.1",
|
|
4
4
|
"description": "LegalPlace LpLogic",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "
|
|
8
|
-
"build": "
|
|
7
|
+
"test": "jest",
|
|
8
|
+
"build": "tsc",
|
|
9
9
|
"release": "standard-version -a --no-verify"
|
|
10
10
|
},
|
|
11
11
|
"outDir": "./dist",
|
|
12
12
|
"author": "Moncef Hammou <moncef@legalplace.fr>",
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@legalplace/models-v3-types": "5.1.24",
|
|
16
15
|
"@legalplace/json-logic-js": "^1.2.3",
|
|
16
|
+
"@legalplace/models-v3-types": "5.1.24",
|
|
17
17
|
"jsonschema": "^1.2.4"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@babel/core": "^7.7.2",
|
|
21
21
|
"@babel/preset-typescript": "^7.7.2",
|
|
22
|
+
"@commitlint/cli": "^9.0.1",
|
|
23
|
+
"@commitlint/config-conventional": "^9.0.1",
|
|
24
|
+
"@types/jest": "^29.5.14",
|
|
22
25
|
"@types/node": "^12.12.6",
|
|
23
26
|
"@typescript-eslint/eslint-plugin": "^2.6.1",
|
|
24
27
|
"@typescript-eslint/parser": "^2.6.1",
|
|
@@ -26,12 +29,12 @@
|
|
|
26
29
|
"eslint": "^6.6.0",
|
|
27
30
|
"eslint-config-airbnb-base": "^14.0.0",
|
|
28
31
|
"eslint-plugin-import": "^2.18.2",
|
|
29
|
-
"typescript": "4.4.3",
|
|
30
|
-
"semantic-release": "^17.1.1",
|
|
31
32
|
"husky": "^4.2.5",
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"standard-version": "^8.0.0"
|
|
33
|
+
"jest": "^29.7.0",
|
|
34
|
+
"semantic-release": "^17.1.1",
|
|
35
|
+
"standard-version": "^8.0.0",
|
|
36
|
+
"ts-jest": "^29.2.5",
|
|
37
|
+
"typescript": "5.6.3"
|
|
35
38
|
},
|
|
36
39
|
"husky": {
|
|
37
40
|
"hooks": {
|
package/tests/LpLogic.test.ts
CHANGED
|
@@ -1,131 +1,370 @@
|
|
|
1
1
|
import LpLogic from "../lib/index"
|
|
2
2
|
|
|
3
3
|
test('Testing "selected" operator on a boolean `true`', async () => {
|
|
4
|
-
|
|
4
|
+
expect(LpLogic({"selected":[{"var":"o.1"}]}, {"o":{"1":[true]}})).toBe(true)
|
|
5
5
|
})
|
|
6
6
|
|
|
7
7
|
test('Testing "selected" operator on an array of boolean `true`', async () => {
|
|
8
|
-
|
|
8
|
+
expect(LpLogic({"selected":[{"var":"o.1"}]}, {"o":{"1":[true, true]}})).toBe(true)
|
|
9
9
|
})
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
test('Testing "selected" operator on an array of boolean `false`', async () => {
|
|
13
|
-
|
|
13
|
+
expect(LpLogic({"selected":[{"var":"o.1"}]}, {"o":{"1":[false]}})).toBe(false)
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
test('Testing "selected" operator on an array containing a boolean `false`', async () => {
|
|
17
|
-
|
|
17
|
+
expect(LpLogic({"selected":[{"var":"o.1"}]}, {"o":{"1":[true, false]}})).toBe(false)
|
|
18
18
|
})
|
|
19
19
|
|
|
20
20
|
test('Testing "not-selected" operator on a boolean `false`', async () => {
|
|
21
|
-
|
|
21
|
+
expect(LpLogic({"not-selected":[{"var":"o.1"}]}, {"o":{"1":[false]}})).toBe(true)
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
test('Testing "not-selected" operator on an array of boolean `false`', async () => {
|
|
25
|
-
|
|
25
|
+
expect(LpLogic({"not-selected":[{"var":"o.1"}]}, {"o":{"1":[false, false]}})).toBe(true)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
// Returns false
|
|
29
29
|
|
|
30
30
|
test('Testing "not-selected" operator on a boolean `true`', async () => {
|
|
31
|
-
|
|
31
|
+
expect( LpLogic({"not-selected":[{"var":"o.1"}]}, {"o":{"1":[true]}}) ).toBe(false)
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
test('Testing "not-selected" operator on an array containing a boolean `true`', async () => {
|
|
35
|
-
|
|
35
|
+
expect( LpLogic({"not-selected":[{"var":"o.1"}]}, {"o":{"1":[true, false]}}) ).toBe(false)
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
// Returns true
|
|
39
39
|
test('Testing "has-one" on an array of one element', async () => {
|
|
40
|
-
|
|
40
|
+
expect(LpLogic({"has-one":[{"var":"o.1"}]}, {"o":{"1":[true]}})).toBe(true)
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
// Returns false
|
|
44
44
|
test('Testing "has-one" on an array of two elements', async () => {
|
|
45
|
-
|
|
45
|
+
expect( LpLogic({"has-one":[{"var":"o.1"}]}, {"o":{"1":[true, true]}}) ).toBe(false)
|
|
46
46
|
})
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
// Returns true
|
|
50
50
|
test('Testing "has-many" on an array of two elements', async () => {
|
|
51
|
-
|
|
51
|
+
expect( LpLogic({"has-many":[{"var":"o.1"}]}, {"o":{"1":[true, true]}}) ).toBe(true)
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
// Returns false
|
|
56
56
|
test('Testing "has-many" on an array of one element', async () => {
|
|
57
|
-
|
|
57
|
+
expect( LpLogic({"has-many":[{"var":"o.1"}]}, {"o":{"1":[true]}}) ).toBe(false)
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
// Returns true
|
|
61
61
|
test('Testing "at-least-one" on a array of three elements with one as true', async () => {
|
|
62
|
-
|
|
62
|
+
expect( LpLogic({"at-least-one":[{"var":"o.1"}]}, {"o":{"1":[false, false, true]}}) ).toBe(true)
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
// Returns false
|
|
66
66
|
test('Testing "at-least-one" on an array of three elements with all elements as false', async () => {
|
|
67
|
-
|
|
67
|
+
expect( LpLogic({"at-least-one":[{"var":"o.1"}]}, {"o":{"1":[false, false, false]}}) ).toBe(false)
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
// Returns true
|
|
72
72
|
test('Testing "contains" Hello on a value `Hello`', async () => {
|
|
73
|
-
|
|
73
|
+
expect( LpLogic({"contains":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Hello"]}}) ).toBe(true)
|
|
74
74
|
})
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
// Returns false
|
|
78
78
|
test('Testing "contains" Hello on a value `Bye`', async () => {
|
|
79
|
-
|
|
79
|
+
expect( LpLogic({"contains":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Bye"]}}) ).toBe(false)
|
|
80
80
|
})
|
|
81
81
|
|
|
82
82
|
// Returns true
|
|
83
83
|
test('Testing "is" Hello on a value `Hello`', async () => {
|
|
84
|
-
|
|
84
|
+
expect( LpLogic({"is":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Hello"]}}) ).toBe(true)
|
|
85
85
|
})
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
// Returns false
|
|
89
89
|
test('Testing "is" Hello on a value `Bye`', async () => {
|
|
90
|
-
|
|
90
|
+
expect( LpLogic({"is":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Bye"]}}) ).toBe(false)
|
|
91
91
|
})
|
|
92
92
|
|
|
93
93
|
// Returns true
|
|
94
94
|
test('Testing "does-not-contain" Hello on a value `Bye`', async () => {
|
|
95
|
-
|
|
95
|
+
expect( LpLogic({"does-not-contain":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Bye"]}}) ).toBe(true)
|
|
96
96
|
})
|
|
97
97
|
|
|
98
98
|
// Returns false
|
|
99
99
|
test('Testing "does-not-contain" Hello on a value `Hello`', async () => {
|
|
100
|
-
|
|
100
|
+
expect( LpLogic({"does-not-contain":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Hello"]}}) ).toBe(false)
|
|
101
101
|
})
|
|
102
102
|
|
|
103
103
|
// Returns true
|
|
104
104
|
test('Testing "not" Hello on a value `Bye`', async () => {
|
|
105
|
-
|
|
105
|
+
expect( LpLogic({"not":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Bye"]}}) ).toBe(true)
|
|
106
106
|
})
|
|
107
107
|
|
|
108
108
|
// Returns false
|
|
109
109
|
test('Testing "not" Hello on a value `Hello`', async () => {
|
|
110
|
-
|
|
110
|
+
expect( LpLogic({"not":[{"var":"v.1"}, "Hello"]}, {"v":{"1":["Hello"]}}) ).toBe(false)
|
|
111
111
|
})
|
|
112
112
|
|
|
113
113
|
// Returns true
|
|
114
114
|
test('Testing "like" World on a value `Hello world`', async () => {
|
|
115
|
-
|
|
115
|
+
expect( LpLogic({"like":[{"var":"v.1"}, "World"]}, {"v":{"1":["Hello world"]}}) ).toBe(true)
|
|
116
116
|
})
|
|
117
117
|
|
|
118
118
|
// Returns false
|
|
119
119
|
test('Testing "like" Bye on a value `Hello world`', async () => {
|
|
120
|
-
|
|
120
|
+
expect( LpLogic({"like":[{"var":"v.1"}, "Bye"]}, {"v":{"1":["Hello world"]}}) ).toBe(false)
|
|
121
121
|
})
|
|
122
122
|
|
|
123
123
|
// Returns true
|
|
124
124
|
test('Testing "not-like" Bye on a value `Hello world`', async () => {
|
|
125
|
-
|
|
125
|
+
expect( LpLogic({"not-like":[{"var":"v.1"}, "Bye"]}, {"v":{"1":["Hello world"]}}) ).toBe(true)
|
|
126
126
|
})
|
|
127
127
|
|
|
128
128
|
// Returns false
|
|
129
129
|
test('Testing "not-like" World on a value `Hello world`', async () => {
|
|
130
|
-
|
|
131
|
-
})
|
|
130
|
+
expect( LpLogic({"not-like":[{"var":"v.1"}, "World"]}, {"v":{"1":["Hello world"]}}) ).toBe(false)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('Testing "selected-first" on first occurrence only', async () => {
|
|
134
|
+
expect(LpLogic({"selected-first":[{"var":"o.1"}]}, {"o":{"1":[true, false]}})).toBe(true)
|
|
135
|
+
expect(LpLogic({"selected-first":[{"var":"o.1"}]}, {"o":{"1":[false, true]}})).toBe(false)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('Testing "=-any" on multiple values', async () => {
|
|
139
|
+
expect(LpLogic({"=-any":[{"var":"v.1"}, "a"]}, {"v":{"1":["a", "b"]}})).toBe(true)
|
|
140
|
+
expect(LpLogic({"=-any":[{"var":"v.1"}, "a"]}, {"v":{"1":["b", "c"]}})).toBe(false)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* empty-any / not-empty-any cover occurrence scope "at least one" for emptiness checks.
|
|
145
|
+
*/
|
|
146
|
+
test('Testing "empty-any" on multiple values', async () => {
|
|
147
|
+
expect(LpLogic({"empty-any":[{"var":"v.1"}]}, {"v":{"1":["", "x"]}})).toBe(true)
|
|
148
|
+
expect(LpLogic({"empty-any":[{"var":"v.1"}]}, {"v":{"1":["x", "y"]}})).toBe(false)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test('Testing "empty-first" on multiple values', async () => {
|
|
152
|
+
expect(LpLogic({"empty-first":[{"var":"v.1"}]}, {"v":{"1":["", "x"]}})).toBe(true)
|
|
153
|
+
expect(LpLogic({"empty-first":[{"var":"v.1"}]}, {"v":{"1":["x", ""]}})).toBe(false)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test('Testing "not-empty-any" on multiple values', async () => {
|
|
157
|
+
expect(LpLogic({"not-empty-any":[{"var":"v.1"}]}, {"v":{"1":["", "x"]}})).toBe(true)
|
|
158
|
+
expect(LpLogic({"not-empty-any":[{"var":"v.1"}]}, {"v":{"1":["", ""]}})).toBe(false)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
test('Testing "=-first" on multiple values', async () => {
|
|
162
|
+
expect(LpLogic({"=-first":[{"var":"v.1"}, "a"]}, {"v":{"1":["a", "b"]}})).toBe(true)
|
|
163
|
+
expect(LpLogic({"=-first":[{"var":"v.1"}, "a"]}, {"v":{"1":["b", "a"]}})).toBe(false)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('Testing "conditions-met" without parents', async () => {
|
|
167
|
+
expect(
|
|
168
|
+
LpLogic({"conditions-met":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[true, true]}}})
|
|
169
|
+
).toBe(true)
|
|
170
|
+
expect(
|
|
171
|
+
LpLogic({"conditions-met":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[true, false]}}})
|
|
172
|
+
).toBe(false)
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
test('Testing "conditions-met" with parents', async () => {
|
|
176
|
+
expect(
|
|
177
|
+
LpLogic(
|
|
178
|
+
{"conditions-met":[{"var":"c.o.2"}, undefined, [{"var":"o.1"}]]},
|
|
179
|
+
{"c":{"o":{"2":[true, true]}}, "o":{"1":[true, true]}}
|
|
180
|
+
)
|
|
181
|
+
).toBe(true)
|
|
182
|
+
expect(
|
|
183
|
+
LpLogic(
|
|
184
|
+
{"conditions-met":[{"var":"c.o.2"}, undefined, [{"var":"o.1"}]]},
|
|
185
|
+
{"c":{"o":{"2":[true, true]}}, "o":{"1":[true, false]}}
|
|
186
|
+
)
|
|
187
|
+
).toBe(false)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
test('Testing "conditions-met-first" on first occurrence only', async () => {
|
|
191
|
+
expect(
|
|
192
|
+
LpLogic({"conditions-met-first":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[true, false]}}})
|
|
193
|
+
).toBe(true)
|
|
194
|
+
expect(
|
|
195
|
+
LpLogic({"conditions-met-first":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[false, true]}}})
|
|
196
|
+
).toBe(false)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test('Testing "conditions-met-any" on multiple values', async () => {
|
|
200
|
+
expect(
|
|
201
|
+
LpLogic({"conditions-met-any":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[false, true]}}})
|
|
202
|
+
).toBe(true)
|
|
203
|
+
expect(
|
|
204
|
+
LpLogic({"conditions-met-any":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[false, false]}}})
|
|
205
|
+
).toBe(false)
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
test('Testing "conditions-not-met"', async () => {
|
|
209
|
+
expect(
|
|
210
|
+
LpLogic({"conditions-not-met":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[false, false]}}})
|
|
211
|
+
).toBe(true)
|
|
212
|
+
expect(
|
|
213
|
+
LpLogic({"conditions-not-met":[{"var":"c.o.1"}]}, {"c":{"o":{"1":[true, false]}}})
|
|
214
|
+
).toBe(false)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Regression: when a condition tree containing `undefined` parents is passed
|
|
219
|
+
* through any JSON serialization (e.g. Redux DevTools), `undefined` becomes
|
|
220
|
+
* `null` (`JSON.stringify([a, undefined])` → `'[a,null]'`). LpLogic must
|
|
221
|
+
* treat a `null` parents arg as "no parents" instead of throwing on
|
|
222
|
+
* `null.length`.
|
|
223
|
+
*/
|
|
224
|
+
test('Testing "conditions-met" with null parents (JSON round-trip safety)', async () => {
|
|
225
|
+
expect(
|
|
226
|
+
LpLogic(
|
|
227
|
+
{ "conditions-met": [{ var: "c.o.1" }, null, null] },
|
|
228
|
+
{ "c": { "o": { "1": [true, true] } } }
|
|
229
|
+
)
|
|
230
|
+
).toBe(true)
|
|
231
|
+
expect(
|
|
232
|
+
LpLogic(
|
|
233
|
+
{ "conditions-met-first": [{ var: "c.o.1" }, null, null] },
|
|
234
|
+
{ "c": { "o": { "1": [true, false] } } }
|
|
235
|
+
)
|
|
236
|
+
).toBe(true)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
test('Testing "selected" with null parents (JSON round-trip safety)', async () => {
|
|
240
|
+
expect(
|
|
241
|
+
LpLogic(
|
|
242
|
+
{ "selected": [{ var: "o.1" }, null, null] },
|
|
243
|
+
{ "o": { "1": [true, true] } }
|
|
244
|
+
)
|
|
245
|
+
).toBe(true)
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test('Testing "conditions-met" with parents containing missing refs (null entries)', async () => {
|
|
249
|
+
// `{ var: "o.999" }` resolves to `null` because `o.999` is absent from data.
|
|
250
|
+
// Parents array is `[null]`; LpLogic must not throw.
|
|
251
|
+
expect(
|
|
252
|
+
LpLogic(
|
|
253
|
+
{ "conditions-met": [{ var: "c.o.1" }, undefined, [{ var: "o.999" }]] },
|
|
254
|
+
{ "c": { "o": { "1": [true] } } }
|
|
255
|
+
)
|
|
256
|
+
).toBe(true)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Accent- and case-insensitive text matching (=, contains, like and negations).
|
|
261
|
+
* Matches the product table: la/lax, la/la ha, la/là, la/La, Léon/Leon.
|
|
262
|
+
*/
|
|
263
|
+
test('Testing "=" case-insensitive for strings', async () => {
|
|
264
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, "la"] }, { v: { 1: ["La"] } })).toBe(
|
|
265
|
+
true
|
|
266
|
+
)
|
|
267
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, "la"] }, { v: { 1: ["LA"] } })).toBe(
|
|
268
|
+
true
|
|
269
|
+
)
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
test('Testing "=" accent-insensitive for strings', async () => {
|
|
273
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })).toBe(
|
|
274
|
+
true
|
|
275
|
+
)
|
|
276
|
+
expect(
|
|
277
|
+
LpLogic({ "=": [{ var: "v.1" }, "Léon"] }, { v: { 1: ["Leon"] } })
|
|
278
|
+
).toBe(true)
|
|
279
|
+
expect(
|
|
280
|
+
LpLogic({ "=": [{ var: "v.1" }, "Léon"] }, { v: { 1: ["LEON"] } })
|
|
281
|
+
).toBe(true)
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
test('Testing "=" still false for different words', async () => {
|
|
285
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, "la"] }, { v: { 1: ["lax"] } })).toBe(
|
|
286
|
+
false
|
|
287
|
+
)
|
|
288
|
+
expect(
|
|
289
|
+
LpLogic({ "=": [{ var: "v.1" }, "la"] }, { v: { 1: ["la ha"] } })
|
|
290
|
+
).toBe(false)
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
test('Testing "=" still numeric for number-like values', async () => {
|
|
294
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, "1.0"] }, { v: { 1: [1] } })).toBe(
|
|
295
|
+
true
|
|
296
|
+
)
|
|
297
|
+
expect(LpLogic({ "=": [{ var: "v.1" }, 1] }, { v: { 1: ["1"] } })).toBe(true)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
test('Testing "<>" is inverse of accent/case-insensitive "="', async () => {
|
|
301
|
+
expect(LpLogic({ "<>": [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })).toBe(
|
|
302
|
+
false
|
|
303
|
+
)
|
|
304
|
+
expect(LpLogic({ "<>": [{ var: "v.1" }, "la"] }, { v: { 1: ["lax"] } })).toBe(
|
|
305
|
+
true
|
|
306
|
+
)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
test('Testing "contains" accent- and case-insensitive', async () => {
|
|
310
|
+
expect(
|
|
311
|
+
LpLogic({ contains: [{ var: "v.1" }, "la"] }, { v: { 1: ["lax"] } })
|
|
312
|
+
).toBe(true)
|
|
313
|
+
expect(
|
|
314
|
+
LpLogic({ contains: [{ var: "v.1" }, "la"] }, { v: { 1: ["la ha"] } })
|
|
315
|
+
).toBe(true)
|
|
316
|
+
expect(
|
|
317
|
+
LpLogic({ contains: [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })
|
|
318
|
+
).toBe(true)
|
|
319
|
+
expect(
|
|
320
|
+
LpLogic({ contains: [{ var: "v.1" }, "la"] }, { v: { 1: ["La"] } })
|
|
321
|
+
).toBe(true)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
test('Testing "does-not-contain" is inverse of accent-insensitive contains', async () => {
|
|
325
|
+
expect(
|
|
326
|
+
LpLogic(
|
|
327
|
+
{ "does-not-contain": [{ var: "v.1" }, "la"] },
|
|
328
|
+
{ v: { 1: ["là"] } }
|
|
329
|
+
)
|
|
330
|
+
).toBe(false)
|
|
331
|
+
expect(
|
|
332
|
+
LpLogic(
|
|
333
|
+
{ "does-not-contain": [{ var: "v.1" }, "la"] },
|
|
334
|
+
{ v: { 1: ["Bye"] } }
|
|
335
|
+
)
|
|
336
|
+
).toBe(true)
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
test('Testing "like" accent- and case-insensitive word match', async () => {
|
|
340
|
+
expect(
|
|
341
|
+
LpLogic({ like: [{ var: "v.1" }, "la"] }, { v: { 1: ["lax"] } })
|
|
342
|
+
).toBe(false)
|
|
343
|
+
expect(
|
|
344
|
+
LpLogic({ like: [{ var: "v.1" }, "la"] }, { v: { 1: ["la ha"] } })
|
|
345
|
+
).toBe(true)
|
|
346
|
+
expect(
|
|
347
|
+
LpLogic({ like: [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })
|
|
348
|
+
).toBe(true)
|
|
349
|
+
expect(
|
|
350
|
+
LpLogic({ like: [{ var: "v.1" }, "la"] }, { v: { 1: ["La"] } })
|
|
351
|
+
).toBe(true)
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
test('Testing "not-like" is inverse of accent-insensitive like', async () => {
|
|
355
|
+
expect(
|
|
356
|
+
LpLogic({ "not-like": [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })
|
|
357
|
+
).toBe(false)
|
|
358
|
+
expect(
|
|
359
|
+
LpLogic({ "not-like": [{ var: "v.1" }, "la"] }, { v: { 1: ["lax"] } })
|
|
360
|
+
).toBe(true)
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
test('Testing "is" accent-insensitive (legacy equal alias)', async () => {
|
|
364
|
+
expect(LpLogic({ is: [{ var: "v.1" }, "la"] }, { v: { 1: ["là"] } })).toBe(
|
|
365
|
+
true
|
|
366
|
+
)
|
|
367
|
+
expect(
|
|
368
|
+
LpLogic({ is: [{ var: "v.1" }, "Léon"] }, { v: { 1: ["Leon"] } })
|
|
369
|
+
).toBe(true)
|
|
370
|
+
})
|