import { App, Component, mount, onMounted, onPatched, useRef, useState, xml, } from "../../src/index"; import { logStep, makeTestFixture, nextAppError, nextTick, snapshotEverything } from "../helpers"; snapshotEverything(); let fixture: HTMLElement; beforeEach(() => { fixture = makeTestFixture(); }); describe("refs", () => { test("basic use", async () => { class Test extends Component { static template = xml`
`; button = useRef("div"); } const test = await mount(Test, fixture); expect(test.button.el).toBe(fixture.firstChild); }); test("refs are properly bound in slots", async () => { class Dialog extends Component { static template = xml``; } class Parent extends Component { static template = xml`
`; static components = { Dialog }; state = useState({ val: 0 }); button = useRef("myButton"); doSomething() { this.state.val++; } } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe( '
0
' ); parent.button.el!.click(); await nextTick(); expect(fixture.innerHTML).toBe( '
1
' ); }); test("can use 2 refs with same name in a t-if/t-else situation", async () => { class Test extends Component { static template = xml`
`; state = useState({ value: true }); ref = useRef("coucou"); } const test = await mount(Test, fixture); expect(fixture.innerHTML).toBe("
"); expect(test.ref.el!.tagName).toBe("DIV"); test.state.value = false; await nextTick(); expect(fixture.innerHTML).toBe(""); expect(test.ref.el!.tagName).toBe("SPAN"); test.state.value = true; await nextTick(); expect(fixture.innerHTML).toBe("
"); expect(test.ref.el!.tagName).toBe("DIV"); }); test("ref is unset when t-if goes to false after unrelated render", async () => { class Comp extends Component { static template = xml`
`; state = useState({ show: true, class: "test" }); ref = useRef("coucou"); } const comp = await mount(Comp, fixture); expect(comp.ref.el).not.toBeNull(); comp.state.class = "test2"; await nextTick(); comp.state.show = false; await nextTick(); expect(comp!.ref.el).toBeNull(); comp.state.show = true; await nextTick(); expect(comp!.ref.el).not.toBeNull(); }); test("throws if there are 2 same refs at the same time", async () => { const consoleWarn = console.warn; console.warn = jest.fn(); class Test extends Component { static template = xml`
`; state = useState({ value: true }); ref = useRef("coucou"); } const app = new App(Test, { test: true }); const appError = nextAppError(app); const mountProm = expect(app.mount(fixture)).rejects.toThrowError( 'Cannot set the same ref more than once in the same component, ref "coucou" was set multiple times in Test' ); await expect(appError).resolves.toThrow( 'Cannot set the same ref more than once in the same component, ref "coucou" was set multiple times in Test' ); await mountProm; expect(console.warn).toBeCalledTimes(1); console.warn = consoleWarn; }); test("refs and recursive templates", async () => { class Test extends Component { static components = {}; static template = xml`

`; root = useRef("root"); setup() { onMounted(() => logStep(this.root.el!.outerHTML)); } } Test.components = { Test }; const tree = { value: "a", child: { value: "b", child: null } }; await mount(Test, fixture, { props: { tree } }); expect(fixture.innerHTML).toBe("

a

b

"); expect(["

b

", "

a

b

"]).toBeLogged(); }); test("refs and t-key", async () => { let el; class Test extends Component { static components = {}; static template = xml`