UNPKG

mframejs

Version:
2,120 lines (1,729 loc) 42.1 kB
import { BindingEngine, valueConverter, IBindingContext, createBindingContext } from 'mframejs'; /* * Helper for tests **/ const e = (t: any) => { return BindingEngine.tokenizeParseAndTraverseAST(t.expressions, t.ctx); }; /* * Context for our expression tests **/ const ctx: IBindingContext = createBindingContext({ 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 't1': 5, 't2': 5, 'a1': 5, 'a2': 5, 'over': 'no', '_': '_', $five: 5, $four: 4, item: { id: 1, name: 'name', lastName: 'lastname', age: 10, num1: 10, num2: 10, name1: 'cool', name2: 'wee' }, internal2: { test: function () { return 5; }, internal: { test: function () { return 5; } } }, arrayTest: [], internal: { test: function () { return 5; }, internal: { test: function () { return 5; } } }, undefinedVal: undefined, nullVal: null, functionAdd2To: (a: number) => { return a + 2; }, functionAddNumbers: (...a: any[]) => { return a.reduce((newval, current) => newval + current); }, returnValueString: (a: number) => { return 'nooo:' + a; // I should never be called } }, createBindingContext({ 'over': 'yes', returnValueString: (a: number) => { return a + ''; }, internal2: { test: function () { return 7; }, internal: { test: function () { return 7; } } } }) ); /* * Helper for tests * Error message gets kinda broken this way. * But test text is better, and easy to make many **/ const testExpr = (expression: string, tobe: any, ctx: IBindingContext, callable: Function) => { const description = `${expression} toBe(${tobe}<${typeof tobe}>)`; const result = e({ expressions: `${expression}`, ctx: ctx }); callable( description, result, tobe); }; @valueConverter('times2or') export class ValueConverterTest1 { public toView(arg1: any, val: any) { val = val ? val : 2; return arg1 * val; } } @valueConverter('repeat') export class ValueConverterTest2 { public toView(arg1: any) { return arg1 + ' ' + arg1; } } describe('tokenize parse nd traverse AST with expressions', () => { testExpr( 'internal.test()', 5, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'internal.internal.test()', 5, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'internal2.test()', 7, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'internal2.internal.test()', 7, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(2 === 2) && (3 === 3)', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '($five === $five) && ($four=== $four)', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' ( 2 = = = 2 ) & & ( 3 = = = 3 ) ', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${(2 === 2) && (3 === 3)}', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{(2 === 2) && (3 === 3)}', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'e*((a*(b+c))+d)', 45, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' e * ( ( a * (b+ c)) +d)', 45, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${e*((a*(b+c))+d)}', '45', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{e*((a*(b+c))+d)}', '45', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '4+-1', 3, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' 4 + - 1 ', 3, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' 4+ -1 ', 3, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${4+-1}', '3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{4+-1}', '3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${ 4 + - 1 }', '3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{ 4 + - 1 }', '3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '4+-1 + 4+-1', 6, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' 4 + - 1 + 4 + - 1 ', 6, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ` 4 + - 1 + 4 + - 1 `, 6, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${4+-1 + 4+-1}', '6', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{4+-1 + 4+-1}', '6', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${4+-1} + ${4+-1}', '3 + 3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{4+-1} + @{4+-1}', '3 + 3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${4+-1} + @{4+-1}', '3 + 3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{4+-1} + ${4+-1}', '3 + 3', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(2 === 1) && (3 === 3)', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'over', 'yes', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'over | repeat', 'yes yes', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'over | repeat | repeat', 'yes yes yes yes', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'returnValueString(5)', '5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'Idonotexist()', // I should fail--- undefined, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(2 === 2) && !(3 === 3)', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '!(2 === 2) && (3 === 3)', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '!(2 === 2) && !(3 === 3)', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(2 === 1) || (3 === 3)', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${(2 === 1) || (3 === 3)}', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{(2 === 1) || (3 === 3)}', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '-4 -1', -5, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' - 4 -1 ', -5, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(a === a) && (c === d)', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '3 - (-2)', 5, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'undefinedVal', undefined, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '!undefinedVal', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'undefinedVal === undefined', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( `undefinedVal === undefined`, true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'undefinedVal !== undefined', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'notInContext', undefined, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${notInContext}', '', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${undefined}', '', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); }); testExpr( '${null}', '', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); }); testExpr( '1 ? 1:2', 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '0 ? 1:2', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'null ? 1:2', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'undefined ? 1:2', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '"" ? 1:2', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( "'' ? 1:2", 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '`` ? 1 : 2', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '"x" ? 1:2', 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( "'x' ? 1:2", 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '`x` ? 1 : 2', 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '1 ? true : false', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '1 ? "true" : "false"', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'true ? true : false', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'true ? "true" : "false"', 'true', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '!true ? true : false', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '!true ? "true" : "false"', 'false', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(!true) ? true : false', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '(!true) ? "true" : "false"', 'false', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); // wrong value really... testExpr( '3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3', 0.3333333333333335, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | times2or', 10, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${5 | times2or}', '10', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{5 | times2or}', '10', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | times2or | times2or', 20, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${5 | times2or | times2or}', '20', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{5 | times2or | times2or}', '20', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | times2or:4', 20, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | times2or:4 | times2or', 40, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | repeat ', '5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat & beghaviorthatdoesnotexist', '5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat & beghaviorthatdoesnotexist:555', '5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat & beghaviorthatdoesnotexist:555 & beghaviorthatdoesnotexist:555', '5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 | repeat | repeat', '5 5 5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat | repeat & beghaviorthatdoesnotexist', '5 5 5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat | repeat & something:555', '5 5 5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( // to see it does not mess up with result '5 | repeat | repeat & signal:555 & trigger:555', '5 5 5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '${5 | repeat | repeat}', '5 5 5 5', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'expr1:${5}, expr2:${5+5}, expr3:${9*2}, expr4:${5*5},', 'expr1:5, expr2:10, expr3:18, expr4:25,', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' ${"a"}${"Test"} ', ' aTest ', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( ' ${"a"}${"Test"} ', ' aTest ', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'functionAdd2To(2)', 4, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'functionAdd2To("2")', '22', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'functionAdd2To(item.age)', 12, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'functionAdd2To(item.age.doesNotExist)', NaN, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'item.age.doesNotExist === undefined', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( "{'cool':a, a:b}", JSON.stringify({ 'cool': 1, 'a': 2 }), ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(result)).toBe(shouldbe); }); } ); testExpr( "{'cool':a}", JSON.stringify({ 'cool': 1 }), ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(result)).toBe(shouldbe); }); } ); testExpr( 'a1 = 2', 2, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.a1).toBe(shouldbe); }); } ); testExpr( 'a2 = 1', 1, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.a2).toBe(shouldbe); }); } ); testExpr( 't1 += 1', 6, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.t1).toBe(shouldbe); }); } ); testExpr( 'unknown += 1', NaN, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.unknown).toBe(shouldbe); }); } ); testExpr( 'somethingelse.item += 1', NaN, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.unknown).toBe(shouldbe); }); } ); testExpr( 't2 -= 1', 4, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.t2).toBe(shouldbe); }); } ); testExpr( 'item.num1 += 1', 11, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.item.num1).toBe(shouldbe); }); } ); testExpr( 'item.num2-= 1', 9, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.item.num2).toBe(shouldbe); }); } ); testExpr( 'item.name1 = 5', 5, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.item.name1).toBe(shouldbe); }); } ); testExpr( 'item.somethingUnknown = 5', 5, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.item.somethingUnknown).toBe(shouldbe); }); } ); testExpr( 'item.name2 = "name"', 'name', ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.item.name2).toBe(shouldbe); }); } ); testExpr( 'shi.testing = 5', 5, ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx.$context.shi.testing).toBe(shouldbe); }); } ); testExpr( 'shi.cool = {a:1}', JSON.stringify({ 'a': 1 }), ctx, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx.$context.shi.cool)).toBe(shouldbe); }); } ); testExpr( '{a:a, b:b}', JSON.stringify({ 'a': 1, 'b': 2 }), ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(result)).toBe(shouldbe); }); } ); testExpr( '${a ? ${true ? ${true ? "false man": "yikes"}: "false man"} :false }', 'false man', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '@{a ? @{true ? @{true ? "false man": "yikes"}: "false man"} :false }', 'false man', ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'item["id"]', 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 + functionAddNumbers(1,1,1,1,1)', 10, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 < 4', false, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 > 4', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 % 4', 1, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '6 % 4', 2, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 >= 5', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '5 <= 5', true, ctx, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'value', 'last', createBindingContext({ value: 'first' }, createBindingContext({ value: 'middle' }, createBindingContext({ value: 'last' }))), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( '$value', 'first', createBindingContext({ $value: 'first' }, createBindingContext({ $value: 'middle' }, createBindingContext({ $value: 'last' }))), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj', JSON.stringify({ name: 'string', value: 1 }), createBindingContext({ obj: { name: 'string', value: 1 } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(result)).toBe(shouldbe); }); } ); testExpr( 'obj ? obj: 1', JSON.stringify({ name: 'string', value: 1 }), createBindingContext({ obj: { name: 'string', value: 1 } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(result)).toBe(shouldbe); }); } ); testExpr( 'obj.values[1]', 3, createBindingContext({ obj: { name: 'string', value: 1, values: [5, 3, 2] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values["1"]', 3, createBindingContext({ obj: { name: 'string', value: 1, values: [5, 3, 2] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.value]', 3, createBindingContext({ obj: { name: 'string', value: 1, values: [5, 3, 2] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.a.b + (obj.b.a)', 3, createBindingContext({ obj: { name: 'string', value: 1, values: [5, 3, 2], a: { b: 1 }, b: { a: 2 } } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.values[obj.value]]', 3, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.values[2]]', 3, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'testfn(obj.value) + testfn(obj.value)', 4, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] }, testfn: function (x: any) { return x; } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.values[2]] | times2or', 6, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.values[2]] | times2or:obj.values[obj.values[2]] ', 9, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.values[2]] | times2or:obj.values[obj.values[2]] | times2or:obj.values[obj.values[2]]', 27, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'test2fn(obj.value, obj.value) + testfn(obj.values[0])', 9, createBindingContext({ obj: { name: 'string', value: 2, values: [5, 3, 1] }, testfn: function (x: any) { return x; }, test2fn: function (x: any, y: any) { return x + y; } }), (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); const ctx1 = createBindingContext({ obj: { name: 'string', value1: 2, values: [5, 3, 1, 'wow', { person: { name: 'wow' } }] }, callme(x: any) { return x; } }); testExpr( 'obj.values[1] = 5', 5, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.obj.values[1]).toBe(shouldbe); }); } ); testExpr( 'obj.values[obj.value1] += 5', 6, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.obj.values[2]).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow = 5', 5, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.cool.value.test.wow).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.man = 7', 7, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.cool.value.test.man).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow2 = callme(9)', 9, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.cool.value.test.wow2).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow4 = callme(obj.value1)', 2, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.cool.value.test.wow4).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow5 = callme(obj["value1"])', 2, ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.cool.value.test.wow5).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow6 = callme({wow:"cool"})', JSON.stringify({ wow: 'cool' }), ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx1.$context.cool.value.test.wow6)).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow7 = callme({wow:{name:"cool"}})', JSON.stringify({ wow: { name: 'cool' } }), ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx1.$context.cool.value.test.wow7)).toBe(shouldbe); }); } ); testExpr( 'cool.value.test.wow8 = {wow:{name:"cool"}}', JSON.stringify({ wow: { name: 'cool' } }), ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx1.$context.cool.value.test.wow8)).toBe(shouldbe); }); } ); testExpr( 'wow8 = {wow:{name:"cool"}}', JSON.stringify({ wow: { name: 'cool' } }), ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx1.$context.wow8)).toBe(shouldbe); }); } ); testExpr( 'obj.values[3] = {wow:{name:"cool"}}', JSON.stringify({ wow: { name: 'cool' } }), ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(JSON.stringify(ctx1.$context.obj.values[3])).toBe(shouldbe); }); } ); testExpr( 'obj.values[4].person.name', 'wow', ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.obj.values[4].person.name).toBe(shouldbe); }); } ); testExpr( 'obj.values[4].person.last = "cool"', 'cool', ctx1, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx1.$context.obj.values[4].person.last).toBe(shouldbe); }); } ); const ctx10 = createBindingContext({ obj: { number1: 2, number2: 2, number3: 5, number4: 5 } }); testExpr( 'obj.number1 *= 2', 4, ctx10, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx10.$context.obj.number1).toBe(shouldbe); }); } ); testExpr( 'obj.number2 /= 2', 1, ctx10, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx10.$context.obj.number2).toBe(shouldbe); }); } ); testExpr( 'obj.number3 *= 2', 10, ctx10, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx10.$context.obj.number3).toBe(shouldbe); }); } ); testExpr( 'obj.number4 /= 2', 2.5, ctx10, (description: string, _result: any, shouldbe: any) => { it(description, () => { expect(ctx10.$context.obj.number4).toBe(shouldbe); }); } ); const ctx11 = createBindingContext({ obj: { number1: 2, number2: 2, number3: 5, number4: 5 }, testArray1: [], testArray2: [], testArray3: [5], testArray4: [1, 2, 3] }); testExpr( 'testArray1.length', 0, ctx11, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'testArray2.push(5,1)', 2, ctx11, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'testArray3.pop()', 5, ctx11, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); testExpr( 'testArray4.join("-")', '1-2-3', ctx11, (description: string, result: any, shouldbe: any) => { it(description, () => { expect(result).toBe(shouldbe); }); } ); });