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", ``);
const domRendered = renderToDOM(qweb, "test");
expect(domRendered.textContent).toBe("escaped
");
});
+
test("t-esc=0 is escaped", () => {
qweb.addTemplate("test", ``);
qweb.addTemplate("testCaller", ``);
@@ -176,6 +178,12 @@ describe("t-esc", () => {
""
);
});
+
+ 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']])");
+ });
});