lifecycle-snapshots

This commit is contained in:
Samuel Degueldre
2023-09-29 13:28:14 +02:00
parent b1690f19cc
commit 9c40ee67e1
17 changed files with 3330 additions and 2508 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ exports[`app app: clear scheduler tasks and destroy cancelled nodes immediately
}" }"
`; `;
exports[`app app: clear scheduler tasks and destroy cancelled nodes immediately on destroy 2`] = ` exports[`app app: clear scheduler tasks and destroy cancelled nodes immediately on destroy 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+31 -6
View File
@@ -8,6 +8,7 @@ import {
useLogLifecycle, useLogLifecycle,
makeDeferred, makeDeferred,
nextMicroTick, nextMicroTick,
steps,
} from "../helpers"; } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -123,23 +124,47 @@ describe("app", () => {
const app = new App(A); const app = new App(A);
const comp = await app.mount(fixture); const comp = await app.mount(fixture);
expect(["A:setup", "A:willStart", "A:willRender", "A:rendered", "A:mounted"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:setup",
"A:willStart",
"A:willRender",
"A:rendered",
"A:mounted",
]
`);
comp.state.value = true; comp.state.value = true;
await nextTick(); await nextTick();
expect(["A:willRender", "B:setup", "B:willStart", "A:rendered"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
]
`);
// rerender to force the instantiation of a new B component (and cancelling the first) // rerender to force the instantiation of a new B component (and cancelling the first)
comp.render(); comp.render();
await nextMicroTick(); await nextMicroTick();
expect(["A:willRender", "B:setup", "B:willStart", "A:rendered"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willRender",
"B:setup",
"B:willStart",
"A:rendered",
]
`);
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willUnmount", "A:willUnmount",
"B:willDestroy", "B:willDestroy",
"A:willDestroy", "A:willDestroy",
"B:willDestroy", // make sure the 2 B instances have been destroyed synchronously "B:willDestroy",
]).toBeLogged(); ]
`);
}); });
}); });
@@ -184,7 +184,7 @@ exports[`changing state before first render does not trigger a render (with pare
}" }"
`; `;
exports[`changing state before first render does not trigger a render (with parent) 2`] = ` exports[`changing state before first render does not trigger a render (with parent) 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -254,7 +254,7 @@ exports[`components are not destroyed between animation frame 1`] = `
}" }"
`; `;
exports[`components are not destroyed between animation frame 2`] = ` exports[`components are not destroyed between animation frame 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -268,7 +268,7 @@ exports[`components are not destroyed between animation frame 2`] = `
}" }"
`; `;
exports[`components are not destroyed between animation frame 3`] = ` exports[`components are not destroyed between animation frame 5`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -748,7 +748,7 @@ exports[`concurrent renderings scenario 10 2`] = `
}" }"
`; `;
exports[`concurrent renderings scenario 10 3`] = ` exports[`concurrent renderings scenario 10 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -993,7 +993,7 @@ exports[`concurrent renderings scenario 16 3`] = `
}" }"
`; `;
exports[`concurrent renderings scenario 16 4`] = ` exports[`concurrent renderings scenario 16 6`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1024,7 +1024,7 @@ exports[`creating two async components, scenario 1 1`] = `
}" }"
`; `;
exports[`creating two async components, scenario 1 2`] = ` exports[`creating two async components, scenario 1 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1038,7 +1038,7 @@ exports[`creating two async components, scenario 1 2`] = `
}" }"
`; `;
exports[`creating two async components, scenario 1 3`] = ` exports[`creating two async components, scenario 1 5`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1085,7 +1085,7 @@ exports[`creating two async components, scenario 2 2`] = `
}" }"
`; `;
exports[`creating two async components, scenario 2 3`] = ` exports[`creating two async components, scenario 2 5`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1133,7 +1133,7 @@ exports[`creating two async components, scenario 3 (patching in the same frame)
}" }"
`; `;
exports[`creating two async components, scenario 3 (patching in the same frame) 3`] = ` exports[`creating two async components, scenario 3 (patching in the same frame) 5`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1308,7 +1308,7 @@ exports[`delayed render does not go through when t-component value changed 2`] =
}" }"
`; `;
exports[`delayed render does not go through when t-component value changed 3`] = ` exports[`delayed render does not go through when t-component value changed 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1617,7 +1617,7 @@ exports[`destroyed component causes other soon to be destroyed component to rere
}" }"
`; `;
exports[`destroyed component causes other soon to be destroyed component to rerender, weird stuff happens 2`] = ` exports[`destroyed component causes other soon to be destroyed component to rerender, weird stuff happens 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1628,7 +1628,7 @@ exports[`destroyed component causes other soon to be destroyed component to rere
}" }"
`; `;
exports[`destroyed component causes other soon to be destroyed component to rerender, weird stuff happens 3`] = ` exports[`destroyed component causes other soon to be destroyed component to rerender, weird stuff happens 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1656,7 +1656,7 @@ exports[`destroying/recreating a subcomponent, other scenario 1`] = `
}" }"
`; `;
exports[`destroying/recreating a subcomponent, other scenario 2`] = ` exports[`destroying/recreating a subcomponent, other scenario 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1685,7 +1685,7 @@ exports[`destroying/recreating a subwidget with different props (if start is not
}" }"
`; `;
exports[`destroying/recreating a subwidget with different props (if start is not over) 2`] = ` exports[`destroying/recreating a subwidget with different props (if start is not over) 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -1787,7 +1787,7 @@ exports[`rendering component again in next microtick 1`] = `
}" }"
`; `;
exports[`rendering component again in next microtick 2`] = ` exports[`rendering component again in next microtick 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -241,7 +241,7 @@ exports[`can catch errors an error in onWillDestroy, variation 1`] = `
}" }"
`; `;
exports[`can catch errors an error in onWillDestroy, variation 2`] = ` exports[`can catch errors an error in onWillDestroy, variation 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -92,7 +92,7 @@ exports[`lifecycle hooks component semantics 5`] = `
}" }"
`; `;
exports[`lifecycle hooks component semantics 6`] = ` exports[`lifecycle hooks component semantics 7`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -185,7 +185,7 @@ exports[`lifecycle hooks destroy new children before being mountged 1`] = `
}" }"
`; `;
exports[`lifecycle hooks destroy new children before being mountged 2`] = ` exports[`lifecycle hooks destroy new children before being mountged 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -291,7 +291,7 @@ exports[`lifecycle hooks lifecycle semantics, part 2 1`] = `
}" }"
`; `;
exports[`lifecycle hooks lifecycle semantics, part 2 2`] = ` exports[`lifecycle hooks lifecycle semantics, part 2 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -303,7 +303,7 @@ exports[`lifecycle hooks lifecycle semantics, part 2 2`] = `
}" }"
`; `;
exports[`lifecycle hooks lifecycle semantics, part 2 3`] = ` exports[`lifecycle hooks lifecycle semantics, part 2 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -348,7 +348,7 @@ exports[`lifecycle hooks lifecycle semantics, part 4 1`] = `
}" }"
`; `;
exports[`lifecycle hooks lifecycle semantics, part 4 2`] = ` exports[`lifecycle hooks lifecycle semantics, part 4 3`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -360,7 +360,7 @@ exports[`lifecycle hooks lifecycle semantics, part 4 2`] = `
}" }"
`; `;
exports[`lifecycle hooks lifecycle semantics, part 4 3`] = ` exports[`lifecycle hooks lifecycle semantics, part 4 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
@@ -180,7 +180,7 @@ exports[`t-component switching dynamic component 2`] = `
}" }"
`; `;
exports[`t-component switching dynamic component 3`] = ` exports[`t-component switching dynamic component 4`] = `
"function anonymous(app, bdom, helpers "function anonymous(app, bdom, helpers
) { ) {
let { text, createBlock, list, multi, html, toggler, comment } = bdom; let { text, createBlock, list, multi, html, toggler, comment } = bdom;
+29 -10
View File
@@ -5,6 +5,7 @@ import {
nextAppError, nextAppError,
nextTick, nextTick,
snapshotEverything, snapshotEverything,
steps,
useLogLifecycle, useLogLifecycle,
} from "../helpers"; } from "../helpers";
import { markup } from "../../src/runtime/utils"; import { markup } from "../../src/runtime/utils";
@@ -868,19 +869,26 @@ describe("basics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
]).toBeLogged(); ]
`);
parent.ifVar = false; parent.ifVar = false;
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(Object.keys(parent.__owl__.children).length).toStrictEqual(0); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(0);
expect(["Child:willUnmount", "Child:willDestroy"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willUnmount",
"Child:willDestroy",
]
`);
}); });
test("component children doesn't leak (t-key case)", async () => { test("component children doesn't leak (t-key case)", async () => {
@@ -899,19 +907,22 @@ describe("basics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
]).toBeLogged(); ]
`);
parent.keyVar = 2; parent.keyVar = 2;
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Child:willRender", "Child:willRender",
@@ -919,7 +930,8 @@ describe("basics", () => {
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Child:mounted", "Child:mounted",
]).toBeLogged(); ]
`);
}); });
test("GrandChild display is controlled by its GrandParent", async () => { test("GrandChild display is controlled by its GrandParent", async () => {
@@ -943,20 +955,27 @@ describe("basics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div></div>"); expect(fixture.innerHTML).toBe("<div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"GrandChild:setup", "GrandChild:setup",
"GrandChild:willStart", "GrandChild:willStart",
"GrandChild:willRender", "GrandChild:willRender",
"GrandChild:rendered", "GrandChild:rendered",
"GrandChild:mounted", "GrandChild:mounted",
]).toBeLogged(); ]
`);
parent.displayGrandChild = false; parent.displayGrandChild = false;
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect(["GrandChild:willUnmount", "GrandChild:willDestroy"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"GrandChild:willUnmount",
"GrandChild:willDestroy",
]
`);
}); });
}); });
File diff suppressed because it is too large Load Diff
+43 -19
View File
@@ -19,6 +19,7 @@ import {
snapshotEverything, snapshotEverything,
useLogLifecycle, useLogLifecycle,
nextAppError, nextAppError,
steps,
} from "../helpers"; } from "../helpers";
import { OwlError } from "../../src/common/owl_error"; import { OwlError } from "../../src/common/owl_error";
@@ -948,7 +949,8 @@ describe("can catch errors", () => {
} }
await mount(Root, fixture); await mount(Root, fixture);
expect(fixture.innerHTML).toBe("<div><div>Error handled</div></div>"); expect(fixture.innerHTML).toBe("<div><div>Error handled</div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Root:setup", "Root:setup",
"Root:willStart", "Root:willStart",
"Root:willRender", "Root:willRender",
@@ -967,7 +969,8 @@ describe("can catch errors", () => {
"ErrorBoundary:rendered", "ErrorBoundary:rendered",
"ErrorBoundary:mounted", "ErrorBoundary:mounted",
"Root:mounted", "Root:mounted",
]).toBeLogged(); ]
`);
expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0);
}); });
@@ -998,7 +1001,8 @@ describe("can catch errors", () => {
} }
await mount(Root, fixture); await mount(Root, fixture);
expect(fixture.innerHTML).toBe("<div>Error handled</div>"); expect(fixture.innerHTML).toBe("<div>Error handled</div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Root:setup", "Root:setup",
"Root:willStart", "Root:willStart",
"Root:willRender", "Root:willRender",
@@ -1012,7 +1016,8 @@ describe("can catch errors", () => {
"Root:willRender", "Root:willRender",
"Root:rendered", "Root:rendered",
"Root:mounted", "Root:mounted",
]).toBeLogged(); ]
`);
expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0);
}); });
@@ -1059,7 +1064,8 @@ describe("can catch errors", () => {
} }
await mount(A, fixture); await mount(A, fixture);
expect(fixture.innerHTML).toBe("<div><div>Error handled</div></div>"); expect(fixture.innerHTML).toBe("<div><div>Error handled</div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:setup", "A:setup",
"A:willStart", "A:willStart",
"A:willRender", "A:willRender",
@@ -1083,7 +1089,8 @@ describe("can catch errors", () => {
"C:mounted", "C:mounted",
"B:mounted", "B:mounted",
"A:mounted", "A:mounted",
]).toBeLogged(); ]
`);
expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0);
}); });
@@ -1130,7 +1137,8 @@ describe("can catch errors", () => {
} }
await mount(Root, fixture); await mount(Root, fixture);
expect(fixture.innerHTML).toBe("<div>OK<div>Error handled</div></div>"); expect(fixture.innerHTML).toBe("<div>OK<div>Error handled</div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Root:setup", "Root:setup",
"Root:willStart", "Root:willStart",
"Root:willRender", "Root:willRender",
@@ -1154,7 +1162,8 @@ describe("can catch errors", () => {
"ErrorBoundary:mounted", "ErrorBoundary:mounted",
"OK:mounted", "OK:mounted",
"Root:mounted", "Root:mounted",
]).toBeLogged(); ]
`);
expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleError).toBeCalledTimes(0);
expect(mockConsoleWarn).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0);
}); });
@@ -1481,7 +1490,8 @@ describe("can catch errors", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("1<div>abc</div>"); expect(fixture.innerHTML).toBe("1<div>abc</div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -1492,13 +1502,15 @@ describe("can catch errors", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = false; parent.state.hasChild = false;
await nextTick(); await nextTick();
await nextTick(); await nextTick();
await nextTick(); await nextTick();
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
@@ -1509,7 +1521,8 @@ describe("can catch errors", () => {
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("2"); expect(fixture.innerHTML).toBe("2");
}); });
@@ -1542,13 +1555,15 @@ describe("can catch errors", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("1"); expect(fixture.innerHTML).toBe("1");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = true; parent.state.hasChild = true;
await nextMicroTick(); await nextMicroTick();
@@ -1556,26 +1571,35 @@ describe("can catch errors", () => {
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
"Parent:rendered", "Parent:rendered",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
]).toBeLogged(); ]
`);
parent.state.hasChild = false; parent.state.hasChild = false;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Child:willDestroy", "Child:willDestroy",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("1"); expect(fixture.innerHTML).toBe("1");
await nextTick(); await nextTick();
expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willPatch",
"Parent:patched",
]
`);
expect(fixture.innerHTML).toBe("2"); expect(fixture.innerHTML).toBe("2");
}); });
}); });
+166 -73
View File
@@ -17,6 +17,7 @@ import {
nextMicroTick, nextMicroTick,
nextTick, nextTick,
snapshotEverything, snapshotEverything,
steps,
useLogLifecycle, useLogLifecycle,
} from "../helpers"; } from "../helpers";
@@ -455,7 +456,8 @@ describe("lifecycle hooks", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div><span>0</span></div>"); expect(fixture.innerHTML).toBe("<div><span>0</span></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -466,12 +468,14 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.increment(); parent.increment();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><span>1</span></div>"); expect(fixture.innerHTML).toBe("<div><span>1</span></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:willUpdateProps", "Child:willUpdateProps",
"Parent:rendered", "Parent:rendered",
@@ -481,19 +485,22 @@ describe("lifecycle hooks", () => {
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
parent.toggleSubWidget(); parent.toggleSubWidget();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("hooks are called in proper order in widget creation/destruction", async () => { test("hooks are called in proper order in widget creation/destruction", async () => {
@@ -514,7 +521,8 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
await app.mount(fixture); await app.mount(fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -525,15 +533,18 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willUnmount", "Parent:willUnmount",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:willDestroy", "Parent:willDestroy",
]).toBeLogged(); ]
`);
}); });
test("willUpdateProps hook is called", async () => { test("willUpdateProps hook is called", async () => {
@@ -632,7 +643,8 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
await app.mount(fixture); await app.mount(fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -643,15 +655,18 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willUnmount", "Parent:willUnmount",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:willDestroy", "Parent:willDestroy",
]).toBeLogged(); ]
`);
}); });
test("lifecycle semantics, part 2", async () => { test("lifecycle semantics, part 2", async () => {
@@ -680,17 +695,20 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
const parent = await app.mount(fixture); const parent = await app.mount(fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = true; parent.state.hasChild = true;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
@@ -705,17 +723,20 @@ describe("lifecycle hooks", () => {
"GrandChild:mounted", "GrandChild:mounted",
"Child:mounted", "Child:mounted",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willUnmount", "Parent:willUnmount",
"Child:willUnmount", "Child:willUnmount",
"GrandChild:willUnmount", "GrandChild:willUnmount",
"GrandChild:willDestroy", "GrandChild:willDestroy",
"Child:willDestroy", "Child:willDestroy",
"Parent:willDestroy", "Parent:willDestroy",
]).toBeLogged(); ]
`);
}); });
test("lifecycle semantics, part 3", async () => { test("lifecycle semantics, part 3", async () => {
@@ -744,19 +765,26 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
const parent = await app.mount(fixture); const parent = await app.mount(fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = true; parent.state.hasChild = true;
// immediately destroy everything // immediately destroy everything
app.destroy(); app.destroy();
await nextTick(); await nextTick();
expect(["Parent:willUnmount", "Parent:willDestroy"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willUnmount",
"Parent:willDestroy",
]
`);
}); });
test("lifecycle semantics, part 4", async () => { test("lifecycle semantics, part 4", async () => {
@@ -789,17 +817,20 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
const parent = await app.mount(fixture); const parent = await app.mount(fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = true; parent.state.hasChild = true;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
@@ -808,15 +839,18 @@ describe("lifecycle hooks", () => {
"GrandChild:setup", "GrandChild:setup",
"GrandChild:willStart", "GrandChild:willStart",
"Child:rendered", "Child:rendered",
]).toBeLogged(); ]
`);
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willUnmount", "Parent:willUnmount",
"GrandChild:willDestroy", "GrandChild:willDestroy",
"Child:willDestroy", "Child:willDestroy",
"Parent:willDestroy", "Parent:willDestroy",
]).toBeLogged(); ]
`);
}); });
test("lifecycle semantics, part 5", async () => { test("lifecycle semantics, part 5", async () => {
@@ -837,7 +871,8 @@ describe("lifecycle hooks", () => {
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -848,18 +883,21 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = false; parent.state.hasChild = false;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("lifecycle semantics, part 6", async () => { test("lifecycle semantics, part 6", async () => {
@@ -880,7 +918,8 @@ describe("lifecycle hooks", () => {
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -891,11 +930,13 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.value = 2; parent.state.value = 2;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:willUpdateProps", "Child:willUpdateProps",
"Parent:rendered", "Parent:rendered",
@@ -905,7 +946,8 @@ describe("lifecycle hooks", () => {
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("onWillRender", async () => { test("onWillRender", async () => {
@@ -937,7 +979,8 @@ describe("lifecycle hooks", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<button>1</button>"); expect(fixture.innerHTML).toBe("<button>1</button>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -948,32 +991,41 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.value++; // to block child render parent.state.value++; // to block child render
await nextTick(); await nextTick();
expect(["Parent:willRender", "Child:willUpdateProps", "Parent:rendered"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender",
"Child:willUpdateProps",
"Parent:rendered",
]
`);
fixture.querySelector("button")!.click(); fixture.querySelector("button")!.click();
await nextTick(); await nextTick();
expect([]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`);
fixture.querySelector("button")!.click(); fixture.querySelector("button")!.click();
await nextTick(); await nextTick();
expect([]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`);
expect(fixture.innerHTML).toBe("<button>1</button>"); expect(fixture.innerHTML).toBe("<button>1</button>");
def.resolve(); def.resolve();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<button>3</button>"); expect(fixture.innerHTML).toBe("<button>3</button>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
// TODO: rename (remove? seems covered by lifecycle semantics) // TODO: rename (remove? seems covered by lifecycle semantics)
@@ -1054,7 +1106,8 @@ describe("lifecycle hooks", () => {
await mount(A, fixture); await mount(A, fixture);
expect(fixture.innerHTML).toBe(`<div>A<div>B</div><div>C<div>D</div><div>E</div></div></div>`); expect(fixture.innerHTML).toBe(`<div>A<div>B</div><div>C<div>D</div><div>E</div></div></div>`);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:setup", "A:setup",
"A:willStart", "A:willStart",
"A:willRender", "A:willRender",
@@ -1080,12 +1133,14 @@ describe("lifecycle hooks", () => {
"C:mounted", "C:mounted",
"B:mounted", "B:mounted",
"A:mounted", "A:mounted",
]).toBeLogged(); ]
`);
// update // update
c!.state.flag = false; c!.state.flag = false;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"C:willRender", "C:willRender",
"F:setup", "F:setup",
"F:willStart", "F:willStart",
@@ -1097,7 +1152,8 @@ describe("lifecycle hooks", () => {
"E:willDestroy", "E:willDestroy",
"F:mounted", "F:mounted",
"C:patched", "C:patched",
]).toBeLogged(); ]
`);
}); });
test("mounted hook is called on every mount, not just the first one", async () => { test("mounted hook is called on every mount, not just the first one", async () => {
@@ -1118,7 +1174,8 @@ describe("lifecycle hooks", () => {
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -1129,22 +1186,26 @@ describe("lifecycle hooks", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.hasChild = false; parent.state.hasChild = false;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
parent.state.hasChild = true; parent.state.hasChild = true;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
@@ -1154,7 +1215,8 @@ describe("lifecycle hooks", () => {
"Parent:willPatch", "Parent:willPatch",
"Child:mounted", "Child:mounted",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("render in mounted", async () => { test("render in mounted", async () => {
@@ -1172,7 +1234,8 @@ describe("lifecycle hooks", () => {
await mount(Parent, fixture); await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<span></span>"); expect(fixture.innerHTML).toBe("<span></span>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -1180,11 +1243,17 @@ describe("lifecycle hooks", () => {
"Parent:mounted", "Parent:mounted",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
]).toBeLogged(); ]
`);
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<span>Patched</span>"); expect(fixture.innerHTML).toBe("<span>Patched</span>");
expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willPatch",
"Parent:patched",
]
`);
}); });
test("render in patched", async () => { test("render in patched", async () => {
@@ -1205,29 +1274,38 @@ describe("lifecycle hooks", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<span></span>"); expect(fixture.innerHTML).toBe("<span></span>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<span></span>"); expect(fixture.innerHTML).toBe("<span></span>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
]).toBeLogged(); ]
`);
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<span>Patched</span>"); expect(fixture.innerHTML).toBe("<span>Patched</span>");
expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willPatch",
"Parent:patched",
]
`);
}); });
test("render in willPatch", async () => { test("render in willPatch", async () => {
@@ -1248,29 +1326,38 @@ describe("lifecycle hooks", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<span></span>"); expect(fixture.innerHTML).toBe("<span></span>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<span></span>"); expect(fixture.innerHTML).toBe("<span></span>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
]).toBeLogged(); ]
`);
await nextTick(); await nextTick();
expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willPatch",
"Parent:patched",
]
`);
expect(fixture.innerHTML).toBe("<span>Patched</span>"); expect(fixture.innerHTML).toBe("<span>Patched</span>");
}); });
@@ -1313,7 +1400,8 @@ describe("lifecycle hooks", () => {
await nextTick(); await nextTick();
app.destroy(); app.destroy();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"onWillStart", "onWillStart",
"onWillRender", "onWillRender",
"onRendered", "onRendered",
@@ -1325,7 +1413,8 @@ describe("lifecycle hooks", () => {
"onPatched", "onPatched",
"onWillUnmount", "onWillUnmount",
"onWillDestroy", "onWillDestroy",
]).toBeLogged(); ]
`);
}); });
test("destroy new children before being mountged", async () => { test("destroy new children before being mountged", async () => {
@@ -1357,19 +1446,22 @@ describe("lifecycle hooks", () => {
const app = new App(Parent); const app = new App(Parent);
const parent = await app.mount(fixture); const parent = await app.mount(fixture);
expect(fixture.innerHTML).toBe("beforeafter"); expect(fixture.innerHTML).toBe("beforeafter");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.flag = true; parent.state.flag = true;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:setup", "Child:setup",
"Child:willStart", "Child:willStart",
@@ -1377,6 +1469,7 @@ describe("lifecycle hooks", () => {
"Parent:willUnmount", "Parent:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:willDestroy", "Parent:willDestroy",
]).toBeLogged(); ]
`);
}); });
}); });
+25 -13
View File
@@ -1,5 +1,5 @@
import { Component, mount, onWillUpdateProps, useState, xml } from "../../src"; import { Component, mount, onWillUpdateProps, useState, xml } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; import { makeTestFixture, nextTick, snapshotEverything, steps, useLogLifecycle } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -272,7 +272,8 @@ test("bound functions are considered 'alike'", async () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("1child"); expect(fixture.innerHTML).toBe("1child");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -283,15 +284,18 @@ test("bound functions are considered 'alike'", async () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.val = 3; parent.state.val = 3;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("3child"); expect(fixture.innerHTML).toBe("3child");
}); });
@@ -330,7 +334,8 @@ test(".alike suffix in a simple case", async () => {
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -341,18 +346,21 @@ test(".alike suffix in a simple case", async () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("01"); expect(fixture.innerHTML).toBe("01");
parent.state.counter++; parent.state.counter++;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("11"); expect(fixture.innerHTML).toBe("11");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test(".alike suffix in a list", async () => { test(".alike suffix in a list", async () => {
@@ -388,7 +396,8 @@ test(".alike suffix in a list", async () => {
} }
await mount(Parent, fixture); await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -404,13 +413,15 @@ test(".alike suffix in a list", async () => {
"Todo:mounted", "Todo:mounted",
"Todo:mounted", "Todo:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("<button>1</button><button>2V</button>"); expect(fixture.innerHTML).toBe("<button>1</button><button>2V</button>");
fixture.querySelector("button")?.click(); fixture.querySelector("button")?.click();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<button>1V</button><button>2V</button>"); expect(fixture.innerHTML).toBe("<button>1V</button><button>2V</button>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Todo:willRender", "Todo:willRender",
@@ -419,5 +430,6 @@ test(".alike suffix in a list", async () => {
"Todo:patched", "Todo:patched",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
+9 -5
View File
@@ -9,7 +9,7 @@ import {
xml, xml,
toRaw, toRaw,
} from "../../src"; } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; import { makeTestFixture, nextTick, snapshotEverything, steps, useLogLifecycle } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -175,7 +175,8 @@ describe("reactivity in lifecycle", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("2"); expect(fixture.innerHTML).toBe("2");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -186,19 +187,22 @@ describe("reactivity in lifecycle", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.content = null; parent.state.content = null;
parent.state.renderChild = false; parent.state.renderChild = false;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("Component is automatically subscribed to reactive object received as prop", async () => { test("Component is automatically subscribed to reactive object received as prop", async () => {
+88 -33
View File
@@ -6,6 +6,7 @@ import {
useLogLifecycle, useLogLifecycle,
makeDeferred, makeDeferred,
nextMicroTick, nextMicroTick,
steps,
} from "../helpers"; } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -41,7 +42,8 @@ describe("rendering semantics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("Achild"); expect(fixture.innerHTML).toBe("Achild");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -52,17 +54,20 @@ describe("rendering semantics", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.value = "B"; parent.state.value = "B";
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("Bchild"); expect(fixture.innerHTML).toBe("Bchild");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("can force a render to update sub tree", async () => { test("can force a render to update sub tree", async () => {
@@ -167,7 +172,8 @@ describe("rendering semantics", () => {
const parent = await mount(Parent, fixture, { env }); const parent = await mount(Parent, fixture, { env });
expect(fixture.innerHTML).toBe("parentAchild3"); expect(fixture.innerHTML).toBe("parentAchild3");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -178,7 +184,8 @@ describe("rendering semantics", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
value = 4; value = 4;
parent.render(true); parent.render(true);
@@ -187,20 +194,23 @@ describe("rendering semantics", () => {
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:willUpdateProps", "Child:willUpdateProps",
"Parent:rendered", "Parent:rendered",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
]).toBeLogged(); ]
`);
parent.state.value = "B"; parent.state.value = "B";
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("parentBchild4"); expect(fixture.innerHTML).toBe("parentBchild4");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Child:willUpdateProps", "Child:willUpdateProps",
"Parent:rendered", "Parent:rendered",
@@ -210,7 +220,8 @@ describe("rendering semantics", () => {
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("props are reactive", async () => { test("props are reactive", async () => {
@@ -235,7 +246,8 @@ describe("rendering semantics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("1"); expect(fixture.innerHTML).toBe("1");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -246,12 +258,20 @@ describe("rendering semantics", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.b = 3; parent.state.b = 3;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("3"); expect(fixture.innerHTML).toBe("3");
expect(["Child:willRender", "Child:rendered", "Child:willPatch", "Child:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender",
"Child:rendered",
"Child:willPatch",
"Child:patched",
]
`);
}); });
test("props are reactive (nested prop)", async () => { test("props are reactive (nested prop)", async () => {
@@ -278,7 +298,8 @@ describe("rendering semantics", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("1"); expect(fixture.innerHTML).toBe("1");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -289,17 +310,26 @@ describe("rendering semantics", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.b.c = 3; // parent is now subscribed to 'b' key parent.state.b.c = 3; // parent is now subscribed to 'b' key
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("3"); expect(fixture.innerHTML).toBe("3");
expect(["Child:willRender", "Child:rendered", "Child:willPatch", "Child:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender",
"Child:rendered",
"Child:willPatch",
"Child:patched",
]
`);
parent.state.b = { c: 444 }; // triggers a parent and a child render parent.state.b = { c: 444 }; // triggers a parent and a child render
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("444"); expect(fixture.innerHTML).toBe("444");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Child:willRender", "Child:willRender",
@@ -308,7 +338,8 @@ describe("rendering semantics", () => {
"Parent:patched", "Parent:patched",
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
]).toBeLogged(); ]
`);
}); });
test("works as expected for dynamic number of props", async () => { test("works as expected for dynamic number of props", async () => {
@@ -366,7 +397,8 @@ describe("rendering semantics", () => {
const parent = await mount(A, fixture); const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("11"); expect(fixture.innerHTML).toBe("11");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:setup", "A:setup",
"A:willStart", "A:willStart",
"A:willRender", "A:willRender",
@@ -382,12 +414,14 @@ describe("rendering semantics", () => {
"C:mounted", "C:mounted",
"B:mounted", "B:mounted",
"A:mounted", "A:mounted",
]).toBeLogged(); ]
`);
parent.state.obj.val = 3; parent.state.obj.val = 3;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("33"); expect(fixture.innerHTML).toBe("33");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willRender", "A:willRender",
"A:rendered", "A:rendered",
"C:willRender", "C:willRender",
@@ -396,11 +430,12 @@ describe("rendering semantics", () => {
"A:patched", "A:patched",
"C:willPatch", "C:willPatch",
"C:patched", "C:patched",
]).toBeLogged(); ]
`);
def.resolve(); def.resolve();
await nextTick(); await nextTick();
expect([]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`);
}); });
}); });
@@ -431,7 +466,8 @@ test("force render in case of existing render", async () => {
} }
const parent = await mount(A, fixture); const parent = await mount(A, fixture);
expect(fixture.innerHTML).toBe("C1"); expect(fixture.innerHTML).toBe("C1");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:setup", "A:setup",
"A:willStart", "A:willStart",
"A:willRender", "A:willRender",
@@ -447,23 +483,37 @@ test("force render in case of existing render", async () => {
"C:mounted", "C:mounted",
"B:mounted", "B:mounted",
"A:mounted", "A:mounted",
]).toBeLogged(); ]
`);
// trigger a new rendering, blocked in B // trigger a new rendering, blocked in B
parent.state.val = 2; parent.state.val = 2;
await nextTick(); await nextTick();
expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willRender",
"B:willUpdateProps",
"A:rendered",
]
`);
// initiate a new render with deep=true. it should cancel the current render // initiate a new render with deep=true. it should cancel the current render
// and also be blocked in B // and also be blocked in B
parent.render(true); parent.render(true);
await nextTick(); await nextTick();
expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"A:willRender",
"B:willUpdateProps",
"A:rendered",
]
`);
def.resolve(); def.resolve();
await nextTick(); await nextTick();
// we check here that the render reaches C (so, that it was properly forced) // we check here that the render reaches C (so, that it was properly forced)
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"B:willRender", "B:willRender",
"C:willUpdateProps", "C:willUpdateProps",
"B:rendered", "B:rendered",
@@ -475,7 +525,8 @@ test("force render in case of existing render", async () => {
"C:patched", "C:patched",
"B:patched", "B:patched",
"A:patched", "A:patched",
]).toBeLogged(); ]
`);
}); });
test("children, default props and renderings", async () => { test("children, default props and renderings", async () => {
@@ -503,7 +554,8 @@ test("children, default props and renderings", async () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("Achild"); expect(fixture.innerHTML).toBe("Achild");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -514,15 +566,18 @@ test("children, default props and renderings", async () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.state.value = "B"; parent.state.value = "B";
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("Bchild"); expect(fixture.innerHTML).toBe("Bchild");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
+13 -7
View File
@@ -1,5 +1,5 @@
import { Component, mount, useState, xml } from "../../src"; import { Component, mount, useState, xml } from "../../src";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; import { makeTestFixture, nextTick, snapshotEverything, steps, useLogLifecycle } from "../helpers";
let fixture: HTMLElement; let fixture: HTMLElement;
@@ -29,7 +29,8 @@ describe("t-component", () => {
await mount(Parent, fixture); await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div>child</div>"); expect(fixture.innerHTML).toBe("<div>child</div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -40,7 +41,8 @@ describe("t-component", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
}); });
test("switching dynamic component", async () => { test("switching dynamic component", async () => {
@@ -68,7 +70,8 @@ describe("t-component", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div>child a</div>"); expect(fixture.innerHTML).toBe("<div>child a</div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -79,13 +82,15 @@ describe("t-component", () => {
"ChildA:rendered", "ChildA:rendered",
"ChildA:mounted", "ChildA:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
parent.Child = ChildB; parent.Child = ChildB;
parent.render(); parent.render();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("child b"); expect(fixture.innerHTML).toBe("child b");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"ChildB:setup", "ChildB:setup",
"ChildB:willStart", "ChildB:willStart",
@@ -97,7 +102,8 @@ describe("t-component", () => {
"ChildA:willDestroy", "ChildA:willDestroy",
"ChildB:mounted", "ChildB:mounted",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
}); });
test("can switch between dynamic components without the need for a t-key", async () => { test("can switch between dynamic components without the need for a t-key", async () => {
+5 -2
View File
@@ -4,6 +4,7 @@ import {
nextAppError, nextAppError,
nextTick, nextTick,
snapshotEverything, snapshotEverything,
steps,
useLogLifecycle, useLogLifecycle,
} from "../helpers"; } from "../helpers";
@@ -91,7 +92,8 @@ describe("list of components", () => {
expect(fixture.innerHTML).toBe( expect(fixture.innerHTML).toBe(
"<div><ul><li><div>1</div></li><li><div>2</div></li></ul></div>" "<div><ul><li><div>1</div></li><li><div>2</div></li></ul></div>"
); );
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -107,7 +109,8 @@ describe("list of components", () => {
"Child:mounted", "Child:mounted",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
}); });
test("reconciliation alg works for t-foreach in t-foreach", async () => { test("reconciliation alg works for t-foreach in t-foreach", async () => {
+1 -1
View File
@@ -137,7 +137,7 @@ export function snapshotEverything() {
}; };
} }
const steps: string[] = []; export const steps: string[] = [];
export function logStep(step: string) { export function logStep(step: string) {
steps.push(step); steps.push(step);
+58 -20
View File
@@ -17,6 +17,7 @@ import {
nextMicroTick, nextMicroTick,
nextTick, nextTick,
snapshotEverything, snapshotEverything,
steps,
useLogLifecycle, useLogLifecycle,
} from "./helpers"; } from "./helpers";
@@ -1850,7 +1851,8 @@ describe("Reactivity: useState", () => {
} }
} }
await mount(Parent, fixture); await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -1866,12 +1868,14 @@ describe("Reactivity: useState", () => {
"Child:mounted", "Child:mounted",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
testContext.value = 321; testContext.value = 321;
await nextTick(); await nextTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Child:willRender", "Child:willRender",
@@ -1880,7 +1884,8 @@ describe("Reactivity: useState", () => {
"Child:patched", "Child:patched",
"Child:willPatch", "Child:willPatch",
"Child:patched", "Child:patched",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>");
}); });
@@ -1904,7 +1909,8 @@ describe("Reactivity: useState", () => {
} }
await mount(Parent, fixture); await mount(Parent, fixture);
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -1920,22 +1926,32 @@ describe("Reactivity: useState", () => {
"Child:mounted", "Child:mounted",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
testContext.value = 321; testContext.value = 321;
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
]).toBeLogged(); ]
`);
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
await nextTick(); await nextTick();
expect(["Child:willPatch", "Child:patched", "Child:willPatch", "Child:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willPatch",
"Child:patched",
"Child:willPatch",
"Child:patched",
]
`);
expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>");
}); });
@@ -1969,7 +1985,8 @@ describe("Reactivity: useState", () => {
await mount(GrandFather, fixture); await mount(GrandFather, fixture);
expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"GrandFather:setup", "GrandFather:setup",
"GrandFather:willStart", "GrandFather:willStart",
"GrandFather:willRender", "GrandFather:willRender",
@@ -1990,22 +2007,32 @@ describe("Reactivity: useState", () => {
"Parent:mounted", "Parent:mounted",
"Child:mounted", "Child:mounted",
"GrandFather:mounted", "GrandFather:mounted",
]).toBeLogged(); ]
`);
testContext.value = 321; testContext.value = 321;
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
"Child:willRender", "Child:willRender",
"Child:rendered", "Child:rendered",
]).toBeLogged(); ]
`);
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><span>321</span><div><span>321</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><div><span>321</span></div></div>");
expect(["Child:willPatch", "Child:patched", "Child:willPatch", "Child:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willPatch",
"Child:patched",
"Child:willPatch",
"Child:patched",
]
`);
}); });
test("one components can subscribe twice to same context", async () => { test("one components can subscribe twice to same context", async () => {
@@ -2181,7 +2208,8 @@ describe("Reactivity: useState", () => {
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:setup", "Parent:setup",
"Parent:willStart", "Parent:willStart",
"Parent:willRender", "Parent:willRender",
@@ -2192,27 +2220,37 @@ describe("Reactivity: useState", () => {
"Child:rendered", "Child:rendered",
"Child:mounted", "Child:mounted",
"Parent:mounted", "Parent:mounted",
]).toBeLogged(); ]
`);
testContext.a = 321; testContext.a = 321;
await nextTick(); await nextTick();
expect(["Child:willRender", "Child:rendered", "Child:willPatch", "Child:patched"]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Child:willRender",
"Child:rendered",
"Child:willPatch",
"Child:patched",
]
`);
parent.state.flag = false; parent.state.flag = false;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div></div>"); expect(fixture.innerHTML).toBe("<div></div>");
expect([ expect(steps.splice(0)).toMatchInlineSnapshot(`
Array [
"Parent:willRender", "Parent:willRender",
"Parent:rendered", "Parent:rendered",
"Parent:willPatch", "Parent:willPatch",
"Child:willUnmount", "Child:willUnmount",
"Child:willDestroy", "Child:willDestroy",
"Parent:patched", "Parent:patched",
]).toBeLogged(); ]
`);
testContext.a = 456; testContext.a = 456;
await nextTick(); await nextTick();
expect([]).toBeLogged(); expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`);
}); });
test("destroyed component before being mounted is inactive", async () => { test("destroyed component before being mounted is inactive", async () => {