import { Component, mount, onMounted, useState, xml } from "../../src/index";
import { elem, logStep, makeTestFixture, nextTick, snapshotEverything } from "../helpers";
import { status } from "../../src/runtime/status";
snapshotEverything();
let fixture: HTMLElement;
beforeEach(() => {
fixture = makeTestFixture();
});
describe("t-on", () => {
test("t-on on destroyed components", async () => {
const steps: string[] = [];
let child: any;
class Child extends Component {
static template = xml`
`;
setup() {
onMounted(() => {
child = this;
});
}
onClick() {
steps.push("click");
}
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
state = useState({ flag: true });
}
const parent = await mount(Parent, fixture);
let el = elem(child!);
el.click();
expect(steps).toEqual(["click"]);
(parent as any).state.flag = false;
await nextTick();
expect(status(child as any)).toBe("destroyed");
el.click();
expect(steps).toEqual(["click"]);
});
test("t-on when first component child is an empty component", async () => {
class Child extends Component {
static template = xml`
`;
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
list = useState([] as string[]);
push() {
this.list.push("foo");
}
}
const parent = await mount(Parent, fixture);
const el = elem(parent);
expect(el.innerHTML).toBe("");
el.click();
await nextTick();
expect(el.innerHTML).toBe("foo");
});
test("t-on expression in t-foreach", async () => {
class Comp extends Component {
static template = xml`
`;
state = useState({ values: ["a", "b"] });
otherState = { vals: [] };
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe(
""
);
expect(comp.otherState.vals).toStrictEqual([]);
const buttons = fixture.querySelectorAll("button");
buttons[0].click();
buttons[1].click();
expect(comp.otherState.vals).toStrictEqual(["a", "b"]);
});
test("t-on expression in t-foreach with t-set", async () => {
class Comp extends Component {
static template = xml`
`;
state = useState({ values: ["a", "b"] });
otherState = { vals: [] };
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe(
""
);
expect(comp.otherState.vals).toStrictEqual([]);
const buttons = fixture.querySelectorAll("button");
buttons[0].click();
buttons[1].click();
expect(comp.otherState.vals).toStrictEqual(["a_nova_0", "b_nova_0_1"]);
});
test("t-on method call in t-foreach", async () => {
class Comp extends Component {
static template = xml`
`;
state = useState({ values: ["a", "b"] });
otherState = { vals: new Array() };
addVal(val: string) {
this.otherState.vals.push(val);
}
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe(
"0: a
1: b
"
);
expect(comp.otherState.vals).toStrictEqual([]);
const buttons = fixture.querySelectorAll("button");
buttons[0].click();
buttons[1].click();
expect(comp.otherState.vals).toStrictEqual(["a", "b"]);
});
test("t-on expression captured in t-foreach", async () => {
class Comp extends Component {
static template = xml`
`;
arr = ["a", "b"];
otherState = { vals: new Array() };
}
const comp = await mount(Comp, fixture);
expect(fixture.innerHTML).toBe(
""
);
expect(comp.otherState.vals).toStrictEqual([]);
const buttons = fixture.querySelectorAll("button");
buttons[0].click();
buttons[1].click();
expect(comp.otherState.vals).toStrictEqual(["0_0", "1_1"]);
});
test("t-on on components", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml``;
static components = { Child };
state = useState({ value: 1 });
increment() {
this.state.value++;
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("");
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
});
test("t-on on components, variation", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
state = useState({ value: 1 });
increment() {
this.state.value++;
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("");
fixture.querySelector("span")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
});
test("t-on on component next to t-on on div", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
state = useState({ value: 1 });
increment() {
this.state.value++;
}
decrement() {
this.state.value--;
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("");
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
});
test("t-on on t-slots", async () => {
class Child extends Component {
static template = xml`
[]
`;
state = useState({ count: 0 });
}
class Parent extends Component {
static template = xml`
something
`;
static components = { Child };
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(" [0] something
");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe(" [1] something
");
});
test("t-on on t-set-slots", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
[]
something
paragraph
`;
static components = { Child };
state = useState({ count: 0 });
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe(" [0] something
paragraph
");
fixture.querySelector("p")!.click();
await nextTick();
expect(fixture.innerHTML).toBe(" [1] something
paragraph
");
});
test("t-on on components, with 'prevent' modifier", async () => {
expect.assertions(4); // 2 snaps and 2 expects
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml``;
static components = { Child };
state = useState({ value: 1 });
increment(ev: MouseEvent) {
expect(ev.defaultPrevented).toBe(true);
this.state.value++;
}
}
await mount(Parent, fixture);
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
});
test("t-on on slot, with 'prevent' modifier", async () => {
class Child extends Component {
static template = xml``;
doSomething(ev: MouseEvent) {
expect(ev.defaultPrevented).toBe(true);
logStep("hey");
}
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
}
await mount(Parent, fixture);
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.innerHTML).toBe("");
expect(["hey"]).toBeLogged();
});
test("t-on on components and t-foreach", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
log(name: string) {
logStep(name);
}
}
await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("John
Raoul
Gérald
");
expect([]).toBeLogged();
fixture.querySelectorAll("div")[0].click();
await nextTick();
expect(["John"]).toBeLogged();
fixture.querySelectorAll("div")[1].click();
await nextTick();
expect(["Raoul"]).toBeLogged();
fixture.querySelectorAll("div")[2].click();
await nextTick();
expect(["Gérald"]).toBeLogged();
});
test("t-on on components, with a handler update", async () => {
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
`;
static components = { Child };
state = useState({ name: "aaron" });
log(name: string) {
logStep(name);
}
}
const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("aaron
");
expect([]).toBeLogged();
fixture.querySelectorAll("div")[0].click();
await nextTick();
expect(["aaron"]).toBeLogged();
parent.state.name = "lucas";
await nextTick();
expect(fixture.innerHTML).toBe("lucas
");
fixture.querySelectorAll("div")[0].click();
await nextTick();
expect(["lucas"]).toBeLogged();
});
});