import { makeTestFixture, snapshotEverything, nextTick, logStep, nextMicroTick } from "../helpers"; import { mount, Component, useState, xml, App } from "../../src/index"; snapshotEverything(); let fixture: HTMLElement; beforeEach(() => { fixture = makeTestFixture(); }); describe("event handling", () => { test("handler receive the event as argument", async () => { class Child extends Component { static template = xml`
simple vnode
`; } class Parent extends Component { static template = xml``; static components = { Child }; state = useState({ value: 1 }); inc(ev: any) { this.state.value++; expect(ev.type).toBe("click"); } } await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
simple vnode
1
"); fixture.querySelector("div")!.click(); await nextTick(); expect(fixture.innerHTML).toBe("
simple vnode
2
"); }); test("Invalid handler throws an error", async () => { window.addEventListener( "error", (ev) => { logStep(ev.error.message); ev.preventDefault(); }, { once: true } ); class Parent extends Component { static template = xml``; doSomething() {} } await mount(Parent, fixture); expect([]).toBeLogged(); fixture.querySelector("button")!.click(); expect(["Invalid handler (expected a function, received: 'undefined')"]).toBeLogged(); }); test("support for callable expression in event handler", async () => { class Counter extends Component { static template = xml`
`; state = useState({ value: "" }); obj = { onInput: (ev: any) => (this.state.value = ev.target.value) }; } await mount(Counter, fixture); await nextTick(); expect(fixture.innerHTML).toBe(`
`); const input = fixture.getElementsByTagName("input")[0]; input.value = "test"; input.dispatchEvent(new Event("input")); await nextTick(); expect(fixture.innerHTML).toBe(`
test
`); }); test("t-on with handler bound to dynamic argument on a t-foreach", async () => { let onClickArgs: [number, MouseEvent] | null = null; class Parent extends Component { static template = xml`
`; items = [1, 2, 3, 4]; onClick(n: number, ev: MouseEvent) { onClickArgs = [n, ev]; } } await mount(Parent, fixture); expect(onClickArgs).toBeNull(); (fixture.querySelector(".item")).click(); expect(onClickArgs![0]).toBe(1); expect(onClickArgs![1]).toBeInstanceOf(MouseEvent); }); test("objects from scope are properly captured by t-on", async () => { let onClickArgs: [number, MouseEvent] | null = null; class Parent extends Component { static template = xml`
`; items = [{ val: 1 }, { val: 2 }, { val: 3 }, { val: 4 }]; onClick(n: number, ev: MouseEvent) { onClickArgs = [n, ev]; } } await mount(Parent, fixture); expect(onClickArgs).toBeNull(); (fixture.querySelector(".item")).click(); expect(onClickArgs![0]).toBe(1); expect(onClickArgs![1]).toBeInstanceOf(MouseEvent); }); test("handler is not called if component is destroyed", async () => { class Parent extends Component { static template = xml``; click() { logStep("click"); } } const app = new App(Parent); await app.mount(fixture); const span = fixture.querySelector("span")!; span.click(); expect(["click"]).toBeLogged(); app.destroy(); expect([]).toBeLogged(); span.click(); expect([]).toBeLogged(); }); test("input blur event is not called if component is destroyed", async () => { class Child extends Component { static template = xml``; blur() { logStep("blur"); } } class Parent extends Component { static template = xml`