From 924dffeb36f10bc8d49744f51bbfb98aa1ab0b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 27 Jan 2022 14:55:02 +0100 Subject: [PATCH] [TEST] component: add test to make sure a specific issue does not arise --- .../__snapshots__/lifecycle.test.ts.snap | 28 ++++++++++ tests/components/lifecycle.test.ts | 52 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/tests/components/__snapshots__/lifecycle.test.ts.snap b/tests/components/__snapshots__/lifecycle.test.ts.snap index fcd8e9f6..d43ae107 100644 --- a/tests/components/__snapshots__/lifecycle.test.ts.snap +++ b/tests/components/__snapshots__/lifecycle.test.ts.snap @@ -160,6 +160,34 @@ exports[`lifecycle hooks components are unmounted destroyed if no longer in DOM }" `; +exports[`lifecycle hooks destroy new children before being mountged 1`] = ` +"function anonymous(bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; + + return function template(ctx, node, key = \\"\\") { + let b2,b3,b4; + b2 = text(\`before\`); + if (ctx['state'].flag) { + b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx); + } + b4 = text(\`after\`); + return multi([b2, b3, b4]); + } +}" +`; + +exports[`lifecycle hooks destroy new children before being mountged 2`] = ` +"function anonymous(bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, component, comment } = bdom; + + return function template(ctx, node, key = \\"\\") { + return text(\`child\`); + } +}" +`; + exports[`lifecycle hooks hooks are called in proper order in widget creation/destruction 1`] = ` "function anonymous(bdom, helpers ) { diff --git a/tests/components/lifecycle.test.ts b/tests/components/lifecycle.test.ts index befbccda..6545cdc2 100644 --- a/tests/components/lifecycle.test.ts +++ b/tests/components/lifecycle.test.ts @@ -1253,4 +1253,56 @@ describe("lifecycle hooks", () => { "onWillDestroy", ]).toBeLogged(); }); + + test("destroy new children before being mountged", async () => { + class Child extends Component { + static template = xml`child`; + setup() { + useLogLifecycle(); + } + } + + class Parent extends Component { + static template = xml`beforeafter`; + static components = { Child }; + + state = useState({ flag: false }); + setup() { + useLogLifecycle(); + onRendered(async () => { + // we destroy here the app after the new child component has been + // created, but before this rendering has been patched to the DOM + if (this.state.flag) { + await Promise.resolve(); + app.destroy(); + } + }); + } + } + + const app = new App(Parent); + const parent = await app.mount(fixture); + expect(fixture.innerHTML).toBe("beforeafter"); + expect([ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ]).toBeLogged(); + + parent.state.flag = true; + + await nextTick(); + expect(fixture.innerHTML).toBe(""); + expect([ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Parent:rendered", + "Parent:willUnmount", + "Child:willDestroy", + "Parent:willDestroy", + ]).toBeLogged(); + }); });