From 629b379ea90eaab930678afcd3d8dca2f1a6fb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 19 Nov 2021 09:43:06 +0100 Subject: [PATCH] [IMP] components: rename onRender->onWillRender, add onRendered --- CHANGELOG.md | 2 +- src/component/lifecycle_hooks.ts | 12 +- src/index.ts | 3 +- .../__snapshots__/lifecycle.test.ts.snap | 4 +- tests/components/concurrency.test.ts | 518 ++++++++++++------ tests/components/lifecycle.test.ts | 138 +++-- tests/components/reactivity.test.ts | 8 +- tests/components/t_component.test.ts | 18 +- tests/components/t_foreach.test.ts | 9 +- tests/helpers.ts | 11 +- tests/reactivity.test.ts | 34 +- 11 files changed, 508 insertions(+), 249 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b78f1f84..67f2a9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ removed after. - components can now have empty content or multiple root nodes (htmlelement or text) ([details](#31-components-can-now-have-arbitrary-content)) - new `useEffect` hook -- new `onDestroyed` and `onRender` hooks +- new `onDestroyed`, `onWillRender` and `onRendered` hooks - breaking: lifecycle methods are removed ([details](#1-component-lifecycle-methods-are-removed)) - breaking: can no longer be mounted on detached DOM ([details](#2-components-can-no-longer-be-mounted-in-a-detached-dom-element)) - breaking: standalone `mount` method API is simpler ([details](#4-mount-method-api-is-simpler)) diff --git a/src/component/lifecycle_hooks.ts b/src/component/lifecycle_hooks.ts index 22773f00..e8e20e4c 100644 --- a/src/component/lifecycle_hooks.ts +++ b/src/component/lifecycle_hooks.ts @@ -40,7 +40,7 @@ export function onDestroyed(fn: () => Promise | void | any) { node.destroyed.push(fn); } -export function onRender(fn: () => void | any) { +export function onWillRender(fn: () => void | any) { const node = getCurrent()!; const renderFn = node.renderFn; node.renderFn = () => { @@ -49,6 +49,16 @@ export function onRender(fn: () => void | any) { }; } +export function onRendered(fn: () => void | any) { + const node = getCurrent()!; + const renderFn = node.renderFn; + node.renderFn = () => { + const result = renderFn(); + fn(); + return result; + }; +} + export function onError(fn: (error: Error) => void | any) { const node = getCurrent()!; let handlers = nodeErrorHandlers.get(node); diff --git a/src/index.ts b/src/index.ts index 87bfbf01..615c6371 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,7 +66,8 @@ export { onWillUpdateProps, onWillPatch, onPatched, - onRender, + onWillRender, + onRendered, onDestroyed, onError, } from "./component/lifecycle_hooks"; diff --git a/tests/components/__snapshots__/lifecycle.test.ts.snap b/tests/components/__snapshots__/lifecycle.test.ts.snap index a2c96d9f..b6a6c446 100644 --- a/tests/components/__snapshots__/lifecycle.test.ts.snap +++ b/tests/components/__snapshots__/lifecycle.test.ts.snap @@ -531,7 +531,7 @@ exports[`lifecycle hooks mounted hook is called on subsubcomponents, in proper o }" `; -exports[`lifecycle hooks onRender 1`] = ` +exports[`lifecycle hooks onWillRender 1`] = ` "function anonymous(bdom, helpers ) { let { text, createBlock, list, multi, html, toggler, component } = bdom; @@ -548,7 +548,7 @@ exports[`lifecycle hooks onRender 1`] = ` }" `; -exports[`lifecycle hooks onRender 2`] = ` +exports[`lifecycle hooks onWillRender 2`] = ` "function anonymous(bdom, helpers ) { let { text, createBlock, list, multi, html, toggler, component } = bdom; diff --git a/tests/components/concurrency.test.ts b/tests/components/concurrency.test.ts index c9257d0a..3f8a2743 100644 --- a/tests/components/concurrency.test.ts +++ b/tests/components/concurrency.test.ts @@ -112,16 +112,20 @@ test("destroying/recreating a subwidget with different props (if start is not ov expect(steps).toEqual([ "W:setup", "W:willStart", - "W:render", + "W:willRender", + "W:rendered", "W:mounted", - "W:render", + "W:willRender", "Child:setup", "Child:willStart", - "W:render", + "W:rendered", + "W:willRender", "Child:destroyed", "Child:setup", "Child:willStart", - "Child:render", + "W:rendered", + "Child:willRender", + "Child:rendered", "W:willPatch", "Child:mounted", "W:patched", @@ -189,19 +193,24 @@ test("creating two async components, scenario 1", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "ChildA:destroyed", "ChildA:setup", "ChildA:willStart", "ChildB:setup", "ChildB:willStart", - "ChildB:render", - "ChildA:render", + "Parent:rendered", + "ChildB:willRender", + "ChildB:rendered", + "ChildA:willRender", + "ChildA:rendered", "Parent:willPatch", "ChildB:mounted", "ChildA:mounted", @@ -263,20 +272,26 @@ test("creating two async components, scenario 2", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", + "ChildA:rendered", "ChildA:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildA:willUpdateProps", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "ChildA:willUpdateProps", "ChildB:setup", "ChildB:willStart", - "ChildB:render", - "ChildA:render", + "Parent:rendered", + "ChildB:willRender", + "ChildB:rendered", + "ChildA:willRender", + "ChildA:rendered", "Parent:willPatch", "ChildA:willPatch", "ChildB:mounted", @@ -336,20 +351,26 @@ test("creating two async components, scenario 3 (patching in the same frame)", a expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", + "ChildA:rendered", "ChildA:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildA:willUpdateProps", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "ChildA:willUpdateProps", "ChildB:setup", "ChildB:willStart", - "ChildB:render", - "ChildA:render", + "Parent:rendered", + "ChildB:willRender", + "ChildB:rendered", + "ChildA:willRender", + "ChildA:rendered", "Parent:willPatch", "ChildA:willPatch", "ChildB:mounted", @@ -396,17 +417,22 @@ test("update a sub-component twice in the same frame", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", + "ChildA:rendered", "ChildA:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildA:willUpdateProps", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "ChildA:willUpdateProps", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", + "ChildA:rendered", "Parent:willPatch", "ChildA:willPatch", "ChildA:patched", @@ -447,15 +473,18 @@ test("update a sub-component twice in the same frame, 2", async () => { expect(steps.splice(0)).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", "render", + "ChildA:rendered", "ChildA:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildA:willUpdateProps", + "Parent:rendered", ]); await nextMicroTick(); // For an unknown reason, this test fails on windows without the next microtick. It works @@ -463,22 +492,27 @@ test("update a sub-component twice in the same frame, 2", async () => { // I do not see anything harmful in waiting an extra tick. But it is annoying to not // know what is different. await nextMicroTick(); - expect(steps.splice(0)).toEqual(["ChildA:render", "render"]); + expect(steps.splice(0)).toEqual(["ChildA:willRender", "render", "ChildA:rendered"]); expect(fixture.innerHTML).toBe("
1
"); parent.state.valA = 3; await nextMicroTick(); await nextMicroTick(); - expect(steps.splice(0)).toEqual(["Parent:render", "ChildA:willUpdateProps"]); + expect(steps.splice(0)).toEqual([ + "Parent:willRender", + "ChildA:willUpdateProps", + "Parent:rendered", + ]); await nextMicroTick(); // same as above await nextMicroTick(); - expect(steps).toEqual(["ChildA:render", "render"]); + expect(steps).toEqual(["ChildA:willRender", "render", "ChildA:rendered"]); expect(fixture.innerHTML).toBe("
1
"); await nextTick(); expect(fixture.innerHTML).toBe("
3
"); expect(steps).toEqual([ - "ChildA:render", + "ChildA:willRender", "render", + "ChildA:rendered", "Parent:willPatch", "ChildA:willPatch", "ChildA:patched", @@ -548,21 +582,27 @@ test("properly behave when destroyed/unmounted while rendering ", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", "SubChild:setup", "SubChild:willStart", - "SubChild:render", + "Child:rendered", + "SubChild:willRender", + "SubChild:rendered", "SubChild:mounted", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", - "Child:render", + "Parent:rendered", + "Child:willRender", "SubChild:willUpdateProps", - "Parent:render", + "Child:rendered", + "Parent:willRender", + "Parent:rendered", "Parent:willPatch", "Child:willUnmount", "SubChild:willUnmount", @@ -612,16 +652,20 @@ test("rendering component again in next microtick", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "Child:destroyed", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:mounted", "Parent:patched", @@ -689,23 +733,30 @@ test("concurrent renderings scenario 1", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentB:render", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentA:render", + "ComponentB:rendered", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -774,23 +825,30 @@ test("concurrent renderings scenario 2", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentB:render", + "ComponentB:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -858,23 +916,30 @@ test("concurrent renderings scenario 2bis", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentB:render", + "ComponentB:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -964,29 +1029,38 @@ test("concurrent renderings scenario 3", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", "ComponentD:setup", "ComponentD:willStart", - "ComponentD:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", "ComponentD:mounted", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentC:render", + "ComponentA:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentB:render", + "ComponentC:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentD:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -1078,29 +1152,38 @@ test("concurrent renderings scenario 4", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", "ComponentD:setup", "ComponentD:willStart", - "ComponentD:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", "ComponentD:mounted", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentC:render", + "ComponentA:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentB:render", + "ComponentC:rendered", + "ComponentB:willRender", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentD:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -1164,17 +1247,22 @@ test("concurrent renderings scenario 5", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentA:render", + "ComponentA:rendered", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentB:patched", @@ -1235,17 +1323,22 @@ test("concurrent renderings scenario 6", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentA:render", + "ComponentA:rendered", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentB:patched", @@ -1294,15 +1387,19 @@ test("concurrent renderings scenario 7", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentB:patched", @@ -1354,15 +1451,19 @@ test("concurrent renderings scenario 8", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentB:patched", @@ -1446,30 +1547,40 @@ test("concurrent renderings scenario 9", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", "ComponentC:setup", "ComponentC:willStart", - "ComponentB:render", - "ComponentC:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentC:willRender", "ComponentD:setup", "ComponentD:willStart", - "ComponentD:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", "ComponentD:mounted", "ComponentC:mounted", "ComponentB:mounted", "ComponentA:mounted", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:willUpdateProps", "ComponentC:willUpdateProps", - "ComponentC:render", + "ComponentA:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentD:render", - "ComponentC:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:willRender", "ComponentD:willUpdateProps", - "ComponentD:render", - "ComponentB:render", + "ComponentC:rendered", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:willPatch", @@ -1554,22 +1665,28 @@ test("concurrent renderings scenario 10", async () => { expect(steps).toEqual([ "ComponentA:setup", "ComponentA:willStart", - "ComponentA:render", + "ComponentA:willRender", "ComponentB:setup", "ComponentB:willStart", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", "ComponentB:mounted", "ComponentA:mounted", - "ComponentB:render", + "ComponentB:willRender", "ComponentC:setup", "ComponentC:willStart", - "ComponentA:render", + "ComponentB:rendered", + "ComponentA:willRender", "ComponentB:willUpdateProps", - "ComponentB:render", + "ComponentA:rendered", + "ComponentB:willRender", "ComponentC:destroyed", "ComponentC:setup", "ComponentC:willStart", - "ComponentC:render", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", "ComponentA:willPatch", "ComponentB:willPatch", "ComponentC:mounted", @@ -1624,15 +1741,19 @@ test("concurrent renderings scenario 11", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:patched", @@ -1697,17 +1818,22 @@ test("concurrent renderings scenario 12", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", - "Parent:render", + "Parent:rendered", + "Parent:willRender", "Child:willUpdateProps", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:patched", @@ -1761,28 +1887,36 @@ test("concurrent renderings scenario 13", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Child:render", + "Child:willRender", + "Child:rendered", "Child:willPatch", "Child:patched", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", "Child:setup", "Child:willStart", - "Child:render", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:mounted", "Child:patched", "Parent:patched", - "Child:render", - "Child:render", + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", "Child:willPatch", "Child:patched", "Child:willPatch", @@ -1856,24 +1990,32 @@ test("concurrent renderings scenario 14", async () => { expect(steps).toEqual([ "A:setup", "A:willStart", - "A:render", + "A:willRender", "B:setup", "B:willStart", - "B:render", + "A:rendered", + "B:willRender", "C:setup", "C:willStart", - "C:render", + "B:rendered", + "C:willRender", + "C:rendered", "C:mounted", "B:mounted", "A:mounted", - "A:render", + "A:willRender", "B:willUpdateProps", - "B:render", + "A:rendered", + "B:willRender", "C:willUpdateProps", - "C:render", - "B:render", + "B:rendered", + "C:willRender", + "C:rendered", + "B:willRender", "C:willUpdateProps", - "C:render", + "B:rendered", + "C:willRender", + "C:rendered", "A:willPatch", "B:willPatch", "C:willPatch", @@ -1955,24 +2097,32 @@ test("concurrent renderings scenario 15", async () => { expect(steps).toEqual([ "A:setup", "A:willStart", - "A:render", + "A:willRender", "B:setup", "B:willStart", - "B:render", + "A:rendered", + "B:willRender", "C:setup", "C:willStart", - "C:render", + "B:rendered", + "C:willRender", + "C:rendered", "C:mounted", "B:mounted", "A:mounted", - "A:render", + "A:willRender", "B:willUpdateProps", - "B:render", + "A:rendered", + "B:willRender", "C:willUpdateProps", - "C:render", - "B:render", + "B:rendered", + "C:willRender", + "C:rendered", + "B:willRender", "C:willUpdateProps", - "C:render", + "B:rendered", + "C:willRender", + "C:rendered", "A:willPatch", "B:willPatch", "C:willPatch", @@ -2063,30 +2213,39 @@ test.skip("concurrent renderings scenario 16", async () => { expect(steps).toEqual([ "A:setup", "A:willStart", - "A:render", + "A:willRender", "B:setup", "B:willStart", - "B:render", + "A:rendered", + "B:willRender", "C:setup", "C:willStart", - "C:render", + "B:rendered", + "C:willRender", + "C:rendered", "C:mounted", "B:mounted", "A:mounted", - "A:render", + "A:willRender", "B:willUpdateProps", - "B:render", + "A:rendered", + "B:willRender", + "B:rendered", "C:willUpdateProps", - "C:render", + "C:willRender", + "C:rendered", "D:setup", "D:willStart", - "B:render", + "B:willRender", + "B:rendered", "C:willUpdateProps", - "C:render", + "C:willRender", + "C:rendered", "D:destroyed", "D:setup", "D:willStart", - "D:render", + "D:willRender", + "D:rendered", "A:willPatch", "B:willPatch", "C:willPatch", @@ -2209,9 +2368,11 @@ test("change state and call manually render: no unnecessary rendering", async () expect(steps).toEqual([ "Test:setup", "Test:willStart", - "Test:render", + "Test:willRender", + "Test:rendered", "Test:mounted", - "Test:render", + "Test:willRender", + "Test:rendered", "Test:willPatch", "Test:patched", ]); @@ -2242,7 +2403,13 @@ test("changing state before first render does not trigger a render", async () => await nextTick(); expect(renders).toBe(1); expect(fixture.innerHTML).toBe("
3
"); - expect(steps).toEqual(["TestW:setup", "TestW:willStart", "TestW:render", "TestW:mounted"]); + expect(steps).toEqual([ + "TestW:setup", + "TestW:willStart", + "TestW:willRender", + "TestW:rendered", + "TestW:mounted", + ]); Object.freeze(steps); }); @@ -2278,17 +2445,25 @@ test("changing state before first render does not trigger a render (with parent) const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
"); - expect(steps).toEqual(["Parent:setup", "Parent:willStart", "Parent:render", "Parent:mounted"]); + expect(steps).toEqual([ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ]); steps.splice(0); parent.state.flag = true; await nextTick(); expect(fixture.innerHTML).toBe("
3
"); expect(renders).toBe(1); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", "TestW:setup", "TestW:willStart", - "TestW:render", + "Parent:rendered", + "TestW:willRender", + "TestW:rendered", "Parent:willPatch", "TestW:mounted", "Parent:patched", @@ -2342,10 +2517,12 @@ test("two renderings initiated between willPatch and patched", async () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Panel:setup", "Panel:willStart", - "Panel:render", + "Parent:rendered", + "Panel:willRender", + "Panel:rendered", "Panel:mounted", "Parent:mounted", ]); @@ -2356,10 +2533,12 @@ test("two renderings initiated between willPatch and patched", async () => { expect(fixture.innerHTML).toBe("
Panel2
"); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", "Panel:setup", "Panel:willStart", - "Panel:render", + "Parent:rendered", + "Panel:willRender", + "Panel:rendered", "Parent:willPatch", "Panel:willUnmount", "Panel:destroyed", @@ -2373,7 +2552,8 @@ test("two renderings initiated between willPatch and patched", async () => { expect(fixture.innerHTML).toBe("
"); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:willPatch", "Panel:willUnmount", "Panel:destroyed", diff --git a/tests/components/lifecycle.test.ts b/tests/components/lifecycle.test.ts index ae26e84f..4b877991 100644 --- a/tests/components/lifecycle.test.ts +++ b/tests/components/lifecycle.test.ts @@ -4,7 +4,7 @@ import { onWillUnmount, onPatched, onWillUpdateProps, - onRender, + onWillRender, } from "../../src/component/lifecycle_hooks"; import { status } from "../../src/component/status"; import { xml } from "../../src/tags"; @@ -385,20 +385,25 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:patched", "Parent:patched", - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:willPatch", "Child:willUnmount", "Child:destroyed", @@ -561,10 +566,12 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", ]); @@ -609,20 +616,29 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect(steps).toEqual(["Parent:setup", "Parent:willStart", "Parent:render", "Parent:mounted"]); + expect(steps).toEqual([ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ]); steps.splice(0); parent.state.hasChild = true; await nextTick(); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", "GrandChild:setup", "GrandChild:willStart", - "GrandChild:render", + "Child:rendered", + "GrandChild:willRender", + "GrandChild:rendered", "Parent:willPatch", "GrandChild:mounted", "Child:mounted", @@ -672,7 +688,13 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect(steps).toEqual(["Parent:setup", "Parent:willStart", "Parent:render", "Parent:mounted"]); + expect(steps).toEqual([ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ]); steps.splice(0); @@ -717,7 +739,13 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect(steps).toEqual(["Parent:setup", "Parent:willStart", "Parent:render", "Parent:mounted"]); + expect(steps).toEqual([ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ]); steps.splice(0); @@ -725,12 +753,14 @@ describe("lifecycle hooks", () => { await nextTick(); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", "GrandChild:setup", "GrandChild:willStart", + "Child:rendered", ]); steps.splice(0); @@ -769,10 +799,12 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", ]); @@ -783,7 +815,8 @@ describe("lifecycle hooks", () => { await nextTick(); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:willPatch", "Child:willUnmount", "Child:destroyed", @@ -816,10 +849,12 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", ]); @@ -830,9 +865,11 @@ describe("lifecycle hooks", () => { await nextTick(); expect(steps).toEqual([ - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:patched", @@ -841,7 +878,7 @@ describe("lifecycle hooks", () => { Object.freeze(steps); }); - test("onRender", async () => { + test("onWillRender", async () => { let steps: string[] = []; const def = makeDeferred(); @@ -852,7 +889,7 @@ describe("lifecycle hooks", () => { setup() { useLogLifecycle(steps); onWillUpdateProps(() => def); - onRender(() => (this.visibleState = this.state.value)); + onWillRender(() => (this.visibleState = this.state.value)); } increment() { this.state.value++; @@ -891,17 +928,21 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "Child:willUpdateProps", + "Parent:rendered", "inc:1", "inc:1", - "Child:render", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:willPatch", "Child:patched", @@ -993,19 +1034,24 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "A:setup", "A:willStart", - "A:render", + "A:willRender", "B:setup", "B:willStart", "C:setup", "C:willStart", - "B:render", - "C:render", + "A:rendered", + "B:willRender", + "B:rendered", + "C:willRender", "D:setup", "D:willStart", "E:setup", "E:willStart", - "D:render", - "E:render", + "C:rendered", + "D:willRender", + "D:rendered", + "E:willRender", + "E:rendered", "E:mounted", "D:mounted", "C:mounted", @@ -1018,12 +1064,15 @@ describe("lifecycle hooks", () => { c!.state.flag = false; await nextTick(); expect(steps).toEqual([ - "C:render", + "C:willRender", "D:willUpdateProps", "F:setup", "F:willStart", - "D:render", - "F:render", + "C:rendered", + "D:willRender", + "D:rendered", + "F:willRender", + "F:rendered", "C:willPatch", "D:willPatch", "E:willUnmount", @@ -1062,21 +1111,26 @@ describe("lifecycle hooks", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", + "Parent:rendered", "Parent:willPatch", "Child:willUnmount", "Child:destroyed", "Parent:patched", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Parent:willPatch", "Child:mounted", "Parent:patched", diff --git a/tests/components/reactivity.test.ts b/tests/components/reactivity.test.ts index cfab26b3..5bab8910 100644 --- a/tests/components/reactivity.test.ts +++ b/tests/components/reactivity.test.ts @@ -2,7 +2,7 @@ import { Component, mount, onPatched, - onRender, + onWillRender, onWillPatch, onWillUnmount, useState, @@ -37,7 +37,7 @@ describe("reactivity in lifecycle", () => { static template = xml`
`; state = useState({ a: 5, b: 7 }); setup() { - onRender(() => n++); + onWillRender(() => n++); } } const comp = await mount(Comp, fixture); @@ -61,7 +61,7 @@ describe("reactivity in lifecycle", () => { `; state = useState({ n: 2 }); setup() { - onRender(() => { + onWillRender(() => { steps.push("render"); }); onWillPatch(() => { @@ -132,7 +132,7 @@ describe("reactivity in lifecycle", () => { state = useState({ val: 1 }); setup() { STATE = this.state; - onRender(() => { + onWillRender(() => { steps.push(this.state.val); }); } diff --git a/tests/components/t_component.test.ts b/tests/components/t_component.test.ts index c3a9ff63..91e01663 100644 --- a/tests/components/t_component.test.ts +++ b/tests/components/t_component.test.ts @@ -35,10 +35,12 @@ describe("t-component", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Parent:mounted", ]); @@ -80,16 +82,20 @@ describe("t-component", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "ChildA:setup", "ChildA:willStart", - "ChildA:render", + "Parent:rendered", + "ChildA:willRender", + "ChildA:rendered", "ChildA:mounted", "Parent:mounted", - "Parent:render", + "Parent:willRender", "ChildB:setup", "ChildB:willStart", - "ChildB:render", + "Parent:rendered", + "ChildB:willRender", + "ChildB:rendered", "Parent:willPatch", "ChildA:willUnmount", "ChildA:destroyed", diff --git a/tests/components/t_foreach.test.ts b/tests/components/t_foreach.test.ts index 2a76a885..01626e5f 100644 --- a/tests/components/t_foreach.test.ts +++ b/tests/components/t_foreach.test.ts @@ -81,13 +81,16 @@ describe("list of components", () => { expect(steps).toEqual([ "Parent:setup", "Parent:willStart", - "Parent:render", + "Parent:willRender", "Child:setup", "Child:willStart", "Child:setup", "Child:willStart", - "Child:render", - "Child:render", + "Parent:rendered", + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", "Child:mounted", "Child:mounted", "Parent:mounted", diff --git a/tests/helpers.ts b/tests/helpers.ts index 9a3d6fbb..70d811f5 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -4,13 +4,14 @@ import { onDestroyed, onMounted, onPatched, - onRender, + onWillRender, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, useComponent, + onRendered, } from "../src"; import { BDom } from "../src/blockdom"; import { blockDom } from "../src"; @@ -181,8 +182,12 @@ export function useLogLifecycle(steps: string[]) { steps.push(`${name}:willUpdateProps`); }); - onRender(() => { - steps.push(`${name}:render`); + onWillRender(() => { + steps.push(`${name}:willRender`); + }); + + onRendered(() => { + steps.push(`${name}:rendered`); }); onWillPatch(() => { diff --git a/tests/reactivity.test.ts b/tests/reactivity.test.ts index 40687b18..2836fe04 100644 --- a/tests/reactivity.test.ts +++ b/tests/reactivity.test.ts @@ -1,4 +1,4 @@ -import { Component, mount, onRender, onWillStart, onWillUpdateProps, useState } from "../src"; +import { Component, mount, onWillRender, onWillStart, onWillUpdateProps, useState } from "../src"; import { batched, reactive } from "../src/reactivity"; import { xml } from "../src/tags"; import { @@ -1125,7 +1125,7 @@ describe("Reactivity: useState", () => { static template = xml``; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("child"); }); } @@ -1134,7 +1134,7 @@ describe("Reactivity: useState", () => { static template = xml`
`; static components = { Child }; setup() { - onRender(() => { + onWillRender(() => { steps.push("parent"); }); } @@ -1156,7 +1156,7 @@ describe("Reactivity: useState", () => { static template = xml``; contextObj = useState(testContext); setup() { - onRender(async () => { + onWillRender(async () => { steps.push("render"); }); } @@ -1187,7 +1187,7 @@ describe("Reactivity: useState", () => { static components = {}; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("render"); }); } @@ -1228,7 +1228,7 @@ describe("Reactivity: useState", () => { contextObj1 = useState(testContext); contextObj2 = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("comp"); }); } @@ -1250,7 +1250,7 @@ describe("Reactivity: useState", () => { static template = xml``; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("child"); }); } @@ -1260,7 +1260,7 @@ describe("Reactivity: useState", () => { static components = { Child }; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("parent"); }); } @@ -1293,7 +1293,7 @@ describe("Reactivity: useState", () => { static template = xml`
`; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.add("L3A"); }); } @@ -1303,7 +1303,7 @@ describe("Reactivity: useState", () => { static template = xml`
`; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.add("L2B"); }); } @@ -1314,7 +1314,7 @@ describe("Reactivity: useState", () => { static components = { L3A }; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.add("L2A"); }); } @@ -1325,7 +1325,7 @@ describe("Reactivity: useState", () => { static components = { L2A, L2B }; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.add("L1A"); }); } @@ -1380,7 +1380,7 @@ describe("Reactivity: useState", () => { static template = xml``; contextObj = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.push("child"); }); } @@ -1390,7 +1390,7 @@ describe("Reactivity: useState", () => { static components = { Child }; state = useState({ flag: true }); setup() { - onRender(() => { + onWillRender(() => { steps.push("parent"); }); } @@ -1423,7 +1423,7 @@ describe("Reactivity: useState", () => { onWillStart(() => { return makeDeferred(); }); - onRender(() => { + onWillRender(() => { steps.push("child"); }); } @@ -1465,7 +1465,7 @@ describe("Reactivity: useState", () => { state = useState(testContext[this.props.id]); setup() { - onRender(() => { + onWillRender(() => { steps.add(`quantity${this.props.id}`); }); } @@ -1484,7 +1484,7 @@ describe("Reactivity: useState", () => { state = useState(testContext); setup() { - onRender(() => { + onWillRender(() => { steps.add("list"); }); }