import { renderToBdom, renderToString, snapshotEverything, TestContext, makeTestFixture, } from "../helpers"; import { mount, patch } from "../../src/runtime/blockdom"; snapshotEverything(); // ----------------------------------------------------------------------------- // t-foreach // ----------------------------------------------------------------------------- describe("t-foreach", () => { test("simple iteration", () => { const template = ``; expect(renderToString(template)).toBe("321"); }); test("simple iteration with two nodes inside", () => { const template = ` a b `; const expected = "a3b3a2b2a1b1"; expect(renderToString(template)).toBe(expected); }); test("t-key on t-foreach", async () => { const template = `
`; const fixture = makeTestFixture(); const vnode1 = renderToBdom(template, { things: [1, 2] }); mount(vnode1, fixture); let elm = fixture; expect(elm.innerHTML).toBe("
"); const first = elm.querySelectorAll("span")[0]; const second = elm.querySelectorAll("span")[1]; const vnode2 = renderToBdom(template, { things: [2, 1] }); patch(vnode1, vnode2); expect(elm.innerHTML).toBe("
"); expect(first).toBe(elm.querySelectorAll("span")[1]); expect(second).toBe(elm.querySelectorAll("span")[0]); }); test("simple iteration (in a node)", () => { const template = `
`; expect(renderToString(template)).toBe("
321
"); }); test("iterate on items", () => { const template = `
[: ]
`; expect(renderToString(template)).toBe("
[0: 3 3] [1: 2 2] [2: 1 1]
"); }); test("iterate on items (on a element node)", () => { const template = `
`; const expected = `
12
`; expect(renderToString(template)).toBe(expected); }); test("iterate, position", () => { const template = `
- first last ()
`; const expected = `
- first (0) - (1) - (2) - (3) - last (4)
`; expect(renderToString(template)).toBe(expected); }); test("iterate, dict param", () => { const template = `
[: ]
`; const expected = `
[0: a 1] [1: b 2] [2: c 3]
`; const context = { value: { a: 1, b: 2, c: 3 } }; expect(renderToString(template, context)).toBe(expected); }); test("iterate, Map param", () => { const template = ` [: ] `; const expected = ` [0: a 1] [1: b 2] [2: c 3] `; const context = { value: new Map([ ["a", 1], ["b", 2], ["c", 3], ]), }; expect(renderToString(template, context)).toBe(expected); }); test("iterate, Set param", () => { const template = ` [: ] `; const expected = ` [0: 1 1] [1: 2 2] [2: 3 3] `; const context = { value: new Set([1, 2, 3]) }; expect(renderToString(template, context)).toBe(expected); }); test("iterate, iterable param", () => { const template = ` [: ] `; const expected = ` [0: 1 1] [1: 2 2] [2: 3 3] `; const context = { map: new Map([ ["a", 1], ["b", 2], ["c", 3], ]), }; expect(renderToString(template, context)).toBe(expected); }); test("iterate, generator param", () => { const template = ` [: ] `; const expected = ` [0: 1 1] [1: 2 2] [2: 3 3] `; const context = { *gen() { yield 1; yield 2; yield 3; }, }; expect(renderToString(template, context)).toBe(expected); }); test("does not pollute the rendering context", () => { const template = `
`; const context = { __owl__: {} }; renderToString(template, context); expect(Object.keys(context)).toEqual(["__owl__"]); }); test("t-foreach in t-foreach", () => { const template = `
[]
`; const context = { numbers: [1, 2, 3], letters: ["a", "b"] }; const expected = "
[1a] [1b] [2a] [2b] [3a] [3b]
"; expect(renderToString(template, context)).toBe(expected); }); test("t-call without body in t-foreach in t-foreach", () => { const context = new TestContext(); const sub = ` [] [] [] `; const main = `
[][][]
`; context.addTemplate("sub", sub); context.addTemplate("main", main); const ctx = { numbers: [1, 2, 3], letters: ["a", "b"] }; const expected = "
[1] [a] [x_1_a] [1] [b] [x_1_b] [2] [a] [x_2_a] [2] [b] [x_2_b] [3] [a] [x_3_a] [3] [b] [x_3_b] [][][]
"; expect(context.renderToString("main", ctx)).toBe(expected); }); test("t-call with body in t-foreach in t-foreach", () => { const context = new TestContext(); const sub = ` [] [] [] `; const main = `
[][][]
`; context.addTemplate("sub", sub); context.addTemplate("main", main); const ctx = { numbers: [1, 2, 3], letters: ["a", "b"] }; const expected = "
[1] [a] [x_1_a] [1] [b] [x_1_b] [2] [a] [x_2_a] [2] [b] [x_2_b] [3] [a] [x_3_a] [3] [b] [x_3_b] [][][]
"; expect(context.renderToString("main", ctx)).toBe(expected); }); test("throws error if invalid loop expression", () => { const test = `
`; expect(() => renderToString(test)).toThrow( 'Invalid loop expression: "undefined" is not iterable' ); }); test("t-foreach with t-if inside", () => { const template = `
`; const ctx = { elems: [ { id: 1, text: "a" }, { id: 2, text: "b" }, { id: 3, text: "c" }, ], }; expect(renderToString(template, ctx)).toBe("
ab
"); }); test("t-foreach with t-if inside (no external node)", () => { const template = ` `; const ctx = { elems: [ { id: 1, text: "a" }, { id: 2, text: "b" }, { id: 3, text: "c" }, ], }; expect(renderToString(template, ctx)).toBe("ab"); }); test("with t-memo", () => { const items = [ { id: 1, x: 1, y: 1 }, { id: 2, x: 1, y: 1 }, ]; const template = `

`; const expected = `

11

11

`; expect(renderToString(template, { items })).toBe(expected); }); });