import QWeb from "../src/core/qweb"; import { EvalContext } from "../src/core/qweb"; function renderToDOM(t: string, context: EvalContext = {}): DocumentFragment { const qweb = new QWeb(); qweb.addTemplate("test", t); return qweb.render("test", context); } function renderToString(t: string, context: EvalContext = {}): string { const qweb = new QWeb(); qweb.addTemplate("test", t); return qweb.renderToString("test", context); } describe("static templates", () => { test("minimal template", () => { const template = "ok"; const expected = "ok"; expect(renderToString(template)).toBe(expected); }); test("empty div", () => { const template = "
"; const expected = template; expect(renderToString(template)).toBe(expected); }); test("div with a text node", () => { const template = "
word
"; const result = renderToString(template); expect(result).toBe(template); }); test("div with a span child node", () => { const template = "
word
"; const result = renderToString(template); expect(result).toBe(template); }); }); describe("error handling", () => { test("invalid xml", () => { const qweb = new QWeb(); expect(() => qweb.addTemplate("test", "
")).toThrow( "Invalid XML in template" ); }); }); describe("t-esc", () => { test("literal", () => { const template = ``; const result = renderToString(template); expect(result).toBe("ok"); }); test("variable", () => { const template = ``; const result = renderToString(template, { var: "ok" }); expect(result).toBe("ok"); }); test("escaping", () => { const template = ``; const result = renderToString(template, { var: "" }); expect(result).toBe("<ok>"); }); test("escaping on a node", () => { const template = ``; const result = renderToString(template); expect(result).toBe("ok"); }); test("escaping on a node with a body", () => { const template = `nope`; const result = renderToString(template); expect(result).toBe("ok"); }); test("escaping on a node with a body, as a default", () => { const template = `nope`; const result = renderToString(template); expect(result).toBe("nope"); }); }); describe("t-raw", () => { test("literal", () => { const template = ``; const result = renderToString(template); expect(result).toBe("ok"); }); test("variable", () => { const template = ``; const result = renderToString(template, { var: "ok" }); expect(result).toBe("ok"); }); test("not escaping", () => { const template = ``; const result = renderToString(template, { var: "" }); expect(result).toBe(""); }); }); describe("t-set", () => { test("set from attribute literal", () => { const template = ``; const result = renderToString(template); expect(result).toBe("ok"); }); test("set from body literal", () => { const template = `ok`; const result = renderToString(template); expect(result).toBe("ok"); }); test("set from attribute lookup", () => { const template = ``; const result = renderToString(template, { value: "ok" }); expect(result).toBe("ok"); }); test("set from body lookup", () => { const template = ``; const result = renderToString(template, { value: "ok" }); expect(result).toBe("ok"); }); test("set from empty body", () => { const template = ``; const result = renderToString(template); expect(result).toBe(""); }); test("value priority", () => { const template = `2`; const result = renderToString(template); expect(result).toBe("1"); }); test("evaluate value expression", () => { const template = ``; const result = renderToString(template); expect(result).toBe("3"); }); test("evaluate value expression, part 2", () => { const template = ``; const result = renderToString(template, { somevariable: 43 }); expect(result).toBe("45"); }); }); describe("t-if", () => { test("boolean value true condition", () => { const template = `ok`; const result = renderToString(template, { condition: true }); expect(result).toBe("ok"); }); test("boolean value false condition", () => { const template = `fail`; const result = renderToString(template, { condition: false }); expect(result).toBe(""); }); test("boolean value condition missing", () => { const template = `fail`; const result = renderToString(template); expect(result).toBe(""); }); test("boolean value condition elif", () => { const template = ` black pearl yellow submarine red is dead beer `; const result = renderToString(template, { color: "red" }); expect(result.trim()).toBe("red is dead"); }); test("boolean value condition else", () => { const template = `
begin ok ok-else end
`; const result = renderToString(template, { condition: true }); expect(result).toBe( "
\n begin\n ok\n end\n
" ); }); test("boolean value condition false else", () => { const template = `
beginfail fail-elseend
`; const result = renderToString(template, { condition: false }); expect(result).toBe( "
beginfail-elseend
" ); }); }); describe("attributes", () => { test("static attributes", () => { const template = `
`; const expected = `
`; expect(renderToString(template)).toBe(expected); }); test("static attributes on void elements", () => { const template = `Test`; const expected = `Test`; expect(renderToString(template)).toBe(expected); }); test("dynamic attributes", () => { const template = `
`; const expected = `
`; expect(renderToString(template)).toBe(expected); }); test("fixed variable", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: "ok" })).toBe(expected); }); test("dynamic attribute falsy variable ", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: false })).toBe(expected); }); test("tuple literal", () => { const template = `
`; const expected = `
`; expect(renderToString(template)).toBe(expected); }); test("tuple variable", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: ["foo", "bar"] })).toBe(expected); }); test("object", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: { a: 1, b: 2, c: 3 } })).toBe( expected ); }); test("format literal", () => { const template = `
`; const expected = `
`; expect(renderToString(template)).toBe(expected); }); test("format value", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: "a" })).toBe(expected); }); test("format expression", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value: 5 })).toBe(expected); }); test("format multiple", () => { const template = `
`; const expected = `
`; expect(renderToString(template, { value1: 0, value2: 1, value3: 2 })).toBe( expected ); }); xit("various escapes", () => { // need to think about this... This one does not pass, but I am not sure it is // a correct test const template = `
`; const expected = `
`; expect( renderToString(template, { bar: 0, baz: 1, qux: { qux: "<>" } }) ).toBe(expected); }); }); describe("t-call (template calling", () => { test("basic caller", () => { const qweb = new QWeb(); qweb.addTemplate("_basic-callee", "ok"); qweb.addTemplate("caller", ''); const expected = "ok"; expect(qweb.renderToString("caller")).toBe(expected); }); test("with unused body", () => { const qweb = new QWeb(); qweb.addTemplate("_basic-callee", "ok"); qweb.addTemplate("caller", 'WHEEE'); const expected = "ok"; expect(qweb.renderToString("caller")).toBe(expected); }); test("with unused setbody", () => { const qweb = new QWeb(); qweb.addTemplate("_basic-callee", "ok"); qweb.addTemplate( "caller", '' ); const expected = "ok"; expect(qweb.renderToString("caller")).toBe(expected); }); test("with used body", () => { const qweb = new QWeb(); qweb.addTemplate("_callee-printsbody", ''); qweb.addTemplate("caller", 'ok'); const expected = "ok"; expect(qweb.renderToString("caller")).toBe(expected); }); test("with used set body", () => { const qweb = new QWeb(); qweb.addTemplate("_callee-uses-foo", ''); qweb.addTemplate( "caller", ` ` ); const expected = "ok"; expect(qweb.renderToString("caller")).toBe(expected); }); test("inherit context", () => { const qweb = new QWeb(); qweb.addTemplate("_callee-uses-foo", ''); qweb.addTemplate( "caller", ` ` ); const expected = "1"; expect(qweb.renderToString("caller")).toBe(expected); }); test("scoped parameters", () => { const qweb = new QWeb(); qweb.addTemplate("_basic-callee", `ok`); qweb.addTemplate( "caller", ` ` ); const expected = "ok"; expect(qweb.renderToString("caller").trim()).toBe(expected); }); }); describe("foreach", () => { test("iterate on items", () => { const template = ` [: ] `; const expected = `[0: 3 3]\n \n [1: 2 2]\n \n [2: 1 1]`; expect(renderToString(template).trim()).toBe(expected); }); test("iterate, position", () => { const template = ` - first last () `; const expected = `- first (even)\n \n - (odd)\n \n - (even)\n \n - (odd)\n \n - last (even)`; expect(renderToString(template).trim()).toBe(expected); }); test("iterate, integer param", () => { const template = ` [: ] `; const expected = `[0: 0 0]\n \n [1: 1 1]\n \n [2: 2 2]`; expect(renderToString(template).trim()).toBe(expected); }); test("iterate, dict param", () => { const template = ` [: - ]`; const expected = `[0: a 1 - even]\n [1: b 2 - odd]\n [2: c 3 - even]`; expect( renderToString(template, { value: { a: 1, b: 2, c: 3 } }).trim() ).toBe(expected); }); }); describe("misc", () => { test("global", () => { const qweb = new QWeb(); qweb.addTemplate("_callee-asc", ``); qweb.addTemplate( "_callee-uses-foo", `foo default` ); qweb.addTemplate( "_callee-asc-toto", `
toto default
` ); qweb.addTemplate( "caller", ` ` ); const expected = ` 4 aaa foo default bbb 5 aaa foo default bbb 6 aaa foo default bbb
toto default
`.trim(); expect(qweb.renderToString("caller").trim()).toBe(expected); }); }); describe("t-on", () => { test("can bind event handler", () => { let a = 1; const template = ``; const fragment = renderToDOM(template, { add() { a = 3} }); (fragment.firstChild).click(); expect(a).toBe(3); }); test("can bind handlers with arguments", () => { let a = 1; const template = ``; const fragment = renderToDOM(template, { add(n) { a = a + n} }); (fragment.firstChild).click(); expect(a).toBe(6); }); });