import { Component, mount, useState } from "../../src"; import { xml } from "../../src/tags"; import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; let fixture: HTMLElement; snapshotEverything(); beforeEach(() => { fixture = makeTestFixture(); }); describe("t-component", () => { test("t-component works in simple case", async () => { let steps: string[] = []; class Child extends Component { static template = xml`
child
`; setup() { useLogLifecycle(steps); } } class Parent extends Component { static template = xml``; Child = Child; setup() { useLogLifecycle(steps); } } await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
child
"); expect(steps).toEqual([ "Parent:setup", "Parent:willStart", "Parent:render", "Child:setup", "Child:willStart", "Child:render", "Child:mounted", "Parent:mounted", ]); }); test("switching dynamic component", async () => { let steps: string[] = []; class ChildA extends Component { static template = xml`
child a
`; setup() { useLogLifecycle(steps); } } class ChildB extends Component { static template = xml`child b`; setup() { useLogLifecycle(steps); } } class Parent extends Component { static template = xml``; Child = ChildA; setup() { useLogLifecycle(steps); } } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
child a
"); parent.Child = ChildB; parent.render(); await nextTick(); expect(fixture.innerHTML).toBe("child b"); expect(steps).toEqual([ "Parent:setup", "Parent:willStart", "Parent:render", "ChildA:setup", "ChildA:willStart", "ChildA:render", "ChildA:mounted", "Parent:mounted", "Parent:render", "ChildB:setup", "ChildB:willStart", "ChildB:render", "Parent:willPatch", "ChildA:willUnmount", "ChildA:destroyed", "ChildB:mounted", "Parent:patched", ]); }); test("can switch between dynamic components without the need for a t-key", async () => { class A extends Component { static template = xml`child a`; } class B extends Component { static template = xml`child b`; } class App extends Component { static template = xml`
`; static components = { A, B }; state = useState({ child: "A" }); } const app = await mount(App, fixture); expect(fixture.innerHTML).toBe("
child a
"); app.state.child = "B"; await nextTick(); expect(fixture.innerHTML).toBe("
child b
"); }); test("can use dynamic components (the class) if given", async () => { class A extends Component { static template = xml`child a`; } class B extends Component { static template = xml`child b`; } class Parent extends Component { static template = xml``; state = useState({ child: "a", }); get myComponent() { return this.state.child === "a" ? A : B; } } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("child a"); parent.state.child = "b"; await nextTick(); expect(fixture.innerHTML).toBe("child b"); }); test("can use dynamic components (the class) if given (with different root tagname)", async () => { class A extends Component { static template = xml`child a`; } class B extends Component { static template = xml`
child b
`; } class Parent extends Component { static template = xml``; state = useState({ child: "a", }); get myComponent() { return this.state.child === "a" ? A : B; } } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("child a"); parent.state.child = "b"; await nextTick(); expect(fixture.innerHTML).toBe("
child b
"); }); test("modifying a sub widget", async () => { class Counter extends Component { static template = xml`
`; state = useState({ counter: 0, }); } class ParentWidget extends Component { static template = xml`
`; get Counter() { return Counter; } } await mount(ParentWidget, fixture); expect(fixture.innerHTML).toBe("
0
"); const button = fixture.getElementsByTagName("button")[0]; await button.click(); await nextTick(); expect(fixture.innerHTML).toBe("
1
"); }); });