UNPKG

expression-language

Version:

Javascript implementation of symfony/expression-language

331 lines (330 loc) 7.98 kB
"use strict"; var _ExpressionLanguage = _interopRequireDefault(require("../ExpressionLanguage")); var _ExpressionFunction = _interopRequireDefault(require("../ExpressionFunction")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } test('short circuit evaluate', () => { let obj = { foo: () => { throw new Error("This method should not be called due to short circuiting."); } }; let shortCircuits = [['false && object.foo()', { object: obj }, false], ['false and object.foo()', { object: obj }, false], ['true || object.foo()', { object: obj }, true], ['true or object.foo()', { object: obj }, true]]; for (let shortCircuit of shortCircuits) { //console.log("Testing: ", shortCircuit[0]); let exprLang = new _ExpressionLanguage.default(); expect(exprLang.evaluate(shortCircuit[0], shortCircuit[1])).toBe(shortCircuit[2]); } }); test('short circuit compile', () => { let shortCircuits = [['false && foo', [{ foo: 'foo' }], false], ['false and foo', [{ foo: 'foo' }], false], ['true || foo', [{ foo: 'foo' }], true], ['true or foo', [{ foo: 'foo' }], true]]; for (let shortCircuit of shortCircuits) { let exprLang = new _ExpressionLanguage.default(); let compiled = exprLang.compile(shortCircuit[0], shortCircuit[1]); expect(eval(compiled)).toBe(shortCircuit[2]); } }); test('caching for overridden variable names', () => { let expressionLanguage = new _ExpressionLanguage.default(), expression = 'a + b'; expressionLanguage.evaluate(expression, { a: 1, b: 1 }); let result = expressionLanguage.compile(expression, ['a', { 'B': 'b' }]); expect(result).toBe("(a + B)"); }); test('strict equality', () => { let expressionLanguage = new _ExpressionLanguage.default(), expression = '123 === a'; let result = expressionLanguage.compile(expression, ['a']); expect(result).toBe("(123 === a)"); }); test('register after parse', () => { let callbacks = getRegisterCallbacks(); for (let callback of callbacks) { try { let expressionLanguage = new _ExpressionLanguage.default(); expressionLanguage.parse("1 + 1", []); callback[0](expressionLanguage); console.log("Shouldn't get to this point."); expect(true).toBe(false); } catch (err) { //console.log(err); expect(err.name).toBe('LogicException'); } } }); test('register after eval', () => { let callbacks = getRegisterCallbacks(); for (let callback of callbacks) { try { let expressionLanguage = new _ExpressionLanguage.default(); expressionLanguage.evaluate("1 + 1"); callback[0](expressionLanguage); console.log("Shouldn't get to this point."); expect(true).toBe(false); } catch (err) { //console.log(err); expect(err.name).toBe('LogicException'); } } }); test('register after compile', () => { let callbacks = getRegisterCallbacks(); for (let callback of callbacks) { try { let expressionLanguage = new _ExpressionLanguage.default(); expressionLanguage.compile("1 + 1"); callback[0](expressionLanguage); console.log("Shouldn't get to this point."); expect(true).toBe(false); } catch (err) { //console.log(err); expect(err.name).toBe('LogicException'); } } }); test('bad callable', () => { try { let expressionLanguage = new _ExpressionLanguage.default(); expressionLanguage.evaluate("foo.myfunction()", { foo: {} }); console.log("Shouldn't get to this point."); expect(true).toBe(false); } catch (err) { //console.log(err); expect(err.toString()).toBe('Error: Method "myfunction" is undefined on object.'); } }); function getRegisterCallbacks() { let provider = { getFunctions: () => { return [new _ExpressionFunction.default('fn', () => {}, () => {})]; } }; return [[expressionLanguage => { expressionLanguage.register('fn', () => {}, () => {}); }], [expressionLanguage => { expressionLanguage.addFunction(new _ExpressionFunction.default('fn', () => {}, () => {})); }], [expressionLanguage => { expressionLanguage.registerProvider(provider); }]]; } test('evaluate', () => { let evaluateData = getEvaluateData(); for (let evaluateDatum of evaluateData) { let expressionLanguage = new _ExpressionLanguage.default(), provider = evaluateDatum[3], expression = evaluateDatum[0], values = evaluateDatum[1], expectedOutcome = evaluateDatum[2]; if (provider) { expressionLanguage.registerProvider(provider); } let result = expressionLanguage.evaluate(expression, values); if (expectedOutcome !== null && typeof expectedOutcome === "object") { expect(result).toMatchObject(expectedOutcome); } else { expect(result).toBe(expectedOutcome); } } }); function getEvaluateData() { return [[ // Expression '1.0', // Values {}, // Expected Outcome 1, // Provider null], [ // Expression '1 + 1', // Values {}, // Expected Outcome 2, // Provider null], [ // Expression '2 ** 3', // Values {}, // Expected Outcome 8, // Provider null], [ // Expression 'a > 0', // Values { a: 1 }, // Expected Outcome true, // Provider null], [ // Expression 'a >= 0', // Values { a: 1 }, // Expected Outcome true, // Provider null], [ // Expression 'a <= 0', // Values { a: 1 }, // Expected Outcome false, // Provider null], [ // Expression 'a != 0', // Values { a: 1 }, // Expected Outcome true, // Provider null], [ // Expression 'a == 1', // Values { a: 1 }, // Expected Outcome true, // Provider null], [ // Expression 'a === 1', // Values { a: 1 }, // Expected Outcome true, // Provider null], [ // Expression 'a !== 1', // Values { a: 1 }, // Expected Outcome false, // Provider null], ['foo.getFirst() + bar.getSecond()', { foo: { getFirst: () => { return 7; } }, bar: { getSecond: () => { return 100; } } }, 107, null], ['(foo.getFirst() + bar.getSecond()) / foo.second', { foo: { second: 4, getFirst: () => { return 7; } }, bar: { getSecond: () => { return 9; } } }, 4, null], ['foo.getFirst() + bar.getSecond() / foo.second', { foo: { second: 4, getFirst: () => { return 7; } }, bar: { getSecond: () => { return 8; } } }, 9, null], ['(foo.getFirst() + bar.getSecond() / foo.second) + bar.first[3]', { foo: { getFirst: () => { return 7; }, second: 4 }, bar: { first: [1, 2, 3, 4, 5], getSecond: () => { return 8; } } }, 13, null], ['b.myMethod(a[1])', { a: ["one", "two", "three"], b: { myProperty: "foo", myMethod: word => { return "bar " + word; } } }, "bar two", null], ['a[2] === "three" and b.myMethod(a[1]) === "bar two" and (b.myProperty == "foo" or b["myProperty"] == "foo") and b["property with spaces and &*()*%$##@% characters"] == "fun"', { a: ["one", "two", "three"], b: { myProperty: "foo", myMethod: word => { return "bar " + word; }, ["property with spaces and &*()*%$##@% characters"]: 'fun' } }, true, null], ['a and !b', { a: true, b: false }, true, null], ['a in b', { a: "Dogs", b: ["Cats", "Dogs"] }, true, null], ['a in outputs["typesOfAnimalsAllowed"]', { a: "Dogs", outputs: { typesOfAnimalsAllowed: ["Dogs", "Other"] } }, true, null], ['"Other" in inputs["typesOfAnimalsAllowed"]', { inputs: { typesOfAnimalsAllowed: ["Dogs", "Other"] } }, true], ['a not in b', { a: "Dogs", b: ["Cats", "Bags"] }, true, null]]; }