diff --git a/compiler.js b/compiler.js index 1cc56dd..dc85183 100644 --- a/compiler.js +++ b/compiler.js @@ -36,12 +36,13 @@ import asyncIterators from './async_iterators.js' * @param {*} x * @returns */ -function isPrimitive (x) { +function isPrimitive (x, preserveObject) { if (typeof x === 'number' && (x === Infinity || x === -Infinity || Number.isNaN(x))) return false return ( x === null || x === undefined || - ['Number', 'String', 'Boolean', 'Object'].includes(x.constructor.name) + ['Number', 'String', 'Boolean'].includes(x.constructor.name) || + (!preserveObject && x.constructor.name === 'Object') ) } @@ -245,8 +246,8 @@ function buildString (method, buildState = {}) { values = [], engine } = buildState - function pushValue (value) { - if (isPrimitive(value)) return JSON.stringify(value) + function pushValue (value, preserveObject = false) { + if (isPrimitive(value, preserveObject)) return JSON.stringify(value) values.push(value) return `values[${values.length - 1}]` } @@ -273,7 +274,7 @@ function buildString (method, buildState = {}) { if (method && typeof method === 'object') { if (!engine.methods[func]) { // If we are in permissive mode, we will just return the object. - if (engine.options.permissive) return pushValue(method) + if (engine.options.permissive) return pushValue(method, true) throw new Error(`Method '${func}' was not found in the Logic Engine.`) } functions[func] = functions[func] || 2 @@ -284,7 +285,7 @@ function buildString (method, buildState = {}) { isDeterministic(method, engine, buildState) ) { if (isDeepSync(method, engine)) { - return pushValue((engine.fallback || engine).run(method)) + return pushValue((engine.fallback || engine).run(method), true) } else if (!buildState.avoidInlineAsync) { processing.push(engine.run(method).then((i) => pushValue(i))) return `__%%%${processing.length - 1}%%%__` diff --git a/general.test.js b/general.test.js index 6096500..94dde7b 100644 --- a/general.test.js +++ b/general.test.js @@ -16,7 +16,7 @@ const permissiveEngines = [ new AsyncLogicEngine(undefined, { yieldSupported: true, permissive: true }) ] -async function testEngineAsync (engine, rule, data, expected) { +async function testEngineAsync (engine, rule, data, expected, matcher = 'deepStrictEqual') { // run if (expected === Error) { try { @@ -25,7 +25,7 @@ async function testEngineAsync (engine, rule, data, expected) { } catch (e) {} } else { const result = await engine.run(rule, data) - assert.deepStrictEqual(result, expected) + assert[matcher](result, expected) } // build @@ -38,13 +38,13 @@ async function testEngineAsync (engine, rule, data, expected) { } else { const built = await engine.build(rule) const builtResult = await built(data) - assert.deepStrictEqual(builtResult, expected) + assert[matcher](builtResult, expected) } } -function testEngine (engine, rule, data, expected) { +function testEngine (engine, rule, data, expected, matcher = 'deepStrictEqual') { if (engine instanceof AsyncLogicEngine) { - return testEngineAsync(engine, rule, data, expected) + return testEngineAsync(engine, rule, data, expected, matcher) } // run @@ -55,7 +55,7 @@ function testEngine (engine, rule, data, expected) { } catch (e) {} } else { const result = engine.run(rule, data) - assert.deepStrictEqual(result, expected) + assert[matcher](result, expected) } // build @@ -68,7 +68,7 @@ function testEngine (engine, rule, data, expected) { } else { const built = engine.build(rule) const builtResult = built(data) - assert.deepStrictEqual(builtResult, expected) + assert[matcher](builtResult, expected) } } @@ -84,6 +84,20 @@ describe('Various Test Cases', () => { await testEngine(engine, { if: [true, { unknown: true, unknown2: 2 }, 5] }, {}, { unknown: true, unknown2: 2 }) + + const obj = { unknown: true, unknown2: 2 } + + // test with deterministic function returning a passively preserved element. + await testEngine(engine, { + if: [true, obj, 5] + }, {}, obj, 'equal') + + // test with a non-deterministic function returning a passively preserved element. + await testEngine(engine, { + if: [{ var: 'data' }, obj, 5] + }, { + data: true + }, obj, 'equal') } }) }) diff --git a/package.json b/package.json index e08b02c..33c805a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json-logic-engine", - "version": "1.2.2", + "version": "1.2.3", "description": "Construct complex rules with JSON & process them.", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js",