diff --git a/src/runtime/component_node.ts b/src/runtime/component_node.ts index bffc0fc54..97950ab41 100644 --- a/src/runtime/component_node.ts +++ b/src/runtime/component_node.ts @@ -6,7 +6,7 @@ import { OwlError } from "../common/owl_error"; import { Fiber, makeChildFiber, makeRootFiber, MountFiber, MountOptions } from "./fibers"; import { clearReactivesForCallback, getSubscriptions, reactive, targets } from "./reactivity"; import { STATUS } from "./status"; -import { batched, Callback } from "./utils"; +import { batched, Callback, possiblySync } from "./utils"; let currentNode: ComponentNode | null = null; @@ -128,21 +128,29 @@ export class ComponentNode

implements VNode f.call(component))); - } catch (e) { - this.app.handleError({ node: this, error: e }); - return; - } - if (this.status === STATUS.NEW && this.fiber === fiber) { - fiber.render(); - } + return possiblySync( + () => { + const willStartResults = this.willStart.map((f) => f.call(component)); + if (willStartResults.some((r) => typeof r?.then === "function")) { + return Promise.all(willStartResults); + } + return; + }, + () => { + if (this.status === STATUS.NEW && this.fiber === fiber) { + fiber.render(); + } + }, + (e: any) => { + this.app.handleError({ node: this, error: e }); + } + ); } async render(deep: boolean) { @@ -238,7 +246,7 @@ export class ComponentNode

implements VNode implements VNode f.call(component, props))); - await prom; - if (fiber !== this.fiber) { - return; - } - component.props = props; - fiber.render(); - const parentRoot = parentFiber.root!; - if (this.willPatch.length) { - parentRoot.willPatch.push(fiber); - } - if (this.patched.length) { - parentRoot.patched.push(fiber); - } + return possiblySync( + () => { + const willUpdateProps = this.willUpdateProps.map((f) => f.call(component, props)); + if (willUpdateProps.some((p) => typeof p?.then === "function")) { + return Promise.all(willUpdateProps); + } + return; + }, + () => { + if (fiber !== this.fiber) { + return; + } + component.props = props; + fiber.render(); + const parentRoot = parentFiber.root!; + if (this.willPatch.length) { + parentRoot.willPatch.push(fiber); + } + if (this.patched.length) { + parentRoot.patched.push(fiber); + } + } + ); } /** diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 7aa9b112f..4721950be 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -88,3 +88,24 @@ export class Markup extends String {} export function markup(value: any) { return new Markup(value); } + +export function possiblySync(computation: Function, onSuccess: Function, onError?: Function) { + try { + let result; + if (onError) { + try { + result = computation(); + } catch (e) { + return onError(e); + } + } else { + result = computation(); + } + if (typeof result?.then === "function") { + return result.then(onSuccess, onError); + } + return onSuccess(result); + } catch (e) { + return Promise.reject(e); + } +} diff --git a/tests/app/__snapshots__/app.test.ts.snap b/tests/app/__snapshots__/app.test.ts.snap index 649624886..e170910ca 100644 --- a/tests/app/__snapshots__/app.test.ts.snap +++ b/tests/app/__snapshots__/app.test.ts.snap @@ -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 ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; diff --git a/tests/app/app.test.ts b/tests/app/app.test.ts index ce219e4f3..ffc986866 100644 --- a/tests/app/app.test.ts +++ b/tests/app/app.test.ts @@ -8,6 +8,7 @@ import { useLogLifecycle, makeDeferred, nextMicroTick, + steps, } from "../helpers"; let fixture: HTMLElement; @@ -123,23 +124,47 @@ describe("app", () => { const app = new App(A); 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; 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) comp.render(); 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(); - expect([ - "A:willUnmount", - "B:willDestroy", - "A:willDestroy", - "B:willDestroy", // make sure the 2 B instances have been destroyed synchronously - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willUnmount", + "B:willDestroy", + "A:willDestroy", + "B:willDestroy", + ] + `); }); }); diff --git a/tests/components/__snapshots__/concurrency.test.ts.snap b/tests/components/__snapshots__/concurrency.test.ts.snap index 6b263e7e2..331eb0b37 100644 --- a/tests/components/__snapshots__/concurrency.test.ts.snap +++ b/tests/components/__snapshots__/concurrency.test.ts.snap @@ -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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; @@ -1861,10 +1861,10 @@ exports[`renderings, destruction, patch, stuff, ... yet another variation 3`] = ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; - let block3 = createBlock(\`

\`); + let block3 = createBlock(\`\`); return function template(ctx, node, key = \\"\\") { - const b2 = text(\`D\`); + const b2 = text(\`C\`); let hdlr1 = [ctx['increment'], ctx]; let txt1 = ctx['state'].val; const b3 = block3([hdlr1, txt1]); @@ -1878,10 +1878,10 @@ exports[`renderings, destruction, patch, stuff, ... yet another variation 4`] = ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; - let block3 = createBlock(\`\`); + let block3 = createBlock(\`

\`); return function template(ctx, node, key = \\"\\") { - const b2 = text(\`C\`); + const b2 = text(\`D\`); let hdlr1 = [ctx['increment'], ctx]; let txt1 = ctx['state'].val; const b3 = block3([hdlr1, txt1]); diff --git a/tests/components/__snapshots__/error_handling.test.ts.snap b/tests/components/__snapshots__/error_handling.test.ts.snap index 7ddb11a61..d674b9750 100644 --- a/tests/components/__snapshots__/error_handling.test.ts.snap +++ b/tests/components/__snapshots__/error_handling.test.ts.snap @@ -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 ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; diff --git a/tests/components/__snapshots__/lifecycle.test.ts.snap b/tests/components/__snapshots__/lifecycle.test.ts.snap index 24b54f607..6d8cc8111 100644 --- a/tests/components/__snapshots__/lifecycle.test.ts.snap +++ b/tests/components/__snapshots__/lifecycle.test.ts.snap @@ -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 ) { 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 ) { 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 ) { 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 ) { 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 ) { 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 ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; diff --git a/tests/components/__snapshots__/t_component.test.ts.snap b/tests/components/__snapshots__/t_component.test.ts.snap index 6a9ef1048..4e6013143 100644 --- a/tests/components/__snapshots__/t_component.test.ts.snap +++ b/tests/components/__snapshots__/t_component.test.ts.snap @@ -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 ) { let { text, createBlock, list, multi, html, toggler, comment } = bdom; diff --git a/tests/components/basics.test.ts b/tests/components/basics.test.ts index 6ddd5d65c..264fceb2e 100644 --- a/tests/components/basics.test.ts +++ b/tests/components/basics.test.ts @@ -5,6 +5,7 @@ import { nextAppError, nextTick, snapshotEverything, + steps, useLogLifecycle, } from "../helpers"; import { markup } from "../../src/runtime/utils"; @@ -868,19 +869,26 @@ describe("basics", () => { const parent = await mount(Parent, fixture); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); - expect([ - "Child:setup", - "Child:willStart", - "Child:willRender", - "Child:rendered", - "Child:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:mounted", + ] + `); parent.ifVar = false; parent.render(); await nextTick(); 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 () => { @@ -899,27 +907,31 @@ describe("basics", () => { const parent = await mount(Parent, fixture); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); - expect([ - "Child:setup", - "Child:willStart", - "Child:willRender", - "Child:rendered", - "Child:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:mounted", + ] + `); parent.keyVar = 2; parent.render(); await nextTick(); expect(Object.keys(parent.__owl__.children).length).toStrictEqual(1); - expect([ - "Child:setup", - "Child:willStart", - "Child:willRender", - "Child:rendered", - "Child:willUnmount", - "Child:willDestroy", - "Child:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:willUnmount", + "Child:willDestroy", + "Child:mounted", + ] + `); }); test("GrandChild display is controlled by its GrandParent", async () => { @@ -943,20 +955,27 @@ describe("basics", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
"); - expect([ - "GrandChild:setup", - "GrandChild:willStart", - "GrandChild:willRender", - "GrandChild:rendered", - "GrandChild:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandChild:setup", + "GrandChild:willStart", + "GrandChild:willRender", + "GrandChild:rendered", + "GrandChild:mounted", + ] + `); parent.displayGrandChild = false; parent.render(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect(["GrandChild:willUnmount", "GrandChild:willDestroy"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandChild:willUnmount", + "GrandChild:willDestroy", + ] + `); }); }); diff --git a/tests/components/concurrency.test.ts b/tests/components/concurrency.test.ts index 62909302e..8507037f4 100644 --- a/tests/components/concurrency.test.ts +++ b/tests/components/concurrency.test.ts @@ -21,6 +21,7 @@ import { nextMicroTick, nextTick, snapshotEverything, + steps, useLogLifecycle, } from "../helpers"; @@ -69,7 +70,13 @@ describe("async rendering", () => { def.resolve(); await nextTick(); expect(status(w)).toBe("destroyed"); - expect(["W:setup", "W:willStart", "W:willDestroy"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "W:setup", + "W:willStart", + "W:willDestroy", + ] + `); }); }); @@ -99,7 +106,15 @@ test("destroying/recreating a subwidget with different props (if start is not ov const w = await mount(W, fixture); - expect(["W:setup", "W:willStart", "W:willRender", "W:rendered", "W:mounted"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "W:setup", + "W:willStart", + "W:willRender", + "W:rendered", + "W:mounted", + ] + `); expect(n).toBe(0); @@ -108,27 +123,43 @@ test("destroying/recreating a subwidget with different props (if start is not ov await nextMicroTick(); expect(n).toBe(1); - expect(["W:willRender", "Child:setup", "Child:willStart", "W:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "W:willRender", + "Child:setup", + "Child:willStart", + "W:rendered", + ] + `); w.state.val = 3; await nextMicroTick(); await nextMicroTick(); expect(n).toBe(2); - expect(["W:willRender", "Child:setup", "Child:willStart", "W:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "W:willRender", + "Child:setup", + "Child:willStart", + "W:rendered", + ] + `); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
child:3
"); expect(Object.values(w.__owl__.children).length).toBe(1); - expect([ - "Child:willRender", - "Child:rendered", - "Child:willDestroy", - "W:willPatch", - "Child:mounted", - "W:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Child:willDestroy", + "W:willPatch", + "Child:mounted", + "W:patched", + ] + `); }); test("destroying/recreating a subcomponent, other scenario", async () => { @@ -156,34 +187,40 @@ test("destroying/recreating a subcomponent, other scenario", async () => { const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("parent"); parent.state.hasChild = true; await nextTick(); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:willDestroy", - "Parent:willPatch", - "Child:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:willDestroy", + "Parent:willPatch", + "Child:mounted", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("parentchild"); }); @@ -228,51 +265,69 @@ test("creating two async components, scenario 1", async () => { } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe(""); parent.state.flagA = true; await nextTick(); - expect(["Parent:willRender", "ChildA:setup", "ChildA:willStart", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "Parent:rendered", + ] + `); expect(fixture.innerHTML).toBe(""); parent.state.flagB = true; await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "ChildB:setup", - "ChildB:willStart", - "Parent:rendered", - "ChildA:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildB:setup", + "ChildB:willStart", + "Parent:rendered", + "ChildA:willDestroy", + ] + `); defB.resolve(); await nextTick(); expect(fixture.innerHTML).toBe(""); expect(nbRenderings).toBe(0); - expect(["ChildB:willRender", "ChildB:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildB:willRender", + "ChildB:rendered", + ] + `); defA.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("ab"); expect(nbRenderings).toBe(1); - expect([ - "ChildA:willRender", - "ChildA:rendered", - "Parent:willPatch", - "ChildB:mounted", - "ChildA:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildA:willRender", + "ChildA:rendered", + "Parent:willPatch", + "ChildB:mounted", + "ChildA:mounted", + "Parent:patched", + ] + `); }); test("creating two async components, scenario 2", async () => { @@ -309,53 +364,70 @@ test("creating two async components, scenario 2", async () => { } } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "Parent:rendered", - "ChildA:willRender", - "ChildA:rendered", - "ChildA:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + "ChildA:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("
a1
"); parent.state.valA = 2; await nextTick(); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "Parent:rendered", + ] + `); expect(fixture.innerHTML).toBe("
a1
"); parent.state.flagB = true; await nextTick(); expect(fixture.innerHTML).toBe("
a1
"); - expect([ - "Parent:willRender", - "ChildA:willUpdateProps", - "ChildB:setup", - "ChildB:willStart", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "ChildB:setup", + "ChildB:willStart", + "Parent:rendered", + ] + `); defB.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
a1
"); - expect(["ChildB:willRender", "ChildB:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildB:willRender", + "ChildB:rendered", + ] + `); defA.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
a2b2
"); - expect([ - "ChildA:willRender", - "ChildA:rendered", - "Parent:willPatch", - "ChildA:willPatch", - "ChildB:mounted", - "ChildA:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildA:willRender", + "ChildA:rendered", + "Parent:willPatch", + "ChildA:willPatch", + "ChildB:mounted", + "ChildA:patched", + "Parent:patched", + ] + `); }); test("creating two async components, scenario 3 (patching in the same frame)", async () => { @@ -390,54 +462,66 @@ test("creating two async components, scenario 3 (patching in the same frame)", a } } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "Parent:rendered", - "ChildA:willRender", - "ChildA:rendered", - "ChildA:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + "ChildA:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("
a1
"); parent.state.valA = 2; await nextTick(); expect(fixture.innerHTML).toBe("
a1
"); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "Parent:rendered", + ] + `); parent.state.flagB = true; await nextTick(); expect(fixture.innerHTML).toBe("
a1
"); - expect([ - "Parent:willRender", - "ChildA:willUpdateProps", - "ChildB:setup", - "ChildB:willStart", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "ChildB:setup", + "ChildB:willStart", + "Parent:rendered", + ] + `); defB.resolve(); expect(fixture.innerHTML).toBe("
a1
"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defA.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
a2b2
"); - expect([ - "ChildB:willRender", - "ChildB:rendered", - "ChildA:willRender", - "ChildA:rendered", - "Parent:willPatch", - "ChildA:willPatch", - "ChildB:mounted", - "ChildA:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildB:willRender", + "ChildB:rendered", + "ChildA:willRender", + "ChildA:rendered", + "Parent:willPatch", + "ChildA:willPatch", + "ChildB:mounted", + "ChildA:patched", + "Parent:patched", + ] + `); }); test("update a sub-component twice in the same frame", async () => { @@ -461,42 +545,58 @@ test("update a sub-component twice in the same frame", async () => { } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
1
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "Parent:rendered", - "ChildA:willRender", - "ChildA:rendered", - "ChildA:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + "ChildA:mounted", + "Parent:mounted", + ] + `); parent.state.valA = 2; await nextTick(); expect(fixture.innerHTML).toBe("
1
"); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "Parent:rendered", + ] + `); parent.state.valA = 3; await nextTick(); expect(fixture.innerHTML).toBe("
1
"); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "Parent:rendered", + ] + `); defs[0].resolve(); await Promise.resolve(); defs[1].resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
3
"); - expect([ - "ChildA:willRender", - "ChildA:rendered", - "Parent:willPatch", - "ChildA:willPatch", - "ChildA:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ChildA:willRender", + "ChildA:rendered", + "Parent:willPatch", + "ChildA:willPatch", + "ChildA:patched", + "Parent:patched", + ] + `); }); test("update a sub-component twice in the same frame, 2", async () => { @@ -521,46 +621,71 @@ test("update a sub-component twice in the same frame, 2", async () => { } } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "Parent:rendered", - "ChildA:willRender", - "ChildA:rendered", - "ChildA:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + "ChildA:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("
1
"); parent.state.valA = 2; await nextMicroTick(); await nextMicroTick(); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + ] + `); await nextMicroTick(); // For an unknown reason, this test fails on windows without the next microtick. It works // in linux and osx, but fails on at least this machine. // I do not see anything harmful in waiting an extra tick. But it is annoying to not // know what is different. await nextMicroTick(); - expect(["ChildA:willRender", "ChildA:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); expect(fixture.innerHTML).toBe("
1
"); parent.state.valA = 3; await nextMicroTick(); await nextMicroTick(); - expect(["Parent:willRender", "ChildA:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildA:willUpdateProps", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + ] + `); await nextMicroTick(); // same as above await nextMicroTick(); - expect(["ChildA:willRender", "ChildA:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); expect(fixture.innerHTML).toBe("
1
"); await nextTick(); expect(fixture.innerHTML).toBe("
3
"); - expect(["Parent:willPatch", "ChildA:willPatch", "ChildA:patched", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "ChildA:willPatch", + "ChildA:patched", + "Parent:patched", + ] + `); }); test("properly behave when destroyed/unmounted while rendering ", async () => { @@ -597,59 +722,65 @@ test("properly behave when destroyed/unmounted while rendering ", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "SubChild:setup", - "SubChild:willStart", - "Child:rendered", - "SubChild:willRender", - "SubChild:rendered", - "SubChild:mounted", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "SubChild:setup", + "SubChild:willStart", + "SubChild:willRender", + "SubChild:rendered", + "Child:rendered", + "Parent:rendered", + "SubChild:mounted", + "Child:mounted", + "Parent:mounted", + ] + `); // this change triggers a rendering of the parent. This rendering is delayed, // because child is now waiting for def to be resolved parent.state.val = "Framboise Girardin"; await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "SubChild:willUpdateProps", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "SubChild:willUpdateProps", + "Child:rendered", + "Parent:rendered", + ] + `); // with this, we remove child, and subchild, even though it is not finished // rendering from previous changes parent.state.flag = false; await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "SubChild:willUnmount", - "SubChild:willDestroy", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "SubChild:willUnmount", + "SubChild:willDestroy", + "Child:willDestroy", + "Parent:patched", + ] + `); // we now resolve def, so the child rendering is now complete. def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); test("rendering component again in next microtick", async () => { @@ -682,33 +813,39 @@ test("rendering component again in next microtick", async () => { const env = { config: { flag: false } }; await mount(Parent, fixture, { env }); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); fixture.querySelector("button")!.click(); await nextTick(); expect(fixture.innerHTML).toBe("
Child
"); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:willDestroy", - "Parent:willPatch", - "Child:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:willDestroy", + "Parent:willPatch", + "Child:mounted", + "Parent:patched", + ] + `); }); test("concurrent renderings scenario 1", async () => { @@ -749,60 +886,68 @@ test("concurrent renderings scenario 1", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); stateB.fromB = "c"; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + "ComponentA:rendered", + ] + `); expect(ComponentC.prototype.someValue).toBeCalledTimes(1); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("

2c

"); expect(ComponentC.prototype.someValue).toBeCalledTimes(2); - expect([ - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:willPatch", - "ComponentC:patched", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentC:willPatch", + "ComponentC:patched", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 2", async () => { @@ -842,63 +987,71 @@ test("concurrent renderings scenario 2", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("
1

1b

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("
1

1b

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + "ComponentA:rendered", + ] + `); stateB.fromB = "c"; await nextTick(); expect(fixture.innerHTML).toBe("
1

1b

"); - expect([ - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + ] + `); defs[1].resolve(); // resolve rendering initiated in B await nextTick(); expect(fixture.innerHTML).toBe("
2

2c

"); - expect([ - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:willPatch", - "ComponentC:patched", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentC:willPatch", + "ComponentC:patched", + "ComponentB:patched", + "ComponentA:patched", + ] + `); defs[0].resolve(); // resolve rendering initiated in A await nextTick(); expect(fixture.innerHTML).toBe("
2

2c

"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); test("concurrent renderings scenario 2bis", async () => { @@ -937,63 +1090,71 @@ test("concurrent renderings scenario 2bis", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + "ComponentA:rendered", + ] + `); stateB.fromB = "c"; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentB:rendered", + ] + `); defs[0].resolve(); // resolve rendering initiated in A await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); // TODO: is this what we want?? 2b could be ok too - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defs[1].resolve(); // resolve rendering initiated in B await nextTick(); expect(fixture.innerHTML).toBe("

2c

"); - expect([ - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:willPatch", - "ComponentC:patched", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentC:willPatch", + "ComponentC:patched", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 3", async () => { @@ -1047,70 +1208,78 @@ test("concurrent renderings scenario 3", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentD:setup", - "ComponentD:willStart", - "ComponentC:rendered", - "ComponentD:willRender", - "ComponentD:rendered", - "ComponentD:mounted", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentD:setup", + "ComponentD:willStart", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:rendered", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentD:mounted", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); stateC.fromC = "d"; await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defB.resolve(); // resolve rendering initiated in A (still blocked in D) await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentD:willUpdateProps", - "ComponentC:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentC:willRender", + "ComponentD:willUpdateProps", + "ComponentC:rendered", + "ComponentB:rendered", + ] + `); defsD[0].resolve(); // resolve rendering initiated in C (should be ignored) await nextTick(); expect(fixture.innerHTML).toBe("

2d

"); - expect([ - "ComponentD:willRender", - "ComponentD:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:willPatch", - "ComponentD:willPatch", - "ComponentD:patched", - "ComponentC:patched", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentA:willPatch", + "ComponentC:willPatch", + "ComponentB:willPatch", + "ComponentD:willPatch", + "ComponentD:patched", + "ComponentB:patched", + "ComponentC:patched", + "ComponentA:patched", + ] + `); expect(ComponentD.prototype.someValue).toBeCalledTimes(2); }); @@ -1165,77 +1334,85 @@ test("concurrent renderings scenario 4", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentD:setup", - "ComponentD:willStart", - "ComponentC:rendered", - "ComponentD:willRender", - "ComponentD:rendered", - "ComponentD:mounted", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentD:setup", + "ComponentD:willStart", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:rendered", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentD:mounted", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); stateC.fromC = "d"; await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defB.resolve(); // resolve rendering initiated in A (still blocked in D) await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); - expect([ - "ComponentB:willRender", - "ComponentC:willUpdateProps", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentD:willUpdateProps", - "ComponentC:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:willUpdateProps", + "ComponentC:willRender", + "ComponentD:willUpdateProps", + "ComponentC:rendered", + "ComponentB:rendered", + ] + `); defsD[1].resolve(); // completely resolve rendering initiated in A await nextTick(); expect(fixture.innerHTML).toBe("

1c

"); expect(ComponentD.prototype.someValue).toBeCalledTimes(1); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defsD[0].resolve(); // resolve rendering initiated in C (should be ignored) await nextTick(); expect(fixture.innerHTML).toBe("

2d

"); expect(ComponentD.prototype.someValue).toBeCalledTimes(2); - expect([ - "ComponentD:willRender", - "ComponentD:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:willPatch", - "ComponentD:willPatch", - "ComponentD:patched", - "ComponentC:patched", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentA:willPatch", + "ComponentC:willPatch", + "ComponentB:willPatch", + "ComponentD:willPatch", + "ComponentD:patched", + "ComponentB:patched", + "ComponentC:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 5", async () => { @@ -1266,55 +1443,63 @@ test("concurrent renderings scenario 5", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); component.state.fromA = 3; await nextTick(); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); defsB[0].resolve(); // resolve first re-rendering (should be ignored) await nextTick(); expect(fixture.innerHTML).toBe("

1

"); expect(ComponentB.prototype.someValue).toBeCalledTimes(1); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); defsB[1].resolve(); // resolve second re-rendering await nextTick(); expect(fixture.innerHTML).toBe("

3

"); expect(ComponentB.prototype.someValue).toBeCalledTimes(2); - expect([ - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 6", async () => { @@ -1346,55 +1531,63 @@ test("concurrent renderings scenario 6", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); component.state.fromA = 3; await nextTick(); expect(fixture.innerHTML).toBe("

1

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); defsB[1].resolve(); // resolve second re-rendering await nextTick(); expect(fixture.innerHTML).toBe("

3

"); expect(ComponentB.prototype.someValue).toBeCalledTimes(2); - expect([ - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentB:patched", + "ComponentA:patched", + ] + `); defsB[0].resolve(); // resolve first re-rendering (should be ignored) await nextTick(); expect(fixture.innerHTML).toBe("

3

"); expect(ComponentB.prototype.someValue).toBeCalledTimes(2); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); test("concurrent renderings scenario 7", async () => { @@ -1426,34 +1619,40 @@ test("concurrent renderings scenario 7", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1b

"); expect(ComponentB.prototype.someValue).toBeCalledTimes(1); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

2c

"); - expect(ComponentB.prototype.someValue).toBeCalledTimes(2); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(ComponentB.prototype.someValue).toBeCalledTimes(3); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 8", async () => { @@ -1480,44 +1679,50 @@ test("concurrent renderings scenario 8", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = 2; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + ] + `); stateB.fromB = "c"; await nextTick(); expect(fixture.innerHTML).toBe("

1b

"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("

2c

"); - expect([ - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 9", async () => { @@ -1577,70 +1782,78 @@ test("concurrent renderings scenario 9", async () => { const component = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("
a1a1

a1b1

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentD:setup", - "ComponentD:willStart", - "ComponentC:rendered", - "ComponentD:willRender", - "ComponentD:rendered", - "ComponentD:mounted", - "ComponentC:mounted", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentC:willRender", + "ComponentD:setup", + "ComponentD:willStart", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:rendered", + "ComponentA:rendered", + "ComponentD:mounted", + "ComponentC:mounted", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); component.state.fromA = "a2"; await nextTick(); expect(fixture.innerHTML).toBe("
a1a1

a1b1

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentC:willUpdateProps", - "ComponentA:rendered", - "ComponentC:willRender", - "ComponentD:willUpdateProps", - "ComponentC:rendered", - "ComponentD:willRender", - "ComponentD:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentC:willUpdateProps", + "ComponentC:willRender", + "ComponentD:willUpdateProps", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:rendered", + "ComponentA:rendered", + ] + `); stateC.fromC = "b2"; await nextTick(); expect(fixture.innerHTML).toBe("
a1a1

a1b1

"); - expect([ - "ComponentC:willRender", - "ComponentD:willUpdateProps", - "ComponentC:rendered", - "ComponentD:willRender", - "ComponentD:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentC:willRender", + "ComponentD:willUpdateProps", + "ComponentD:willRender", + "ComponentD:rendered", + "ComponentC:rendered", + ] + `); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
a2a2

a2b2

"); - expect([ - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentA:willPatch", - "ComponentC:willPatch", - "ComponentD:willPatch", - "ComponentB:willPatch", - "ComponentB:patched", - "ComponentD:patched", - "ComponentC:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:willPatch", + "ComponentC:willPatch", + "ComponentD:willPatch", + "ComponentB:willPatch", + "ComponentB:patched", + "ComponentD:patched", + "ComponentC:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 10", async () => { @@ -1698,57 +1911,65 @@ test("concurrent renderings scenario 10", async () => { const componentA = await mount(ComponentA, fixture); expect(fixture.innerHTML).toBe("

"); - expect([ - "ComponentA:setup", - "ComponentA:willStart", - "ComponentA:willRender", - "ComponentB:setup", - "ComponentB:willStart", - "ComponentA:rendered", - "ComponentB:willRender", - "ComponentB:rendered", - "ComponentB:mounted", - "ComponentA:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:setup", + "ComponentA:willStart", + "ComponentA:willRender", + "ComponentB:setup", + "ComponentB:willStart", + "ComponentB:willRender", + "ComponentB:rendered", + "ComponentA:rendered", + "ComponentB:mounted", + "ComponentA:mounted", + ] + `); stateB.hasChild = true; await nextTick(); expect(fixture.innerHTML).toBe("

"); - expect([ - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentB:rendered", + ] + `); componentA.state.value = 2; defC.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("

"); - expect([ - "ComponentA:willRender", - "ComponentB:willUpdateProps", - "ComponentA:rendered", - "ComponentC:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentA:willRender", + "ComponentB:willUpdateProps", + "ComponentA:rendered", + "ComponentC:willDestroy", + ] + `); defB.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("

2

"); expect(rendered).toBe(1); - expect([ - "ComponentB:willRender", - "ComponentC:setup", - "ComponentC:willStart", - "ComponentB:rendered", - "ComponentC:willRender", - "ComponentC:rendered", - "ComponentA:willPatch", - "ComponentB:willPatch", - "ComponentC:mounted", - "ComponentB:patched", - "ComponentA:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "ComponentB:willRender", + "ComponentC:setup", + "ComponentC:willStart", + "ComponentB:rendered", + "ComponentC:willRender", + "ComponentC:rendered", + "ComponentA:willPatch", + "ComponentB:willPatch", + "ComponentC:mounted", + "ComponentB:patched", + "ComponentA:patched", + ] + `); }); test("concurrent renderings scenario 11", async () => { @@ -1782,18 +2003,20 @@ test("concurrent renderings scenario 11", async () => { } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
1|3
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.valA = 2; await nextTick(); @@ -1805,17 +2028,19 @@ test("concurrent renderings scenario 11", async () => { await def; await nextTick(); expect(fixture.innerHTML).toBe("
2|5
"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Parent:rendered", + "Child:willRender", + "Child:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("concurrent renderings scenario 12", async () => { @@ -1854,44 +2079,60 @@ test("concurrent renderings scenario 12", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
1
"); expect(rendered).toBe(1); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.val = 2; await nextTick(); expect(fixture.innerHTML).toBe("
1
"); expect(rendered).toBe(2); - expect(["Parent:willRender", "Child:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Parent:rendered", + ] + `); parent.state.val = 3; parent.state.val = 4; await nextTick(); expect(fixture.innerHTML).toBe("
1
"); expect(rendered).toBe(3); - expect(["Parent:willRender", "Child:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Parent:rendered", + ] + `); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("
4
"); expect(rendered).toBe(3); - expect([ - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("concurrent renderings scenario 13", async () => { @@ -1927,46 +2168,62 @@ test("concurrent renderings scenario 13", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
0
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + "Child:willRender", + "Child:rendered", + ] + `); await nextTick(); // wait for changes triggered in mounted to be applied expect(fixture.innerHTML).toBe("
1
"); - expect(["Child:willPatch", "Child:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willPatch", + "Child:patched", + ] + `); parent.state.bool = true; await nextTick(); // wait for this change to be applied - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:mounted", - "Parent:patched", - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:mounted", + "Parent:patched", + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", + ] + `); await nextTick(); // wait for changes triggered in mounted to be applied expect(fixture.innerHTML).toBe("
01
"); - 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("concurrent renderings scenario 14", async () => { @@ -2007,23 +2264,25 @@ test("concurrent renderings scenario 14", async () => { } const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("

123

"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // trigger a re-rendering of the whole tree a.state.fromA += 10; @@ -2034,14 +2293,18 @@ test("concurrent renderings scenario 14", async () => { await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("

123

"); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + ] + `); // trigger a re-rendering from C, which will remap its new fiber c!.state.fromC += 10; @@ -2054,21 +2317,21 @@ test("concurrent renderings scenario 14", async () => { expect(fixture.innerHTML).toBe( "

111213

" ); - expect([ - "C:willRender", - "C:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:willPatch", + "B:willPatch", + "C:willPatch", + "C:patched", + "B:patched", + "A:patched", + ] + `); }); test("concurrent renderings scenario 15", async () => { @@ -2108,23 +2371,25 @@ test("concurrent renderings scenario 15", async () => { const app = new App(A); const a = await app.mount(fixture); expect(fixture.innerHTML).toBe("

123

"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // trigger a re-rendering of the whole tree a.state.fromA += 10; @@ -2135,14 +2400,18 @@ test("concurrent renderings scenario 15", async () => { await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("

123

"); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + ] + `); // trigger a re-rendering from C, which will remap its new fiber c!.state.fromC += 10; @@ -2153,31 +2422,33 @@ test("concurrent renderings scenario 15", async () => { // counter to 0) app.scheduler.flush(); expect(fixture.innerHTML).toBe("

123

"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // wait a bit and simulate another flush (we expect nothing to change as well) await nextMicroTick(); app.scheduler.flush(); expect(fixture.innerHTML).toBe("

123

"); - expect(["C:willRender", "C:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); await nextTick(); expect(fixture.innerHTML).toBe( "

111213

" ); - expect([ - "B:willRender", - "C:willUpdateProps", - "B:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:willPatch", + "B:willPatch", + "C:willPatch", + "C:patched", + "B:patched", + "A:patched", + ] + `); }); test("concurrent renderings scenario 16", async () => { @@ -2225,23 +2496,25 @@ test("concurrent renderings scenario 16", async () => { } const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("1:2:3: "); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // trigger a re-rendering of the whole tree a.state.fromA += 10; @@ -2253,16 +2526,18 @@ test("concurrent renderings scenario 16", async () => { await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("1:2:3: "); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - "C:willRender", - "C:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + ] + `); // trigger a re-rendering from C, which will remap its new fiber c!.state.fromC += 10; @@ -2272,20 +2547,22 @@ test("concurrent renderings scenario 16", async () => { b!.state.fromB += 10; b!.render(); await nextTick(); - expect([ - "C:willRender", - "D:setup", - "D:willStart", - "C:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - "C:willRender", - "D:setup", - "D:willStart", - "C:rendered", - "D:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "C:willRender", + "D:setup", + "D:willStart", + "C:rendered", + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "D:setup", + "D:willStart", + "C:rendered", + "B:rendered", + "D:willDestroy", + ] + `); // at this point, C rendering is still pending, and nothing should have been // updated yet. @@ -2293,17 +2570,19 @@ test("concurrent renderings scenario 16", async () => { await nextTick(); await nextTick(); expect(fixture.innerHTML).toBe("11:12:13: D"); - expect([ - "D:willRender", - "D:rendered", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "D:mounted", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "D:willRender", + "D:rendered", + "A:willPatch", + "B:willPatch", + "C:willPatch", + "D:mounted", + "C:patched", + "B:patched", + "A:patched", + ] + `); }); test("calling render in destroy", async () => { @@ -2353,7 +2632,15 @@ test("calling render in destroy", async () => { const app = new App(A); await app.mount(fixture); expect(fixture.innerHTML).toBe("
a
"); - expect(["B:setup", "B:willStart", "B:willRender", "B:rendered", "B:mounted"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "B:mounted", + ] + `); a.state = "A"; a.key = 2; @@ -2361,19 +2648,21 @@ test("calling render in destroy", async () => { await nextTick(); // this nextTick is critical, otherwise jest may silently swallow errors await nextTick(); - expect([ - "B:setup", - "B:willStart", - "B:willRender", - "B:rendered", - "B:willUnmount", - "B:willDestroy", - "B:mounted", - "B:willRender", - "B:rendered", - "B:willPatch", - "B:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "B:willUnmount", + "B:willDestroy", + "B:mounted", + "B:willRender", + "B:rendered", + "B:willPatch", + "B:patched", + ] + `); expect(fixture.innerHTML).toBe("
A
"); }); @@ -2394,13 +2683,15 @@ test("change state and call manually render: no unnecessary rendering", async () } const test = await mount(Test, fixture); - expect([ - "Test:setup", - "Test:willStart", - "Test:willRender", - "Test:rendered", - "Test:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Test:setup", + "Test:willStart", + "Test:willRender", + "Test:rendered", + "Test:mounted", + ] + `); expect(fixture.innerHTML).toBe("
1
"); expect(numberOfRender).toBe(1); @@ -2409,7 +2700,14 @@ test("change state and call manually render: no unnecessary rendering", async () await nextTick(); expect(fixture.innerHTML).toBe("
2
"); expect(numberOfRender).toBe(2); - expect(["Test:willRender", "Test:rendered", "Test:willPatch", "Test:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Test:willRender", + "Test:rendered", + "Test:willPatch", + "Test:patched", + ] + `); }); test("changing state before first render does not trigger a render", async () => { @@ -2421,7 +2719,7 @@ test("changing state before first render does not trigger a render", async () => setup() { useLogLifecycle(); this.state.drinks++; - onWillStart(() => { + onWillStart(async () => { this.state.drinks++; }); } @@ -2431,18 +2729,20 @@ test("changing state before first render does not trigger a render", async () => } } await mount(TestW, fixture); - expect([ - "TestW:setup", - "TestW:willStart", - "TestW:willRender", - "TestW:rendered", - "TestW:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "TestW:setup", + "TestW:willStart", + "TestW:willRender", + "TestW:rendered", + "TestW:mounted", + ] + `); await nextTick(); expect(renders).toBe(1); expect(fixture.innerHTML).toBe("
3
"); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); test("changing state before first render does not trigger a render (with parent)", async () => { @@ -2454,7 +2754,7 @@ test("changing state before first render does not trigger a render (with parent) setup() { useLogLifecycle(); this.state.drinks++; - onWillStart(() => { + onWillStart(async () => { this.state.drinks++; }); } @@ -2475,29 +2775,33 @@ test("changing state before first render does not trigger a render (with parent) const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.state.flag = true; await nextTick(); expect(fixture.innerHTML).toBe("
3
"); expect(renders).toBe(1); - expect([ - "Parent:willRender", - "TestW:setup", - "TestW:willStart", - "Parent:rendered", - "TestW:willRender", - "TestW:rendered", - "Parent:willPatch", - "TestW:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "TestW:setup", + "TestW:willStart", + "Parent:rendered", + "TestW:willRender", + "TestW:rendered", + "Parent:willPatch", + "TestW:mounted", + "Parent:patched", + ] + `); }); test("two renderings initiated between willPatch and patched", async () => { @@ -2529,77 +2833,99 @@ test("two renderings initiated between willPatch and patched", async () => { await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
Panel1
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Panel:setup", - "Panel:willStart", - "Parent:rendered", - "Panel:willRender", - "Panel:rendered", - "Panel:mounted", - "Parent:mounted", - "Parent:willRender", - "Panel:willUpdateProps", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Panel:setup", + "Panel:willStart", + "Panel:willRender", + "Panel:rendered", + "Parent:rendered", + "Panel:mounted", + "Parent:mounted", + "Parent:willRender", + "Panel:willUpdateProps", + "Panel:willRender", + "Panel:rendered", + "Parent:rendered", + ] + `); await nextMicroTick(); - expect(["Panel:willRender", "Panel:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); await nextTick(); - expect(["Parent:willPatch", "Panel:willPatch", "Panel:patched", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Panel:willPatch", + "Panel:patched", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("
Panel1Mounted
"); parent.state.panel = "Panel2"; await nextTick(); expect(fixture.innerHTML).toBe("
Panel2
"); - expect([ - "Parent:willRender", - "Panel:setup", - "Panel:willStart", - "Parent:rendered", - "Panel:willRender", - "Panel:rendered", - "Parent:willPatch", - "Panel:willUnmount", - "Panel:willDestroy", - "Panel:mounted", - "Parent:patched", - "Parent:willRender", - "Panel:willUpdateProps", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Panel:setup", + "Panel:willStart", + "Panel:willRender", + "Panel:rendered", + "Parent:rendered", + "Parent:willPatch", + "Panel:willUnmount", + "Panel:willDestroy", + "Panel:mounted", + "Parent:patched", + "Parent:willRender", + "Panel:willUpdateProps", + "Panel:willRender", + "Panel:rendered", + "Parent:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("
Panel2Mounted
"); - expect([ - "Panel:willRender", - "Panel:rendered", - "Parent:willPatch", - "Panel:willPatch", - "Panel:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Panel:willPatch", + "Panel:patched", + "Parent:patched", + ] + `); parent.state.flag = false; await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Panel:willUnmount", - "Panel:willDestroy", - "Parent:patched", - "Parent:willRender", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Panel:willUnmount", + "Panel:willDestroy", + "Parent:patched", + "Parent:willRender", + "Parent:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Parent:patched", + ] + `); }); test("parent and child rendered at exact same time", async () => { @@ -2624,35 +2950,39 @@ test("parent and child rendered at exact same time", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("0"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = 1; parent.render(); child.render(); await nextTick(); expect(fixture.innerHTML).toBe("1"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("delay willUpdateProps", async () => { @@ -2683,18 +3013,20 @@ test("delay willUpdateProps", async () => { } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("0_0"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); promise = makeDeferred(); const prom1 = promise; @@ -2703,7 +3035,13 @@ test("delay willUpdateProps", async () => { parent.render(); await nextTick(); expect(fixture.innerHTML).toBe("0_0"); - expect(["Parent:willRender", "Child:willUpdateProps", "Parent:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Parent:rendered", + ] + `); promise = makeDeferred(); const prom2 = promise; @@ -2716,23 +3054,32 @@ test("delay willUpdateProps", async () => { await nextTick(); expect(fixture.innerHTML).toBe("2_1"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Parent:rendered", + "Child:willRender", + "Child:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); prom1.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("2_2"); - 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("delay willUpdateProps with rendering grandchild", async () => { @@ -2788,28 +3135,30 @@ test("delay willUpdateProps with rendering grandchild", async () => { const parent = await mount(GrandParent, fixture); expect(fixture.innerHTML).toBe("0_0
"); - expect([ - "GrandParent:setup", - "GrandParent:willStart", - "GrandParent:willRender", - "Parent:setup", - "Parent:willStart", - "GrandParent:rendered", - "Parent:willRender", - "DelayedChild:setup", - "DelayedChild:willStart", - "ReactiveChild:setup", - "ReactiveChild:willStart", - "Parent:rendered", - "DelayedChild:willRender", - "DelayedChild:rendered", - "ReactiveChild:willRender", - "ReactiveChild:rendered", - "ReactiveChild:mounted", - "DelayedChild:mounted", - "Parent:mounted", - "GrandParent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandParent:setup", + "GrandParent:willStart", + "GrandParent:willRender", + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "DelayedChild:setup", + "DelayedChild:willStart", + "DelayedChild:willRender", + "DelayedChild:rendered", + "ReactiveChild:setup", + "ReactiveChild:willStart", + "ReactiveChild:willRender", + "ReactiveChild:rendered", + "Parent:rendered", + "GrandParent:rendered", + "ReactiveChild:mounted", + "DelayedChild:mounted", + "Parent:mounted", + "GrandParent:mounted", + ] + `); promise = makeDeferred(); const prom1 = promise; @@ -2819,17 +3168,19 @@ test("delay willUpdateProps with rendering grandchild", async () => { reactiveChild.render(); await nextTick(); expect(fixture.innerHTML).toBe("0_0
"); - expect([ - "GrandParent:willRender", - "Parent:willUpdateProps", - "GrandParent:rendered", - "Parent:willRender", - "DelayedChild:willUpdateProps", - "ReactiveChild:willUpdateProps", - "Parent:rendered", - "ReactiveChild:willRender", - "ReactiveChild:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandParent:willRender", + "Parent:willUpdateProps", + "Parent:willRender", + "DelayedChild:willUpdateProps", + "ReactiveChild:willUpdateProps", + "ReactiveChild:willRender", + "ReactiveChild:rendered", + "Parent:rendered", + "GrandParent:rendered", + ] + `); promise = makeDeferred(); const prom2 = promise; @@ -2839,43 +3190,49 @@ test("delay willUpdateProps with rendering grandchild", async () => { reactiveChild.render(); await nextTick(); expect(fixture.innerHTML).toBe("0_0
"); - expect([ - "GrandParent:willRender", - "Parent:willUpdateProps", - "GrandParent:rendered", - "Parent:willRender", - "DelayedChild:willUpdateProps", - "ReactiveChild:willUpdateProps", - "Parent:rendered", - "ReactiveChild:willRender", - "ReactiveChild:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandParent:willRender", + "Parent:willUpdateProps", + "Parent:willRender", + "DelayedChild:willUpdateProps", + "ReactiveChild:willUpdateProps", + "ReactiveChild:willRender", + "ReactiveChild:rendered", + "Parent:rendered", + "GrandParent:rendered", + ] + `); prom2.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("2_1
"); - expect([ - "DelayedChild:willRender", - "DelayedChild:rendered", - "GrandParent:willPatch", - "Parent:willPatch", - "ReactiveChild:willPatch", - "DelayedChild:willPatch", - "DelayedChild:patched", - "ReactiveChild:patched", - "Parent:patched", - "GrandParent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "DelayedChild:willRender", + "DelayedChild:rendered", + "GrandParent:willPatch", + "ReactiveChild:willPatch", + "Parent:willPatch", + "DelayedChild:willPatch", + "DelayedChild:patched", + "Parent:patched", + "ReactiveChild:patched", + "GrandParent:patched", + ] + `); prom1.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("2_2
"); - expect([ - "DelayedChild:willRender", - "DelayedChild:rendered", - "DelayedChild:willPatch", - "DelayedChild:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "DelayedChild:willRender", + "DelayedChild:rendered", + "DelayedChild:willPatch", + "DelayedChild:patched", + ] + `); }); test("two sequential renderings before an animation frame", async () => { @@ -2896,18 +3253,20 @@ test("two sequential renderings before an animation frame", async () => { } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("0"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = 1; await nextMicroTick(); @@ -2916,13 +3275,15 @@ test("two sequential renderings before an animation frame", async () => { await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("0"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + ] + `); parent.state.value = 2; // enough microticks to wait for render + willupdateprops @@ -2932,17 +3293,26 @@ test("two sequential renderings before an animation frame", async () => { await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("0"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + ] + `); await nextTick(); // we check here that the willPatch and patched hooks are called only once - expect(["Parent:willPatch", "Child:willPatch", "Child:patched", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("t-key on dom node having a component", async () => { @@ -2969,15 +3339,17 @@ test("t-key on dom node having a component", async () => { parent.render(); await nextTick(); - expect([ - "Child (1):setup", - "Child (1):willStart", - "Child (1):willRender", - "Child (1):rendered", - "Child (1):mounted", - "Child (2):setup", - "Child (2):willStart", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (1):setup", + "Child (1):willStart", + "Child (1):willRender", + "Child (1):rendered", + "Child (1):mounted", + "Child (2):setup", + "Child (2):willStart", + ] + `); expect(fixture.innerHTML).toBe("
1
"); parent.key = 3; parent.render(); @@ -2991,16 +3363,18 @@ test("t-key on dom node having a component", async () => { await nextTick(); expect(fixture.innerHTML).toBe("
3
"); - expect([ - "Child (3):setup", - "Child (3):willStart", - "Child (3):willRender", - "Child (3):rendered", - "Child (2):willDestroy", - "Child (1):willUnmount", - "Child (1):willDestroy", - "Child (3):mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (3):setup", + "Child (3):willStart", + "Child (3):willRender", + "Child (3):rendered", + "Child (2):willDestroy", + "Child (1):willUnmount", + "Child (1):willDestroy", + "Child (3):mounted", + ] + `); }); test("t-key on dynamic async component (toggler is never patched)", async () => { @@ -3027,15 +3401,17 @@ test("t-key on dynamic async component (toggler is never patched)", async () => parent.render(); await nextTick(); - expect([ - "Child (1):setup", - "Child (1):willStart", - "Child (1):willRender", - "Child (1):rendered", - "Child (1):mounted", - "Child (2):setup", - "Child (2):willStart", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (1):setup", + "Child (1):willStart", + "Child (1):willRender", + "Child (1):rendered", + "Child (1):mounted", + "Child (2):setup", + "Child (2):willStart", + ] + `); expect(fixture.innerHTML).toBe("
1
"); parent.key = 3; parent.render(); @@ -3049,16 +3425,18 @@ test("t-key on dynamic async component (toggler is never patched)", async () => await nextTick(); expect(fixture.innerHTML).toBe("
3
"); - expect([ - "Child (3):setup", - "Child (3):willStart", - "Child (3):willRender", - "Child (3):rendered", - "Child (2):willDestroy", - "Child (1):willUnmount", - "Child (1):willDestroy", - "Child (3):mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (3):setup", + "Child (3):willStart", + "Child (3):willRender", + "Child (3):rendered", + "Child (2):willDestroy", + "Child (1):willUnmount", + "Child (1):willDestroy", + "Child (3):mounted", + ] + `); }); test("t-foreach with dynamic async component", async () => { @@ -3087,15 +3465,17 @@ test("t-foreach with dynamic async component", async () => { parent.render(); await nextTick(); - expect([ - "Child (1):setup", - "Child (1):willStart", - "Child (1):willRender", - "Child (1):rendered", - "Child (1):mounted", - "Child (2):setup", - "Child (2):willStart", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (1):setup", + "Child (1):willStart", + "Child (1):willRender", + "Child (1):rendered", + "Child (1):mounted", + "Child (2):setup", + "Child (2):willStart", + ] + `); expect(fixture.innerHTML).toBe("
1
"); parent.list = [, , [3]]; parent.render(); @@ -3108,16 +3488,18 @@ test("t-foreach with dynamic async component", async () => { await nextTick(); expect(fixture.innerHTML).toBe("
3
"); - expect([ - "Child (3):setup", - "Child (3):willStart", - "Child (3):willRender", - "Child (3):rendered", - "Child (2):willDestroy", - "Child (1):willUnmount", - "Child (1):willDestroy", - "Child (3):mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child (3):setup", + "Child (3):willStart", + "Child (3):willRender", + "Child (3):rendered", + "Child (2):willDestroy", + "Child (1):willUnmount", + "Child (1):willDestroy", + "Child (3):mounted", + ] + `); }); test("Cascading renders after microtaskTick", async () => { @@ -3186,18 +3568,20 @@ test("rendering parent twice, with different props on child and stuff", async () const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = 2; // wait for child to be rendered @@ -3205,30 +3589,34 @@ test("rendering parent twice, with different props on child and stuff", async () await nextMicroTick(); await nextMicroTick(); await nextMicroTick(); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + ] + `); expect(fixture.innerHTML).toBe("1"); // trigger a render, but keep the props for child the same parent.render(); await nextTick(); expect(fixture.innerHTML).toBe("2"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("delayed rendering, but then initial rendering is cancelled by yet another render", async () => { @@ -3276,67 +3664,79 @@ test("delayed rendering, but then initial rendering is cancelled by yet another const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("

36

"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "D:setup", - "D:willStart", - "C:rendered", - "D:willRender", - "D:rendered", - "D:mounted", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "D:setup", + "D:willStart", + "D:willRender", + "D:rendered", + "C:rendered", + "B:rendered", + "A:rendered", + "D:mounted", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // update B and C, but render is blocked by C willupdateProps stateB.someValue = 5; await nextTick(); - expect(["B:willRender", "C:willUpdateProps", "B:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "C:willUpdateProps", + "B:rendered", + ] + `); // update D => render should be delayed, because B is currently rendering fixture.querySelector("button")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // update A => render should go to B and cancel it parent.state.value = 34; await nextTick(); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "C:willUpdateProps", + "B:rendered", + "A:rendered", + ] + `); promC.resolve(); await nextTick(); - expect([ - "C:willRender", - "C:rendered", - "D:willRender", - "D:rendered", - "D:willPatch", - "D:patched", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "C:willRender", + "C:rendered", + "D:willRender", + "D:rendered", + "D:willPatch", + "D:patched", + "A:willPatch", + "B:willPatch", + "C:willPatch", + "C:patched", + "B:patched", + "A:patched", + ] + `); expect(fixture.innerHTML).toBe("

39

"); }); @@ -3385,56 +3785,73 @@ test("delayed rendering, reusing fiber and stuff", async () => { const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("33"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // initiate a render in A, but is blocked in B parent.state.value = 34; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); // initiate a render in C => delayed because of render in A fixture.querySelector("button")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // wait for render in A to be completed prom1.resolve(); await prom2; - expect(["B:willRender", "B:rendered", "C:willRender", "C:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "B:rendered", + "C:willRender", + "C:rendered", + ] + `); // initiate a new render in A => fiber will be reused parent.state.value = 355; await nextTick(); expect(fixture.innerHTML).toBe("355"); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "B:rendered", - "A:willPatch", - "B:willPatch", - "B:patched", - "A:patched", - "C:willPatch", - "C:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + "B:willRender", + "B:rendered", + "A:willPatch", + "B:willPatch", + "B:patched", + "A:patched", + "C:willPatch", + "C:patched", + ] + `); }); test("delayed rendering, then component is destroyed and stuff", async () => { @@ -3471,23 +3888,25 @@ test("delayed rendering, then component is destroyed and stuff", async () => { const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("3"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // initiate a render in C (so will be first task) fixture.querySelector("button")!.click(); @@ -3495,22 +3914,30 @@ test("delayed rendering, then component is destroyed and stuff", async () => { // it blocks the render C parent.state.value = 34; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); // wait for render in A to be completed prom1.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("34"); - expect([ - "B:willRender", - "B:rendered", - "A:willPatch", - "B:willPatch", - "C:willUnmount", - "C:willDestroy", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "B:rendered", + "A:willPatch", + "B:willPatch", + "C:willUnmount", + "C:willDestroy", + "B:patched", + "A:patched", + ] + `); await nextTick(); }); @@ -3549,48 +3976,58 @@ test("delayed rendering, reusing fiber then component is destroyed and stuff", const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("A3"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // initiate a render in A, but is blocked in B parent.state.value = 5; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); // initiate a render in C (will be delayed because of render in A) fixture.querySelector("button")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // initiate a render in A, that will destroy B parent.state.value = 23; await nextTick(); expect(fixture.innerHTML).toBe("A"); - expect([ - "A:willRender", - "A:rendered", - "A:willPatch", - "B:willUnmount", - "C:willUnmount", - "C:willDestroy", - "B:willDestroy", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "A:rendered", + "A:willPatch", + "B:willUnmount", + "C:willUnmount", + "C:willDestroy", + "B:willDestroy", + "A:patched", + ] + `); }); test("another scenario with delayed rendering", async () => { @@ -3635,61 +4072,82 @@ test("another scenario with delayed rendering", async () => { const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("A3"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // initiate a render in A, but is blocked in B parent.state.value = 5; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); // initiate a render in C (will be delayed because of render in A) fixture.querySelector("button")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // initiate a render in A, that will destroy B parent.state.value = 23; await onSecondRenderA; await nextMicroTick(); - expect(["A:willRender", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "A:rendered", + ] + `); // rerender A, but without destroying B parent.state.value = 7; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); prom1.resolve(); await nextTick(); expect(fixture.innerHTML).toBe("A7"); - expect([ - "B:willRender", - "B:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "B:willPatch", - "B:patched", - "A:patched", - "C:willPatch", - "C:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "B:rendered", + "C:willRender", + "C:rendered", + "A:willPatch", + "B:willPatch", + "B:patched", + "A:patched", + "C:willPatch", + "C:patched", + ] + `); }); test("delayed fiber does not get rendered if it was cancelled", async () => { @@ -3728,51 +4186,62 @@ test("delayed fiber does not get rendered if it was cancelled", async () => { const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("ABCD"); - expect([ - "A:setup", - "A:willRender", - "B:setup", - "A:rendered", - "B:willRender", - "C:setup", - "B:rendered", - "C:willRender", - "D:setup", - "C:rendered", - "D:willRender", - "D:rendered", - "D:mounted", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willRender", + "B:setup", + "B:willRender", + "C:setup", + "C:willRender", + "D:setup", + "D:willRender", + "D:rendered", + "C:rendered", + "B:rendered", + "A:rendered", + "D:mounted", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // Start a render in C c!.render(true); await nextMicroTick(); - expect(["C:willRender", "C:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "C:willRender", + "D:willRender", + "D:rendered", + "C:rendered", + ] + `); // Start a render in A such that C is already rendered, but D will be delayed // (because A is rendering) then cancelled (when the render from A reaches C) a.render(true); // Make sure the render can go to completion (Cancelled fibers will throw when rendered) await nextTick(); - expect([ - "A:willRender", - "A:rendered", - "B:willRender", - "B:rendered", - "C:willRender", - "C:rendered", - "D:willRender", - "D:rendered", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "D:willPatch", - "D:patched", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willRender", + "C:willRender", + "D:willRender", + "D:rendered", + "C:rendered", + "B:rendered", + "A:rendered", + "A:willPatch", + "D:willPatch", + "C:willPatch", + "B:willPatch", + "B:patched", + "C:patched", + "D:patched", + "A:patched", + ] + `); }); test("destroyed component causes other soon to be destroyed component to rerender, weird stuff happens", async () => { @@ -3817,47 +4286,59 @@ test("destroyed component causes other soon to be destroyed component to rerende const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe(" A "); - 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", + ] + `); // initiate a render in A, but is blocked in B parent.state.flag = true; await def; await nextMicroTick(); - expect([ - "A:willRender", - "B:setup", - "B:willStart", - "C:setup", - "C:willStart", - "A:rendered", - "B:willRender", - "B:rendered", - "C:willRender", - "C:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "A:rendered", + ] + `); // initiate render in A => will cancel renders in B/C and restarts parent.state.valueB = 2; await nextTick(); - expect([ - "A:willRender", - "B:setup", - "B:willStart", - "C:setup", - "C:willStart", - "A:rendered", - "B:willRender", - "B:rendered", - "C:willRender", - "C:rendered", - "B:willDestroy", - "C:willDestroy", - "A:willPatch", - "C:mounted", - "B:mounted", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "A:rendered", + "B:willDestroy", + "C:willDestroy", + "A:willPatch", + "C:mounted", + "B:mounted", + "A:patched", + ] + `); expect(fixture.innerHTML).toBe(" A 22"); }); @@ -3907,58 +4388,64 @@ test("delayed rendering, destruction, stuff happens", async () => { const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("ABCD

36

"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "D:setup", - "D:willStart", - "C:rendered", - "D:willRender", - "D:rendered", - "D:mounted", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "D:setup", + "D:willStart", + "D:willRender", + "D:rendered", + "C:rendered", + "B:rendered", + "A:rendered", + "D:mounted", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // render in A, it updates B and C, but render is blocked in C parent.state.value = 50; await nextTick(); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "C:willUpdateProps", - "B:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "C:willUpdateProps", + "B:rendered", + "A:rendered", + ] + `); // update B => removes child C stateB.hasChild = false; // update D => render should be delayed, because AB is currently rendering fixture.querySelector("button")!.click(); await nextTick(); - expect([ - "B:willRender", - "B:rendered", - "A:willPatch", - "B:willPatch", - "C:willUnmount", - "D:willUnmount", - "D:willDestroy", - "C:willDestroy", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "B:rendered", + "A:willPatch", + "B:willPatch", + "C:willUnmount", + "D:willUnmount", + "D:willDestroy", + "C:willDestroy", + "B:patched", + "A:patched", + ] + `); expect(fixture.innerHTML).toBe("AB"); }); @@ -4008,58 +4495,75 @@ test("renderings, destruction, patch, stuff, ... yet another variation", async ( const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("ABC1D

1

"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "D:setup", - "D:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "D:willRender", - "D:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "D:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "D:setup", + "D:willStart", + "D:willRender", + "D:rendered", + "A:rendered", + "D:mounted", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // render in A, it updates B, will remove C, stopped in B parent.state.value = 50; await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); // update C => render should be delayed, because AB is currently rendering fixture.querySelector("span")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); // resolve prom B => render is done, component C is destroyed promB.resolve(); await nextTick(); - expect([ - "B:willRender", - "B:rendered", - "A:willPatch", - "B:willPatch", - "C:willUnmount", - "C:willDestroy", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "B:rendered", + "A:willPatch", + "B:willPatch", + "C:willUnmount", + "C:willDestroy", + "B:patched", + "A:patched", + ] + `); expect(fixture.innerHTML).toBe("ABD

1

"); // update D => should just render completely independently fixture.querySelector("p")!.click(); await nextTick(); - expect(["D:willRender", "D:rendered", "D:willPatch", "D:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "D:willRender", + "D:rendered", + "D:willPatch", + "D:patched", + ] + `); expect(fixture.innerHTML).toBe("ABD

2

"); }); @@ -4091,34 +4595,38 @@ test("delayed render does not go through when t-component value changed", async const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("AB1"); - expect([ - "A:setup", - "A:willRender", - "B:setup", - "A:rendered", - "B:willRender", - "B:rendered", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willRender", + "B:setup", + "B:willRender", + "B:rendered", + "A:rendered", + "B:mounted", + "A:mounted", + ] + `); // start a render in B b!.state.val = 2; // start a render in A, invalidating the scheduled render of B, which could crash if executed. a.state.component = C; await nextTick(); expect(fixture.innerHTML).toBe("AC"); - expect([ - "A:willRender", - "C:setup", - "A:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "B:willUnmount", - "B:willDestroy", - "C:mounted", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "C:setup", + "C:willRender", + "C:rendered", + "A:rendered", + "A:willPatch", + "B:willUnmount", + "B:willDestroy", + "C:mounted", + "A:patched", + ] + `); }); test("delayed render is not cancelled by upcoming render", async () => { @@ -4147,24 +4655,26 @@ test("delayed render is not cancelled by upcoming render", async () => { await mount(A, fixture); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "B:rendered", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "A:rendered", + "B:mounted", + "A:mounted", + ] + `); expect(fixture.innerHTML).toBe("0initial"); b.props.state.config.test = "red"; b.props.state.groups.push(1); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); await Promise.resolve(); await Promise.resolve(); await Promise.resolve(); @@ -4172,27 +4682,31 @@ test("delayed render is not cancelled by upcoming render", async () => { await Promise.resolve(); b.props.state.config.test = "black"; b.props.state.groups.push(1); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "B:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "B:rendered", + "A:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("2black"); - expect([ - "A:willRender", - "B:willUpdateProps", - "A:rendered", - "B:willRender", - "B:rendered", - "A:willPatch", - "B:willPatch", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "B:willRender", + "B:rendered", + "A:rendered", + "A:willPatch", + "B:willPatch", + "B:patched", + "A:patched", + ] + `); }); test("components are not destroyed between animation frame", async () => { @@ -4224,12 +4738,27 @@ test("components are not destroyed between animation frame", async () => { } const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("A"); - 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", + ] + `); // turn the flag on, this will render A and stops at B because of def a.state.flag = true; 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", + ] + `); // force a render of A // => owl will need to create a new B component @@ -4247,20 +4776,21 @@ test("components are not destroyed between animation frame", async () => { // resolve def, so B render is unblocked def.resolve(); await nextTick(); - expect([ - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - // animation frame callback starts here - "B:willDestroy", // B is destroyed here - "A:willPatch", - "C:mounted", - "B:mounted", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "B:willDestroy", + "A:willPatch", + "C:mounted", + "B:mounted", + "A:patched", + ] + `); }); test("component destroyed just after render", async () => { @@ -4283,26 +4813,35 @@ test("component destroyed just after render", async () => { } const a = await mount(A, fixture); expect(fixture.innerHTML).toBe("B1"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "B:rendered", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "A:rendered", + "B:mounted", + "A:mounted", + ] + `); stateB!.value++; // force a render of B await nextMicroTick(); // wait for B render to actually start a.__owl__.app.destroy(); - expect(["A:willUnmount", "B:willUnmount", "B:willDestroy", "A:willDestroy"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willUnmount", + "B:willUnmount", + "B:willDestroy", + "A:willDestroy", + ] + `); await nextTick(); // check that B was not rendered after being destroyed - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); // test.skip("components with shouldUpdate=false", async () => { diff --git a/tests/components/error_handling.test.ts b/tests/components/error_handling.test.ts index b5fecf5a9..b9b4b36e0 100644 --- a/tests/components/error_handling.test.ts +++ b/tests/components/error_handling.test.ts @@ -19,6 +19,7 @@ import { snapshotEverything, useLogLifecycle, nextAppError, + steps, } from "../helpers"; import { OwlError } from "../../src/common/owl_error"; @@ -75,8 +76,9 @@ describe("basics", () => { } const app = new App(Parent); let error: Error; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( 'Cannot find the definition of component "SomeMispelledComponent"' ); await mountProm; @@ -95,8 +97,9 @@ describe("basics", () => { } const app = new App(Parent, { test: true }); let error: Error; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( 'Cannot find the definition of component "SomeMispelledComponent"' ); await mountProm; @@ -115,8 +118,9 @@ describe("basics", () => { } const app = new App(Parent as typeof Component); let error: Error; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( '"SomeComponent" is not a Component. It must inherit from the Component class' ); await mountProm; @@ -132,8 +136,9 @@ describe("basics", () => { } const app = new App(Parent as typeof Component); let error: Error; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( 'Cannot find the definition of component "MissingChild", missing static components key in parent' ); await mountProm; @@ -196,8 +201,9 @@ function(app, bdom, helpers) { }`; const app = new App(Parent as typeof Component); let error: Error; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow(expectedErrorMessage); + await expect(appError).resolves.toThrow(expectedErrorMessage); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe(expectedErrorMessage); @@ -243,8 +249,9 @@ describe("errors and promises", () => { const app = new App(Root); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); @@ -267,8 +274,9 @@ describe("errors and promises", () => { const app = new App(Root); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); @@ -290,8 +298,9 @@ describe("errors and promises", () => { const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted"); + await expect(appError).resolves.toThrow("error occurred in onMounted"); await mountProm; expect(error!).toBeDefined(); expect(error!.stack).toContain("Root.setup"); @@ -316,8 +325,9 @@ describe("errors and promises", () => { const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillRender"); + await expect(appError).resolves.toThrow("error occurred in onWillRender"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -357,8 +367,9 @@ describe("errors and promises", () => { const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart"); + await expect(appError).resolves.toThrow("error occurred in onWillStart"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -425,8 +436,9 @@ describe("errors and promises", () => { const app = new App(Parent); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); @@ -471,8 +483,9 @@ describe("errors and promises", () => { const app = new App(Parent); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); @@ -501,8 +514,9 @@ describe("errors and promises", () => { const app = new App(Example, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted"); + await expect(appError).resolves.toThrow("error occurred in onMounted"); await mountProm; expect(error!.message).toBe(`The following error occurred in onMounted: "Error in mounted"`); // 1 additional error is logged because the destruction of the app causes @@ -576,9 +590,9 @@ describe("can catch errors", () => { } const app = new App(Root, { test: true }); let error: OwlError; - const crashProm = expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart"); + const appError = nextAppError(app); await app.mount(fixture).catch((e: Error) => (error = e)); - await crashProm; + await expect(appError).resolves.toThrow("error occurred in onWillStart"); expect(error!.message).toBe( `The following error occurred in onWillStart: "No active component (a hook function should only be called in 'setup')"` ); @@ -598,8 +612,9 @@ describe("can catch errors", () => { } const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onMounted"); + await expect(appError).resolves.toThrow("error occurred in onMounted"); await mountProm; expect(error!.message).toBe(`The following error occurred in onMounted: "test error"`); expect(error!.cause).toBe(err); @@ -620,8 +635,9 @@ describe("can catch errors", () => { } const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occurred in onWillStart"); + await expect(appError).resolves.toThrow("error occurred in onWillStart"); await mountProm; expect(error!.message).toBe(`The following error occurred in onWillStart: "test error"`); expect(error!.cause).toBe(err); @@ -641,8 +657,9 @@ describe("can catch errors", () => { } const app = new App(Root); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!.message).toBe( `An error occured in the owl lifecycle (see this Error's "cause" property)` @@ -665,8 +682,9 @@ describe("can catch errors", () => { } const app = new App(Root); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!.message).toBe( `An error occured in the owl lifecycle (see this Error's "cause" property)` @@ -687,8 +705,9 @@ describe("can catch errors", () => { } const app = new App(Root, { test: true }); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("not an Error was thrown in onMounted"); + await expect(appError).resolves.toThrow("not an Error was thrown in onMounted"); await mountProm; expect(error!.message).toBe( `Something that is not an Error was thrown in onMounted (see this Error's "cause" property)` @@ -709,8 +728,9 @@ describe("can catch errors", () => { } const app = new App(Root); let error: OwlError; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!.message).toBe( `An error occured in the owl lifecycle (see this Error's "cause" property)` @@ -948,26 +968,28 @@ describe("can catch errors", () => { } await mount(Root, fixture); expect(fixture.innerHTML).toBe("
Error handled
"); - expect([ - "Root:setup", - "Root:willStart", - "Root:willRender", - "ErrorBoundary:setup", - "ErrorBoundary:willStart", - "Root:rendered", - "ErrorBoundary:willRender", - "ErrorComponent:setup", - "ErrorComponent:willStart", - "ErrorBoundary:rendered", - "ErrorComponent:willRender", - "ErrorComponent:rendered", - "ErrorComponent:mounted", - "boom", - "ErrorBoundary:willRender", - "ErrorBoundary:rendered", - "ErrorBoundary:mounted", - "Root:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Root:setup", + "Root:willStart", + "Root:willRender", + "ErrorBoundary:setup", + "ErrorBoundary:willStart", + "ErrorBoundary:willRender", + "ErrorComponent:setup", + "ErrorComponent:willStart", + "ErrorComponent:willRender", + "ErrorComponent:rendered", + "ErrorBoundary:rendered", + "Root:rendered", + "ErrorComponent:mounted", + "boom", + "ErrorBoundary:willRender", + "ErrorBoundary:rendered", + "ErrorBoundary:mounted", + "Root:mounted", + ] + `); expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0); }); @@ -998,21 +1020,23 @@ describe("can catch errors", () => { } await mount(Root, fixture); expect(fixture.innerHTML).toBe("
Error handled
"); - expect([ - "Root:setup", - "Root:willStart", - "Root:willRender", - "ErrorComponent:setup", - "ErrorComponent:willStart", - "Root:rendered", - "ErrorComponent:willRender", - "ErrorComponent:rendered", - "ErrorComponent:mounted", - "boom", - "Root:willRender", - "Root:rendered", - "Root:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Root:setup", + "Root:willStart", + "Root:willRender", + "ErrorComponent:setup", + "ErrorComponent:willStart", + "ErrorComponent:willRender", + "ErrorComponent:rendered", + "Root:rendered", + "ErrorComponent:mounted", + "boom", + "Root:willRender", + "Root:rendered", + "Root:mounted", + ] + `); expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0); }); @@ -1059,31 +1083,33 @@ describe("can catch errors", () => { } await mount(A, fixture); expect(fixture.innerHTML).toBe("
Error handled
"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "Boom:setup", - "Boom:willStart", - "C:rendered", - "Boom:willRender", - "Boom:rendered", - "Boom:mounted", - "boom", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "Boom:setup", + "Boom:willStart", + "Boom:willRender", + "Boom:rendered", + "C:rendered", + "B:rendered", + "A:rendered", + "Boom:mounted", + "boom", + "C:willRender", + "C:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0); }); @@ -1130,31 +1156,33 @@ describe("can catch errors", () => { } await mount(Root, fixture); expect(fixture.innerHTML).toBe("
OK
Error handled
"); - expect([ - "Root:setup", - "Root:willStart", - "Root:willRender", - "OK:setup", - "OK:willStart", - "ErrorBoundary:setup", - "ErrorBoundary:willStart", - "Root:rendered", - "OK:willRender", - "OK:rendered", - "ErrorBoundary:willRender", - "ErrorComponent:setup", - "ErrorComponent:willStart", - "ErrorBoundary:rendered", - "ErrorComponent:willRender", - "ErrorComponent:rendered", - "ErrorComponent:mounted", - "boom", - "ErrorBoundary:willRender", - "ErrorBoundary:rendered", - "ErrorBoundary:mounted", - "OK:mounted", - "Root:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Root:setup", + "Root:willStart", + "Root:willRender", + "OK:setup", + "OK:willStart", + "OK:willRender", + "OK:rendered", + "ErrorBoundary:setup", + "ErrorBoundary:willStart", + "ErrorBoundary:willRender", + "ErrorComponent:setup", + "ErrorComponent:willStart", + "ErrorComponent:willRender", + "ErrorComponent:rendered", + "ErrorBoundary:rendered", + "Root:rendered", + "ErrorComponent:mounted", + "boom", + "ErrorBoundary:willRender", + "ErrorBoundary:rendered", + "ErrorBoundary:mounted", + "OK:mounted", + "Root:mounted", + ] + `); expect(mockConsoleError).toBeCalledTimes(0); expect(mockConsoleWarn).toBeCalledTimes(0); }); @@ -1481,35 +1509,39 @@ describe("can catch errors", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1
abc
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.hasChild = false; await nextTick(); await nextTick(); await nextTick(); await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("2"); }); @@ -1542,13 +1574,15 @@ describe("can catch errors", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.state.hasChild = true; await nextMicroTick(); @@ -1556,26 +1590,35 @@ describe("can catch errors", () => { await nextMicroTick(); await nextMicroTick(); await nextMicroTick(); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + ] + `); parent.state.hasChild = false; await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Child:willDestroy", - "Parent:willRender", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Child:willDestroy", + "Parent:willRender", + "Parent:rendered", + ] + `); expect(fixture.innerHTML).toBe("1"); await nextTick(); - expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("2"); }); }); diff --git a/tests/components/hooks.test.ts b/tests/components/hooks.test.ts index 7b72e265d..74ea564ce 100644 --- a/tests/components/hooks.test.ts +++ b/tests/components/hooks.test.ts @@ -660,8 +660,9 @@ describe("hooks", () => { let error: OwlError; const app = new App(MyComponent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!.cause.message).toBe("Intentional error"); // no console.error because the error has been caught in this test diff --git a/tests/components/lifecycle.test.ts b/tests/components/lifecycle.test.ts index aa3f96a39..8640e1068 100644 --- a/tests/components/lifecycle.test.ts +++ b/tests/components/lifecycle.test.ts @@ -17,6 +17,7 @@ import { nextMicroTick, nextTick, snapshotEverything, + steps, useLogLifecycle, } from "../helpers"; @@ -341,15 +342,16 @@ describe("lifecycle hooks", () => { parent.state.n = 2; await nextTick(); app.destroy(); - expect(steps).toEqual([ - "parent:willPatch", - "child:willPatch", - "childchild:willPatch", - "childchild:patched", - "child:patched", - "parent:patched", - ]); - Object.freeze(steps); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "parent:willPatch", + "childchild:willPatch", + "child:willPatch", + "child:patched", + "childchild:patched", + "parent:patched", + ] + `); }); test("willStart, mounted on subwidget rendered after main is mounted in some other position", async () => { @@ -455,45 +457,51 @@ describe("lifecycle hooks", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
0
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.increment(); await nextTick(); expect(fixture.innerHTML).toBe("
1
"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); parent.toggleSubWidget(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + ] + `); }); test("hooks are called in proper order in widget creation/destruction", async () => { @@ -514,26 +522,30 @@ describe("lifecycle hooks", () => { const app = new App(Parent); await app.mount(fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); app.destroy(); - expect([ - "Parent:willUnmount", - "Child:willUnmount", - "Child:willDestroy", - "Parent:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willUnmount", + "Child:willUnmount", + "Child:willDestroy", + "Parent:willDestroy", + ] + `); }); test("willUpdateProps hook is called", async () => { @@ -632,26 +644,30 @@ describe("lifecycle hooks", () => { const app = new App(Parent); await app.mount(fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); app.destroy(); - expect([ - "Parent:willUnmount", - "Child:willUnmount", - "Child:willDestroy", - "Parent:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willUnmount", + "Child:willUnmount", + "Child:willDestroy", + "Parent:willDestroy", + ] + `); }); test("lifecycle semantics, part 2", async () => { @@ -680,42 +696,48 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.state.hasChild = true; await nextTick(); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "GrandChild:setup", - "GrandChild:willStart", - "Child:rendered", - "GrandChild:willRender", - "GrandChild:rendered", - "Parent:willPatch", - "GrandChild:mounted", - "Child:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "GrandChild:setup", + "GrandChild:willStart", + "GrandChild:willRender", + "GrandChild:rendered", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "GrandChild:mounted", + "Child:mounted", + "Parent:patched", + ] + `); app.destroy(); - expect([ - "Parent:willUnmount", - "Child:willUnmount", - "GrandChild:willUnmount", - "GrandChild:willDestroy", - "Child:willDestroy", - "Parent:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willUnmount", + "Child:willUnmount", + "GrandChild:willUnmount", + "GrandChild:willDestroy", + "Child:willDestroy", + "Parent:willDestroy", + ] + `); }); test("lifecycle semantics, part 3", async () => { @@ -744,19 +766,26 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.state.hasChild = true; // immediately destroy everything app.destroy(); await nextTick(); - expect(["Parent:willUnmount", "Parent:willDestroy"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willUnmount", + "Parent:willDestroy", + ] + `); }); test("lifecycle semantics, part 4", async () => { @@ -789,34 +818,40 @@ describe("lifecycle hooks", () => { const app = new App(Parent); const parent = await app.mount(fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.state.hasChild = true; await nextTick(); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "GrandChild:setup", - "GrandChild:willStart", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "GrandChild:setup", + "GrandChild:willStart", + "Child:rendered", + "Parent:rendered", + ] + `); app.destroy(); - expect([ - "Parent:willUnmount", - "GrandChild:willDestroy", - "Child:willDestroy", - "Parent:willDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willUnmount", + "GrandChild:willDestroy", + "Child:willDestroy", + "Parent:willDestroy", + ] + `); }); test("lifecycle semantics, part 5", async () => { @@ -837,29 +872,33 @@ describe("lifecycle hooks", () => { } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.hasChild = false; await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + ] + `); }); test("lifecycle semantics, part 6", async () => { @@ -880,32 +919,36 @@ describe("lifecycle hooks", () => { } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = 2; await nextTick(); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("onWillRender", async () => { @@ -937,43 +980,53 @@ describe("lifecycle hooks", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value++; // to block child render 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(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); fixture.querySelector("button")!.click(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); expect(fixture.innerHTML).toBe(""); def.resolve(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); // TODO: rename (remove? seems covered by lifecycle semantics) @@ -1054,50 +1107,54 @@ describe("lifecycle hooks", () => { await mount(A, fixture); expect(fixture.innerHTML).toBe(`
A
B
C
D
E
`); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "C:setup", - "C:willStart", - "A:rendered", - "B:willRender", - "B:rendered", - "C:willRender", - "D:setup", - "D:willStart", - "E:setup", - "E:willStart", - "C:rendered", - "D:willRender", - "D:rendered", - "E:willRender", - "E:rendered", - "E:mounted", - "D:mounted", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "B:rendered", + "C:setup", + "C:willStart", + "C:willRender", + "D:setup", + "D:willStart", + "D:willRender", + "D:rendered", + "E:setup", + "E:willStart", + "E:willRender", + "E:rendered", + "C:rendered", + "A:rendered", + "E:mounted", + "D:mounted", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // update c!.state.flag = false; await nextTick(); - expect([ - "C:willRender", - "F:setup", - "F:willStart", - "C:rendered", - "F:willRender", - "F:rendered", - "C:willPatch", - "E:willUnmount", - "E:willDestroy", - "F:mounted", - "C:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "C:willRender", + "F:setup", + "F:willStart", + "F:willRender", + "F:rendered", + "C:rendered", + "C:willPatch", + "E:willUnmount", + "E:willDestroy", + "F:mounted", + "C:patched", + ] + `); }); test("mounted hook is called on every mount, not just the first one", async () => { @@ -1118,43 +1175,49 @@ describe("lifecycle hooks", () => { } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.hasChild = false; await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + ] + `); parent.state.hasChild = true; await nextTick(); - expect([ - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:mounted", + "Parent:patched", + ] + `); }); test("render in mounted", async () => { @@ -1172,19 +1235,26 @@ describe("lifecycle hooks", () => { await mount(Parent, fixture); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - "Parent:willRender", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + "Parent:willRender", + "Parent:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("Patched"); - expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Parent:patched", + ] + `); }); test("render in patched", async () => { @@ -1205,29 +1275,38 @@ describe("lifecycle hooks", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.render(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - "Parent:willRender", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + "Parent:willRender", + "Parent:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("Patched"); - expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Parent:patched", + ] + `); }); test("render in willPatch", async () => { @@ -1248,29 +1327,38 @@ describe("lifecycle hooks", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Parent:rendered", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); parent.render(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - "Parent:willRender", - "Parent:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + "Parent:willRender", + "Parent:rendered", + ] + `); await nextTick(); - expect(["Parent:willPatch", "Parent:patched"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willPatch", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("Patched"); }); @@ -1313,19 +1401,21 @@ describe("lifecycle hooks", () => { await nextTick(); app.destroy(); - expect([ - "onWillStart", - "onWillRender", - "onRendered", - "onMounted", - "onWillUpdateProps", - "onWillRender", - "onRendered", - "onWillPatch", - "onPatched", - "onWillUnmount", - "onWillDestroy", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "onWillStart", + "onWillRender", + "onRendered", + "onMounted", + "onWillUpdateProps", + "onWillRender", + "onRendered", + "onWillPatch", + "onPatched", + "onWillUnmount", + "onWillDestroy", + ] + `); }); test("destroy new children before being mountged", async () => { @@ -1357,26 +1447,32 @@ describe("lifecycle hooks", () => { 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(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Parent:rendered", + "Parent:mounted", + ] + `); 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(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willUnmount", + "Child:willDestroy", + "Parent:willDestroy", + ] + `); }); }); diff --git a/tests/components/props.test.ts b/tests/components/props.test.ts index 3cbea392a..8d80f22c6 100644 --- a/tests/components/props.test.ts +++ b/tests/components/props.test.ts @@ -1,5 +1,5 @@ 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; @@ -272,26 +272,30 @@ test("bound functions are considered 'alike'", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1child"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.val = 3; await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + ] + `); expect(fixture.innerHTML).toBe("3child"); }); @@ -330,29 +334,33 @@ test(".alike suffix in a simple case", async () => { } const parent = await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("01"); parent.state.counter++; await nextTick(); expect(fixture.innerHTML).toBe("11"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + ] + `); }); test(".alike suffix in a list", async () => { @@ -388,36 +396,40 @@ test(".alike suffix in a list", async () => { } await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Todo:setup", - "Todo:willStart", - "Todo:setup", - "Todo:willStart", - "Parent:rendered", - "Todo:willRender", - "Todo:rendered", - "Todo:willRender", - "Todo:rendered", - "Todo:mounted", - "Todo:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Todo:setup", + "Todo:willStart", + "Todo:willRender", + "Todo:rendered", + "Todo:setup", + "Todo:willStart", + "Todo:willRender", + "Todo:rendered", + "Parent:rendered", + "Todo:mounted", + "Todo:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe(""); fixture.querySelector("button")?.click(); await nextTick(); expect(fixture.innerHTML).toBe(""); - expect([ - "Parent:willRender", - "Parent:rendered", - "Todo:willRender", - "Todo:rendered", - "Todo:willPatch", - "Todo:patched", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Todo:willRender", + "Todo:rendered", + "Todo:willPatch", + "Todo:patched", + "Parent:willPatch", + "Parent:patched", + ] + `); }); diff --git a/tests/components/props_validation.test.ts b/tests/components/props_validation.test.ts index 265a36ba0..6efb93559 100644 --- a/tests/components/props_validation.test.ts +++ b/tests/components/props_validation.test.ts @@ -51,8 +51,9 @@ describe("props validation", () => { const app = new App(Parent, { test: true }); let error: OwlError | undefined; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( "Invalid props for component 'SubComp': 'message' is missing" ); await mountProm; @@ -80,8 +81,9 @@ describe("props validation", () => { const app = new App(Parent, { test: true }); let error: OwlError | undefined; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( "Invalid props for component 'SubComp': 'message' is missing" ); await mountProm; @@ -131,8 +133,9 @@ describe("props validation", () => { props = {}; let app = new App(Parent, { test: true }); let error: OwlError | undefined; + let appError = nextAppError(app); let mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'"); + await expect(appError).resolves.toThrow("Invalid props for component '_a'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -148,8 +151,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: test.ko }; app = new App(Parent, { test: true }); + appError = nextAppError(app); mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'"); + await expect(appError).resolves.toThrow("Invalid props for component '_a'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -183,8 +187,9 @@ describe("props validation", () => { props = {}; let app = new App(Parent, { test: true }); let error: OwlError | undefined; + let appError = nextAppError(app); let mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'"); + await expect(appError).resolves.toThrow("Invalid props for component '_a'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -200,8 +205,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: test.ko }; app = new App(Parent, { test: true }); + appError = nextAppError(app); mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component '_a'"); + await expect(appError).resolves.toThrow("Invalid props for component '_a'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -240,8 +246,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: 1 }; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -279,8 +286,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: 1 }; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe("Invalid props for component 'SubComp': 'p' is not a string"); @@ -316,14 +324,16 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: [1] }; let app = new App(Parent, { test: true }); + let appError = nextAppError(app); let mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); error = undefined; app = new App(Parent, { test: true }); + appError = nextAppError(app); mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); }); @@ -365,8 +375,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: [true, 1] }; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -399,8 +410,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: { id: 1, url: "url", extra: true } }; let app = new App(Parent, { test: true }); + let appError = nextAppError(app); let mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -408,8 +420,9 @@ describe("props validation", () => { ); props = { p: { id: "1", url: "url" } }; app = new App(Parent, { test: true }); + appError = nextAppError(app); mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -418,8 +431,9 @@ describe("props validation", () => { error = undefined; props = { p: { id: 1 } }; app = new App(Parent, { test: true }); + appError = nextAppError(app); mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -465,8 +479,9 @@ describe("props validation", () => { expect(error!).toBeUndefined(); props = { p: { id: 1, url: [12, true] } }; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -675,8 +690,9 @@ describe("props validation", () => { } let error: Error; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'SubComp'"); + await expect(appError).resolves.toThrow("Invalid props for component 'SubComp'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe("Invalid props for component 'SubComp': 'p' is missing"); @@ -765,8 +781,9 @@ describe("props validation", () => { } let error: Error; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("Invalid props for component 'Child'"); + await expect(appError).resolves.toThrow("Invalid props for component 'Child'"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( @@ -821,8 +838,9 @@ describe("props validation", () => { const app = new App(Parent, { test: true }); let error: OwlError | undefined; + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( "Invalid props for component 'Child': 'message' is missing" ); await mountProm; @@ -895,10 +913,9 @@ describe("default props", () => { } let error: Error; const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow( - "default value cannot be defined for a mandatory prop" - ); + await expect(appError).resolves.toThrow("default value cannot be defined for a mandatory prop"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe( diff --git a/tests/components/reactivity.test.ts b/tests/components/reactivity.test.ts index da1a960c5..e7b86963f 100644 --- a/tests/components/reactivity.test.ts +++ b/tests/components/reactivity.test.ts @@ -9,7 +9,7 @@ import { xml, toRaw, } from "../../src"; -import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers"; +import { makeTestFixture, nextTick, snapshotEverything, steps, useLogLifecycle } from "../helpers"; let fixture: HTMLElement; @@ -151,9 +151,10 @@ describe("reactivity in lifecycle", () => { } } const prom = mount(Comp, fixture); + expect(steps).toEqual([1]); (STATE as any).val = 2; await prom; - expect(steps).toEqual([2]); + expect(steps).toEqual([1, 2]); expect(fixture.innerHTML).toBe("
2
"); }); @@ -175,30 +176,34 @@ describe("reactivity in lifecycle", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("2"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.content = null; parent.state.renderChild = false; await nextTick(); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + ] + `); }); test("Component is automatically subscribed to reactive object received as prop", async () => { diff --git a/tests/components/refs.test.ts b/tests/components/refs.test.ts index b6cf1fb7c..aa5e07954 100644 --- a/tests/components/refs.test.ts +++ b/tests/components/refs.test.ts @@ -125,10 +125,11 @@ describe("refs", () => { } const app = new App(Test, { test: true }); + const appError = nextAppError(app); const mountProm = expect(app.mount(fixture)).rejects.toThrowError( 'Cannot set the same ref more than once in the same component, ref "coucou" was set multiple times in Test' ); - await expect(nextAppError(app)).resolves.toThrow( + await expect(appError).resolves.toThrow( 'Cannot set the same ref more than once in the same component, ref "coucou" was set multiple times in Test' ); await mountProm; diff --git a/tests/components/rendering.test.ts b/tests/components/rendering.test.ts index c97534735..d6272d4f5 100644 --- a/tests/components/rendering.test.ts +++ b/tests/components/rendering.test.ts @@ -6,6 +6,7 @@ import { useLogLifecycle, makeDeferred, nextMicroTick, + steps, } from "../helpers"; let fixture: HTMLElement; @@ -41,28 +42,32 @@ describe("rendering semantics", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("Achild"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = "B"; await nextTick(); expect(fixture.innerHTML).toBe("Bchild"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + ] + `); }); test("can force a render to update sub tree", async () => { @@ -167,18 +172,20 @@ describe("rendering semantics", () => { const parent = await mount(Parent, fixture, { env }); expect(fixture.innerHTML).toBe("parentAchild3"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); value = 4; parent.render(true); @@ -187,30 +194,34 @@ describe("rendering semantics", () => { await nextMicroTick(); await nextMicroTick(); await nextMicroTick(); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + ] + `); parent.state.value = "B"; await nextTick(); expect(fixture.innerHTML).toBe("parentBchild4"); - expect([ - "Parent:willRender", - "Child:willUpdateProps", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Child:willPatch", - "Child:patched", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Child:willUpdateProps", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Parent:willPatch", + "Child:willPatch", + "Child:patched", + "Parent:patched", + ] + `); }); test("props are reactive", async () => { @@ -235,23 +246,32 @@ describe("rendering semantics", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.b = 3; await nextTick(); 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 () => { @@ -278,37 +298,48 @@ describe("rendering semantics", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("1"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.b.c = 3; // parent is now subscribed to 'b' key await nextTick(); 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 await nextTick(); expect(fixture.innerHTML).toBe("444"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willPatch", - "Parent:patched", - "Child:willPatch", - "Child:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Child:willRender", + "Child:rendered", + "Parent:willPatch", + "Parent:patched", + "Child:willPatch", + "Child:patched", + ] + `); }); test("works as expected for dynamic number of props", async () => { @@ -366,41 +397,45 @@ describe("rendering semantics", () => { const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("11"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); parent.state.obj.val = 3; await nextTick(); expect(fixture.innerHTML).toBe("33"); - expect([ - "A:willRender", - "A:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "A:patched", - "C:willPatch", - "C:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "A:rendered", + "C:willRender", + "C:rendered", + "A:willPatch", + "A:patched", + "C:willPatch", + "C:patched", + ] + `); def.resolve(); await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); }); @@ -431,51 +466,67 @@ test("force render in case of existing render", async () => { } const parent = await mount(A, fixture); expect(fixture.innerHTML).toBe("C1"); - expect([ - "A:setup", - "A:willStart", - "A:willRender", - "B:setup", - "B:willStart", - "A:rendered", - "B:willRender", - "C:setup", - "C:willStart", - "B:rendered", - "C:willRender", - "C:rendered", - "C:mounted", - "B:mounted", - "A:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:setup", + "A:willStart", + "A:willRender", + "B:setup", + "B:willStart", + "B:willRender", + "C:setup", + "C:willStart", + "C:willRender", + "C:rendered", + "B:rendered", + "A:rendered", + "C:mounted", + "B:mounted", + "A:mounted", + ] + `); // trigger a new rendering, blocked in B parent.state.val = 2; 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 // and also be blocked in B parent.render(true); await nextTick(); - expect(["A:willRender", "B:willUpdateProps", "A:rendered"]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "A:willRender", + "B:willUpdateProps", + "A:rendered", + ] + `); def.resolve(); await nextTick(); // we check here that the render reaches C (so, that it was properly forced) - expect([ - "B:willRender", - "C:willUpdateProps", - "B:rendered", - "C:willRender", - "C:rendered", - "A:willPatch", - "B:willPatch", - "C:willPatch", - "C:patched", - "B:patched", - "A:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "B:willRender", + "C:willUpdateProps", + "C:willRender", + "C:rendered", + "B:rendered", + "A:willPatch", + "C:willPatch", + "B:willPatch", + "B:patched", + "C:patched", + "A:patched", + ] + `); }); test("children, default props and renderings", async () => { @@ -503,26 +554,30 @@ test("children, default props and renderings", async () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("Achild"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); parent.state.value = "B"; await nextTick(); expect(fixture.innerHTML).toBe("Bchild"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Parent:patched", + ] + `); }); diff --git a/tests/components/slots.test.ts b/tests/components/slots.test.ts index f36ef6d07..c3a478d33 100644 --- a/tests/components/slots.test.ts +++ b/tests/components/slots.test.ts @@ -223,8 +223,9 @@ describe("slots", () => { let error: Error; const app = new App(Parent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).not.toBeNull(); expect(mockConsoleWarn).toBeCalledTimes(1); diff --git a/tests/components/style_class.test.ts b/tests/components/style_class.test.ts index e57dcd5ec..988c12af7 100644 --- a/tests/components/style_class.test.ts +++ b/tests/components/style_class.test.ts @@ -349,8 +349,9 @@ describe("style and class handling", () => { } let error: OwlError; const app = new App(Parent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); diff --git a/tests/components/t_component.test.ts b/tests/components/t_component.test.ts index 8ea37727f..a32aaff23 100644 --- a/tests/components/t_component.test.ts +++ b/tests/components/t_component.test.ts @@ -1,5 +1,5 @@ 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; @@ -29,18 +29,20 @@ describe("t-component", () => { await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
child
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); }); test("switching dynamic component", async () => { @@ -68,36 +70,40 @@ describe("t-component", () => { const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
child a
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "ChildA:setup", - "ChildA:willStart", - "Parent:rendered", - "ChildA:willRender", - "ChildA:rendered", - "ChildA:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "ChildA:setup", + "ChildA:willStart", + "ChildA:willRender", + "ChildA:rendered", + "Parent:rendered", + "ChildA:mounted", + "Parent:mounted", + ] + `); parent.Child = ChildB; parent.render(); await nextTick(); expect(fixture.innerHTML).toBe("child b"); - expect([ - "Parent:willRender", - "ChildB:setup", - "ChildB:willStart", - "Parent:rendered", - "ChildB:willRender", - "ChildB:rendered", - "Parent:willPatch", - "ChildA:willUnmount", - "ChildA:willDestroy", - "ChildB:mounted", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "ChildB:setup", + "ChildB:willStart", + "ChildB:willRender", + "ChildB:rendered", + "Parent:rendered", + "Parent:willPatch", + "ChildA:willUnmount", + "ChildA:willDestroy", + "ChildB:mounted", + "Parent:patched", + ] + `); }); test("can switch between dynamic components without the need for a t-key", async () => { diff --git a/tests/components/t_foreach.test.ts b/tests/components/t_foreach.test.ts index 4c783b66a..b570e92bf 100644 --- a/tests/components/t_foreach.test.ts +++ b/tests/components/t_foreach.test.ts @@ -4,6 +4,7 @@ import { nextAppError, nextTick, snapshotEverything, + steps, useLogLifecycle, } from "../helpers"; @@ -91,23 +92,25 @@ describe("list of components", () => { expect(fixture.innerHTML).toBe( "
" ); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Child:mounted", + "Parent:mounted", + ] + `); }); test("reconciliation alg works for t-foreach in t-foreach", async () => { @@ -323,10 +326,11 @@ describe("list of components", () => { } const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = expect(app.mount(fixture)).rejects.toThrow( "Got duplicate key in t-foreach: child" ); - await expect(nextAppError(app)).resolves.toThrow("Got duplicate key in t-foreach: child"); + await expect(appError).resolves.toThrow("Got duplicate key in t-foreach: child"); await mountProm; console.info = consoleInfo; expect(mockConsoleWarn).toBeCalledTimes(1); @@ -349,12 +353,11 @@ describe("list of components", () => { } const app = new App(Parent, { test: true }); + const appError = nextAppError(app); const mountProm = expect(app.mount(fixture)).rejects.toThrow( "Got duplicate key in t-foreach: [object Object]" ); - await expect(nextAppError(app)).resolves.toThrow( - "Got duplicate key in t-foreach: [object Object]" - ); + await expect(appError).resolves.toThrow("Got duplicate key in t-foreach: [object Object]"); await mountProm; console.info = consoleInfo; expect(mockConsoleWarn).toBeCalledTimes(1); diff --git a/tests/helpers.ts b/tests/helpers.ts index c28b2c17f..f5515d900 100644 --- a/tests/helpers.ts +++ b/tests/helpers.ts @@ -137,7 +137,7 @@ export function snapshotEverything() { }; } -const steps: string[] = []; +export const steps: string[] = []; export function logStep(step: string) { steps.push(step); @@ -235,7 +235,7 @@ expect.extend({ }; const currentSteps = steps.splice(0); - const pass = this.equals(currentSteps, expected); + let pass = this.equals(currentSteps, expected); const message = pass ? () => diff --git a/tests/misc/portal.test.ts b/tests/misc/portal.test.ts index e07d524fa..3e6e74ced 100644 --- a/tests/misc/portal.test.ts +++ b/tests/misc/portal.test.ts @@ -270,8 +270,9 @@ describe("Portal", () => { let error: Error; const app = new App(Parent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("invalid portal target"); + await expect(appError).resolves.toThrow("invalid portal target"); await mountProm; expect(error!).toBeDefined(); @@ -1002,8 +1003,9 @@ describe("Portal: Props validation", () => { } let error: OwlError; const app = new App(Parent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("error occured in the owl lifecycle"); + await expect(appError).resolves.toThrow("error occured in the owl lifecycle"); await mountProm; expect(error!).toBeDefined(); expect(error!.cause).toBeDefined(); @@ -1021,8 +1023,9 @@ describe("Portal: Props validation", () => { } let error: Error; const app = new App(Parent); + const appError = nextAppError(app); const mountProm = app.mount(fixture).catch((e: Error) => (error = e)); - await expect(nextAppError(app)).resolves.toThrow("invalid portal target"); + await expect(appError).resolves.toThrow("invalid portal target"); await mountProm; expect(error!).toBeDefined(); expect(error!.message).toBe(`invalid portal target`); diff --git a/tests/reactivity.test.ts b/tests/reactivity.test.ts index ed6ef7754..081bcc1e3 100644 --- a/tests/reactivity.test.ts +++ b/tests/reactivity.test.ts @@ -17,6 +17,7 @@ import { nextMicroTick, nextTick, snapshotEverything, + steps, useLogLifecycle, } from "./helpers"; @@ -1850,37 +1851,41 @@ describe("Reactivity: useState", () => { } } await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Child:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("
123123
"); testContext.value = 321; await nextTick(); - expect([ - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - "Child:willPatch", - "Child:patched", - "Child:willPatch", - "Child:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", + "Child:willPatch", + "Child:patched", + "Child:willPatch", + "Child:patched", + ] + `); expect(fixture.innerHTML).toBe("
321321
"); }); @@ -1904,38 +1909,49 @@ describe("Reactivity: useState", () => { } await mount(Parent, fixture); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Child:mounted", + "Parent:mounted", + ] + `); expect(fixture.innerHTML).toBe("
123123
"); testContext.value = 321; await nextMicroTick(); await nextMicroTick(); - expect([ - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", + ] + `); expect(fixture.innerHTML).toBe("
123123
"); 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("
321321
"); }); @@ -1969,43 +1985,54 @@ describe("Reactivity: useState", () => { await mount(GrandFather, fixture); expect(fixture.innerHTML).toBe("
123
123
"); - expect([ - "GrandFather:setup", - "GrandFather:willStart", - "GrandFather:willRender", - "Child:setup", - "Child:willStart", - "Parent:setup", - "Parent:willStart", - "GrandFather:rendered", - "Child:willRender", - "Child:rendered", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - "Child:mounted", - "GrandFather:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "GrandFather:setup", + "GrandFather:willStart", + "GrandFather:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "GrandFather:rendered", + "Child:mounted", + "Parent:mounted", + "Child:mounted", + "GrandFather:mounted", + ] + `); testContext.value = 321; await nextMicroTick(); await nextMicroTick(); expect(fixture.innerHTML).toBe("
123
123
"); - expect([ - "Child:willRender", - "Child:rendered", - "Child:willRender", - "Child:rendered", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Child:willRender", + "Child:rendered", + "Child:willRender", + "Child:rendered", + ] + `); await nextTick(); expect(fixture.innerHTML).toBe("
321
321
"); - 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 () => { @@ -2181,38 +2208,49 @@ describe("Reactivity: useState", () => { } const parent = await mount(Parent, fixture); expect(fixture.innerHTML).toBe("
123
"); - expect([ - "Parent:setup", - "Parent:willStart", - "Parent:willRender", - "Child:setup", - "Child:willStart", - "Parent:rendered", - "Child:willRender", - "Child:rendered", - "Child:mounted", - "Parent:mounted", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:setup", + "Parent:willStart", + "Parent:willRender", + "Child:setup", + "Child:willStart", + "Child:willRender", + "Child:rendered", + "Parent:rendered", + "Child:mounted", + "Parent:mounted", + ] + `); testContext.a = 321; 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; await nextTick(); expect(fixture.innerHTML).toBe("
"); - expect([ - "Parent:willRender", - "Parent:rendered", - "Parent:willPatch", - "Child:willUnmount", - "Child:willDestroy", - "Parent:patched", - ]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(` + Array [ + "Parent:willRender", + "Parent:rendered", + "Parent:willPatch", + "Child:willUnmount", + "Child:willDestroy", + "Parent:patched", + ] + `); testContext.a = 456; await nextTick(); - expect([]).toBeLogged(); + expect(steps.splice(0)).toMatchInlineSnapshot(`Array []`); }); test("destroyed component before being mounted is inactive", async () => {