Skip to content

Commit 8ceab06

Browse files
committed
Feature/ Controlled Execution
- Added `controlledExecution` option on `add_operation` function - Added unit tests `controlledExecution`
1 parent 9c805e9 commit 8ceab06

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

logic.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ http://ricostacruz.com/cheatsheets/umdjs.html
3737
}
3838

3939
var jsonLogic = {};
40+
var runOperationAsControlled = {};
4041
var operations = {
4142
"==": function(a, b) {
4243
return a == b;
@@ -348,6 +349,8 @@ http://ricostacruz.com/cheatsheets/umdjs.html
348349
}
349350
}
350351
return false; // None were truthy
352+
} else if (runOperationAsControlled[op]) {
353+
return operations[op](values, data, jsonLogic);
351354
}
352355

353356
// Everyone else gets immediate depth-first recursion
@@ -404,12 +407,16 @@ http://ricostacruz.com/cheatsheets/umdjs.html
404407
return arrayUnique(collection);
405408
};
406409

407-
jsonLogic.add_operation = function(name, code) {
410+
jsonLogic.add_operation = function(name, code, options) {
408411
operations[name] = code;
412+
413+
var controlledExecution = Boolean(options && options.controlledExecution);
414+
runOperationAsControlled[name] = controlledExecution;
409415
};
410416

411417
jsonLogic.rm_operation = function(name) {
412418
delete operations[name];
419+
delete runOperationAsControlled[name];
413420
};
414421

415422
jsonLogic.rule_like = function(rule, pattern) {

tests/tests.js

+45
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,49 @@ QUnit.module('basic', () => {
307307
jsonLogic.apply({"or": [{"push": [true]}, {"push": [true]}]});
308308
assert.deepEqual(i, [true]);
309309
});
310+
311+
QUnit.test("Expanding functionality with add_operator - controlledExecution", function(assert) {
312+
// assert that controlled execution doesn't do pre-evaluation
313+
var customOp = function(values, data, jsonLogic) {
314+
return jsonLogic.apply(values[0], data);
315+
}
316+
317+
jsonLogic.add_operation('customOp', customOp, { controlledExecution: true });
318+
319+
assert.deepEqual(jsonLogic.apply({ customOp: [{ "var": "" }, { "var": "test" }]}, { test: 123 }), { test: 123 });
320+
assert.deepEqual(jsonLogic.apply({ customOp: [{ "var": "test" }, { "var": "" }]}, { test: 123 }), 123);
321+
322+
// assert that controlled execution custom operators can be removed as normal
323+
jsonLogic.rm_operation('customOp');
324+
325+
assert.throws(() => jsonLogic.apply({ customOp: [] }), Error, "Unrecognized operation customOp");
326+
327+
// assert that controlled-execution custom operators have access to jsonLogic object
328+
// and can run on external data
329+
const externalData = {
330+
specialReference: 'external reference'
331+
};
332+
customOp = function(values, data, jsonLogic) {
333+
return jsonLogic.apply(values[0], externalData);
334+
}
335+
336+
jsonLogic.add_operation('customOp', customOp, { controlledExecution: true });
337+
338+
assert.deepEqual(jsonLogic.apply({ customOp: [{ var: "specialReference" }] }, { specialReference: 'pre-evaluation value' }), 'external reference');
339+
340+
// assert that operators are added with normal functionality when options is omitted
341+
jsonLogic.add_operation('customOp', customOp);
342+
343+
assert.throws(() => jsonLogic.apply({ customOp: [{ var: "specialReference" }] }, { specialReference: 'pre-evaluation value' }), TypeError, "Cannot read property 'apply' of undefined");
344+
345+
// assert that adding a custom operator without controlled-execution still
346+
// results in pre-evaluation
347+
customOp = function(value) {
348+
return value;
349+
}
350+
351+
jsonLogic.add_operation('customOp', customOp);
352+
353+
assert.deepEqual(jsonLogic.apply({ customOp: [{ var: "specialReference" }] }, { specialReference: 'pre-evaluation value' }), 'pre-evaluation value');
354+
});
310355
});

0 commit comments

Comments
 (0)