import { TemplateSet } from "../../src/qweb/template_helpers"; import { mount } from "../../src/blockdom"; import { makeTestFixture, renderToBdom, renderToString, snapshotEverything } from "../helpers"; snapshotEverything(); // ----------------------------------------------------------------------------- // t-on // ----------------------------------------------------------------------------- describe("t-on", () => { function mountToFixture(template: string, ctx: any = {}, node?: any): HTMLDivElement { if (!node) { node = { component: ctx }; ctx.__owl__ = node; } const block = renderToBdom(template, ctx, node); const fixture = makeTestFixture(); mount(block, fixture); return fixture; } test("can bind event handler", () => { const template = ``; let a = 1; const fixture = mountToFixture(template, { add: () => (a = 3) }); expect(a).toBe(1); fixture.querySelector("button")!.click(); expect(a).toBe(3); }); test("receive event in first argument", () => { expect.assertions(2); const template = ``; const fixture = mountToFixture(template, { add: (ev: any) => { expect(ev).toBeInstanceOf(Event); }, }); fixture.querySelector("button")!.click(); }); test("can bind two event handlers", () => { const template = ` `; let steps: string[] = []; const fixture = mountToFixture(template, { handleClick() { steps.push("click"); }, handleDblClick() { steps.push("dblclick"); }, }); expect(steps).toEqual([]); fixture.querySelector("button")!.click(); expect(steps).toEqual(["click"]); fixture.querySelector("button")!.dispatchEvent(new Event("dblclick", { bubbles: true })); expect(steps).toEqual(["click", "dblclick"]); }); test("can bind handlers with arguments", () => { const template = ``; let a = 1; const fixture = mountToFixture(template, { add: (n: number) => (a = a + n) }); expect(a).toBe(1); fixture.querySelector("button")!.click(); expect(a).toBe(6); }); test("can bind handlers with object arguments", () => { const template = ``; let a = 1; const fixture = mountToFixture(template, { add: ({ val }: any) => (a = a + val) }); expect(a).toBe(1); fixture.querySelector("button")!.click(); expect(a).toBe(6); }); test("can bind handlers with empty object", () => { expect.assertions(2); const template = ``; const fixture = mountToFixture(template, { doSomething(arg: any) { expect(arg).toEqual({}); }, }); fixture.querySelector("button")!.click(); }); test("can bind handlers with empty object (with non empty inner string)", () => { expect.assertions(2); const template = ``; const fixture = mountToFixture(template, { doSomething(arg: any) { expect(arg).toEqual({}); }, }); fixture.querySelector("button")!.click(); }); test("can bind handlers with empty object (with non empty inner string)", () => { expect.assertions(2); const template = ` `; const fixture = mountToFixture(template, { activate(action: string) { expect(action).toBe("someval"); }, }); fixture.querySelector("a")!.click(); }); test("handler is bound to proper owner", () => { expect.assertions(2); const template = ``; let owner = { add() { expect(this).toBe(owner); }, }; const fixture = mountToFixture(template, owner); fixture.querySelector("button")!.click(); }); test("handler is bound to proper owner, part 2", () => { expect.assertions(2); const template = ` `; let owner = { add() { expect(this).toBe(owner); }, }; const fixture = mountToFixture(template, owner); fixture.querySelector("button")!.click(); }); test("handler is bound to proper owner, part 3", () => { expect.assertions(3); const context = new TemplateSet(); const sub = ``; const main = ``; context.addTemplate("sub", sub); context.addTemplate("main", main); let owner: any = { add() { expect(this).toBe(owner); }, }; const node = { component: owner }; owner.__owl__ = node; const fixture = makeTestFixture(); const render = context.getTemplate("main"); const bdom = render(owner, node); mount(bdom, fixture); fixture.querySelector("button")!.click(); }); test("handler is bound to proper owner, part 4", () => { expect.assertions(3); const context = new TemplateSet(); const sub = ``; const main = ` `; context.addTemplate("sub", sub); context.addTemplate("main", main); let owner: any = { add() { expect(this).toBe(owner); }, }; const node = { component: owner }; owner.__owl__ = node; const fixture = makeTestFixture(); const render = context.getTemplate("main"); const bdom = render(owner, node); mount(bdom, fixture); fixture.querySelector("button")!.click(); }); test("t-on with inline statement", () => { const template = ``; let owner = { state: { counter: 0 } }; const fixture = mountToFixture(template, owner); expect(owner.state.counter).toBe(0); fixture.querySelector("button")!.click(); expect(owner.state.counter).toBe(1); }); test("t-on with inline statement (function call)", () => { const template = ``; let owner = { state: { counter: 0, incrementCounter: (inc: number) => { owner.state.counter += inc; }, }, }; const fixture = mountToFixture(template, owner); expect(owner.state.counter).toBe(0); fixture.querySelector("button")!.click(); expect(owner.state.counter).toBe(2); }); test("t-on with inline statement, part 2", () => { const template = ``; let owner = { state: { flag: true, }, }; const fixture = mountToFixture(template, owner); expect(owner.state.flag).toBe(true); fixture.querySelector("button")!.click(); expect(owner.state.flag).toBe(false); fixture.querySelector("button")!.click(); expect(owner.state.flag).toBe(true); }); test("t-on with inline statement, part 3", () => { const template = ``; let owner = { someFunction(n: number) { return n + 1; }, state: { n: 11, }, }; const fixture = mountToFixture(template, owner); expect(owner.state.n).toBe(11); fixture.querySelector("button")!.click(); expect(owner.state.n).toBe(4); }); test("t-on with t-call", async () => { expect.assertions(3); const app = new TemplateSet(); const sub = `

lucas

`; const main = `
`; app.addTemplate("sub", sub); app.addTemplate("main", main); let owner: any = { update() { expect(this).toBe(owner); }, }; const node = { component: owner }; owner.__owl__ = node; const fixture = makeTestFixture(); const render = app.getTemplate("main"); const bdom = render(owner, node); mount(bdom, fixture); fixture.querySelector("p")!.click(); }); test("t-on, with arguments and t-call", async () => { expect.assertions(4); const app = new TemplateSet(); const sub = `

lucas

`; const main = `
`; app.addTemplate("sub", sub); app.addTemplate("main", main); let owner: any = { update(val: number) { expect(this).toBe(owner); expect(val).toBe(444); }, value: 444, }; const node = { component: owner }; owner.__owl__ = node; const fixture = makeTestFixture(); const render = app.getTemplate("main"); const bdom = render(owner, node); mount(bdom, fixture); fixture.querySelector("p")!.click(); }); test("nice error when t-on is evaluated with a missing event", () => { const template = `
`; expect(() => renderToString(template, { someMethod() {} })).toThrow( "Missing event name with t-on directive" ); }); });