From ef6fd457f85ec08606a799e2d09f76ad53851f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 13 Dec 2019 14:50:49 +0100 Subject: [PATCH] [FIX] qweb: add support for spread operator closes #575 --- src/qweb/expression_parser.ts | 2 +- tests/component/component.test.ts | 8 ++++---- tests/qweb/__snapshots__/qweb.test.ts.snap | 16 ++++++++++++++++ tests/qweb/qweb.test.ts | 8 ++++++++ tests/qweb/qweb_expressions.test.ts | 12 ++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/qweb/expression_parser.ts b/src/qweb/expression_parser.ts index 36acabbe..32a7a966 100644 --- a/src/qweb/expression_parser.ts +++ b/src/qweb/expression_parser.ts @@ -81,7 +81,7 @@ const STATIC_TOKEN_MAP: { [key: string]: TKind } = { // note that the space after typeof is relevant. It makes sure that the formatted // expression has a space after typeof -const OPERATORS = ".,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;".split(","); +const OPERATORS = "...,.,===,==,+,!==,!=,!,||,&&,>=,>,<=,<,?,-,*,/,%,typeof ,=>,=,;".split(","); type Tokenizer = (expr: string) => Token | false; diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index bde684be..3ff1fba8 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -5581,14 +5581,14 @@ describe("t-call", () => { env.qweb.addTemplate("sub", ``); let child; class Child extends Component { - static template = xml `lucas` + static template = xml`lucas`; constructor() { super(...arguments); child = this; } } class Parent extends Component { - static components = { Child } + static components = { Child }; static template = xml`
`; } const parent = new Parent(); @@ -5607,10 +5607,10 @@ describe("t-call", () => { super(...arguments); child = this; } - static template = xml `lucas` + static template = xml`lucas`; } class Parent extends Component { - static components = { Child } + static components = { Child }; static template = xml``; } const parent = new Parent(); diff --git a/tests/qweb/__snapshots__/qweb.test.ts.snap b/tests/qweb/__snapshots__/qweb.test.ts.snap index f1af5dd1..26fd9442 100644 --- a/tests/qweb/__snapshots__/qweb.test.ts.snap +++ b/tests/qweb/__snapshots__/qweb.test.ts.snap @@ -1772,6 +1772,22 @@ exports[`t-esc t-esc is escaped 1`] = ` }" `; +exports[`t-esc t-esc work with spread operator 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = [...scope['state'].list]; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + exports[`t-esc t-esc=0 is escaped 1`] = ` "function anonymous(context, extra ) { diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts index 60b98710..7e0832fc 100644 --- a/tests/qweb/qweb.test.ts +++ b/tests/qweb/qweb.test.ts @@ -141,11 +141,13 @@ describe("t-esc", () => { qweb.addTemplate("test", `nope`); expect(renderToString(qweb, "test")).toBe("nope"); }); + test("t-esc is escaped", () => { qweb.addTemplate("test", `

escaped

`); const domRendered = renderToDOM(qweb, "test"); expect(domRendered.textContent).toBe("

escaped

"); }); + test("t-esc=0 is escaped", () => { qweb.addTemplate("test", ``); qweb.addTemplate("testCaller", `

escaped

`); @@ -176,6 +178,12 @@ describe("t-esc", () => { "

false

0

" ); }); + + test("t-esc work with spread operator", () => { + qweb.addTemplate("test", ``); + const result = renderToString(qweb, "test", { state: { list: [1, 2] } }); + expect(result).toBe("1,2"); + }); }); describe("t-raw", () => { diff --git a/tests/qweb/qweb_expressions.test.ts b/tests/qweb/qweb_expressions.test.ts index abb1ea9b..9c6f8b6a 100644 --- a/tests/qweb/qweb_expressions.test.ts +++ b/tests/qweb/qweb_expressions.test.ts @@ -50,6 +50,12 @@ describe("tokenizer", () => { { type: "OPERATOR", value: "typeof " }, { type: "SYMBOL", value: "a" } ]); + + expect(tokenize("a...1")).toEqual([ + { type: "SYMBOL", value: "a" }, + { type: "OPERATOR", value: "..." }, + { type: "VALUE", value: "1" } + ]); }); test("strings", () => { @@ -177,4 +183,10 @@ describe("expression evaluation", () => { expect(compileExpr("a -= b", {})).toBe("scope['a']-=scope['b']"); expect(compileExpr("a.b = !a.b", {})).toBe("scope['a'].b=!scope['a'].b"); }); + + test("spread operator", () => { + expect(compileExpr("[...state.list]", {})).toBe("[...scope['state'].list]"); + expect(compileExpr("f(...state.list)", {})).toBe("scope['f'](...scope['state'].list)"); + expect(compileExpr("f([...list])", {})).toBe("scope['f']([...scope['list']])"); + }); });