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
13 changes: 7 additions & 6 deletions compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
)
}

Expand Down Expand Up @@ -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}]`
}
Expand All @@ -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
Expand All @@ -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}%%%__`
Expand Down
28 changes: 21 additions & 7 deletions general.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
}
}

Expand All @@ -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')
}
})
})
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down