From f52d64d459921942a905d15e70c055a42dd7b093 Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Tue, 4 Jun 2024 10:23:00 +0100 Subject: [PATCH 1/2] compiler: add test for lazy state with logical not --- .../test/transforms/lazy-state.test.ts | 175 ++++++++++-------- 1 file changed, 94 insertions(+), 81 deletions(-) diff --git a/packages/compiler/test/transforms/lazy-state.test.ts b/packages/compiler/test/transforms/lazy-state.test.ts index aa509bef9..c7a991786 100644 --- a/packages/compiler/test/transforms/lazy-state.test.ts +++ b/packages/compiler/test/transforms/lazy-state.test.ts @@ -10,152 +10,152 @@ import visitors from '../../src/transforms/lazy-state'; test('convert a simple dollar reference', (t) => { const ast = parse('get($.data)'); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, 'get(state => state.data)') -}) + t.is(code, 'get(state => state.data)'); +}); test('convert a chained dollar reference', (t) => { const ast = parse('get($.a.b.c.d)'); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, 'get(state => state.a.b.c.d)') -}) + t.is(code, 'get(state => state.a.b.c.d)'); +}); test('ignore a regular chain reference', (t) => { const ast = parse('get(a.b.c.d)'); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, 'get(a.b.c.d)') -}) + t.is(code, 'get(a.b.c.d)'); +}); test('convert a template literal', (t) => { - const src = 'get(`hello ${$.data}`)' - t.log(src) + const src = 'get(`hello ${$.data}`)'; + t.log(src); const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) - t.log(code) + const { code } = print(transformed); + t.log(code); - t.is(code, 'get(state => `hello ${state.data}`)') -}) + t.is(code, 'get(state => `hello ${state.data}`)'); +}); test('convert a template literal with two refs', (t) => { - const src = 'get(`hello ${$.firstname} ${$.lastname}`)' - t.log(src) + const src = 'get(`hello ${$.firstname} ${$.lastname}`)'; + t.log(src); const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) - t.log(code) + const { code } = print(transformed); + t.log(code); - t.is(code, 'get(state => `hello ${state.firstname} ${state.lastname}`)') -}) + t.is(code, 'get(state => `hello ${state.firstname} ${state.lastname}`)'); +}); test('convert a template literal with a pre-existing parent arrow', (t) => { - const src = 'get(state => `hello ${$.data}`)' - t.log(src) + const src = 'get(state => `hello ${$.data}`)'; + t.log(src); const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) - t.log(code) + const { code } = print(transformed); + t.log(code); - t.is(code, 'get(state => `hello ${state.data}`)') -}) + t.is(code, 'get(state => `hello ${state.data}`)'); +}); test('throw if a $ is already inside a non-compatible arrow (state name)', (t) => { - const src = 'get((s) => `hello ${$.data}`)' // throw!! - t.log(src) + const src = 'get((s) => `hello ${$.data}`)'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: `invalid state operator: parameter "s" should be called "state"` + message: `invalid state operator: parameter "s" should be called "state"`, }); -}) +}); test('throw if a $ is already inside a non-compatible arrow (arity)', (t) => { - const src = 'get((state, b) => `hello ${$.data}`)' // throw!! - t.log(src) + const src = 'get((state, b) => `hello ${$.data}`)'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: 'invalid state operator: parent has wrong arity' + message: 'invalid state operator: parent has wrong arity', }); -}) +}); test('throw if $ is not inside an operation', (t) => { - const src = 'const x = $.data;' // throw!! - t.log(src) + const src = 'const x = $.data;'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: 'invalid state operator: must be inside an expression' + message: 'invalid state operator: must be inside an expression', }); -}) +}); test('throw if $ is on the left hand side of an assignment', (t) => { - const src = '$.data = 20;' // throw!! - t.log(src) + const src = '$.data = 20;'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: 'invalid state operator: must be inside an expression' + message: 'invalid state operator: must be inside an expression', }); -}) +}); test('throw if $ is on the left hand side of a nested assignment', (t) => { - const src = 'fn(() => { $.data = 20; })' // throw!! - t.log(src) + const src = 'fn(() => { $.data = 20; })'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: 'invalid state operator: must be inside an expression' + message: 'invalid state operator: must be inside an expression', }); -}) +}); test('throw if $ is on the left hand side of a multi assignment', (t) => { - const src = 'const z = $.data = 20;' // throw!! - t.log(src) + const src = 'const z = $.data = 20;'; // throw!! + t.log(src); const ast = parse(src); t.throws(() => transform(ast, [visitors]), { - message: 'invalid state operator: must be inside an expression' + message: 'invalid state operator: must be inside an expression', }); -}) +}); test('wrap a concatenation', (t) => { - const src = 'get($.firstname + " " + $.lastname)' - t.log(src) + const src = 'get($.firstname + " " + $.lastname)'; + t.log(src); const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) - t.log(code) + const { code } = print(transformed); + t.log(code); - t.is(code, 'get(state => state.firstname + " " + state.lastname)') -}) + t.is(code, 'get(state => state.firstname + " " + state.lastname)'); +}); test('wrap a dynamic property reference', (t) => { - const src = 'get(city[$.location])' - t.log(src) + const src = 'get(city[$.location])'; + t.log(src); const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) - t.log(code) + const { code } = print(transformed); + t.log(code); - t.is(code, 'get(state => city[state.location])') -}) + t.is(code, 'get(state => city[state.location])'); +}); test('ignore a dollar ref in a string', (t) => { const ast = parse('get("$.a.b")'); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, 'get("$.a.b")') -}) + t.is(code, 'get("$.a.b")'); +}); // TODO do we want to support this? test('convert a nested dollar reference', (t) => { @@ -164,46 +164,59 @@ test('convert a nested dollar reference', (t) => { })`); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); // syntax starts getting a but picky at this level, // better to do ast tests - t.is(code, `fn(() => { + t.is( + code, + `fn(() => { get(state => state.data) -})`) -}) +})` + ); +}); test('do not convert a $ var (param)', (t) => { const src = `fn(($) => { return $.a.b; - })` + })`; const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, src) -}) + t.is(code, src); +}); test('do not convert a $ var (const)', (t) => { const src = `fn((s) => { const $ = 10; s.data = $.a.b return s; - })` + })`; const ast = parse(src); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, src) -}) + t.is(code, src); +}); test('convert an optional chained simple dollar reference', (t) => { const ast = parse('get($.a?.b.c.d)'); const transformed = transform(ast, [visitors]); - const { code } = print(transformed) + const { code } = print(transformed); - t.is(code, 'get(state => state.a?.b.c.d)') -}) \ No newline at end of file + t.is(code, 'get(state => state.a?.b.c.d)'); +}); + +test('convert logical not', (t) => { + const ast = parse('get(!$.data.x)'); + + const transformed = transform(ast, [visitors]); + const { code } = print(transformed); + console.log(code); + + t.is(code, 'get(state => !state.data.x)'); +}); From 1992fb40eae8c471ed17365b9207edf144b72e3b Mon Sep 17 00:00:00 2001 From: Joe Clark Date: Tue, 4 Jun 2024 10:25:00 +0100 Subject: [PATCH 2/2] remove logging --- packages/compiler/test/transforms/lazy-state.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/compiler/test/transforms/lazy-state.test.ts b/packages/compiler/test/transforms/lazy-state.test.ts index c7a991786..bdd939d74 100644 --- a/packages/compiler/test/transforms/lazy-state.test.ts +++ b/packages/compiler/test/transforms/lazy-state.test.ts @@ -216,7 +216,6 @@ test('convert logical not', (t) => { const transformed = transform(ast, [visitors]); const { code } = print(transformed); - console.log(code); t.is(code, 'get(state => !state.data.x)'); });