[TESTS] test lifecycle in reactivity tests

This commit is contained in:
Géry Debongnie
2021-11-27 08:14:25 +01:00
committed by Aaron Bohy
parent bcc4fe2a27
commit 8c600fa539
+123 -35
View File
@@ -6,7 +6,8 @@ import {
makeTestFixture, makeTestFixture,
nextMicroTick, nextMicroTick,
nextTick, nextTick,
snapshotEverything snapshotEverything,
useLogLifecycle,
} from "./helpers"; } from "./helpers";
function createReactive(value: any, observer: any = () => {}) { function createReactive(value: any, observer: any = () => {}) {
@@ -1119,104 +1120,178 @@ describe("Reactivity: useState", () => {
test("two components can subscribe to same context", async () => { test("two components can subscribe to same context", async () => {
const testContext = createReactive({ value: 123 }); const testContext = createReactive({ value: 123 });
const steps: string[] = [];
class Child extends Component { class Child extends Component {
static template = xml`<span><t t-esc="contextObj.value"/></span>`; static template = xml`<span><t t-esc="contextObj.value"/></span>`;
contextObj = useState(testContext); contextObj = useState(testContext);
setup() { setup() {
onWillRender(() => { useLogLifecycle();
steps.push("child");
});
} }
} }
class Parent extends Component { class Parent extends Component {
static template = xml`<div><Child /><Child /></div>`; static template = xml`<div><Child /><Child /></div>`;
static components = { Child }; static components = { Child };
setup() { setup() {
onWillRender(() => { useLogLifecycle();
steps.push("parent");
});
} }
} }
await mount(Parent, fixture); await mount(Parent, fixture);
expect(steps).toEqual(["parent", "child", "child"]); 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(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
testContext.value = 321; testContext.value = 321;
await nextTick(); await nextTick();
expect(steps).toEqual(["parent", "child", "child", "child", "child"]); expect([
"Child:willRender",
"Child:rendered",
"Child:willRender",
"Child:rendered",
"Child:willPatch",
"Child:patched",
"Child:willPatch",
"Child:patched",
]).toBeLogged();
expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>");
}); });
test("two components are updated in parallel", async () => { test("two components are updated in parallel", async () => {
const testContext = createReactive({ value: 123 }); const testContext = createReactive({ value: 123 });
const steps: string[] = [];
class Child extends Component { class Child extends Component {
static template = xml`<span><t t-esc="contextObj.value"/></span>`; static template = xml`<span><t t-esc="contextObj.value"/></span>`;
contextObj = useState(testContext); contextObj = useState(testContext);
setup() { setup() {
onWillRender(async () => { useLogLifecycle();
steps.push("render");
});
} }
} }
class Parent extends Component { class Parent extends Component {
static template = xml`<div><Child /><Child /></div>`; static template = xml`<div><Child /><Child /></div>`;
static components = { Child }; static components = { Child };
setup() {
useLogLifecycle();
}
} }
await mount(Parent, fixture); await mount(Parent, fixture);
expect(steps).toEqual(["render", "render"]); 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(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
testContext.value = 321; testContext.value = 321;
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect(steps).toEqual(["render", "render", "render", "render"]); expect([
"Child:willRender",
"Child:rendered",
"Child:willRender",
"Child:rendered",
]).toBeLogged();
expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><span>123</span></div>");
await nextTick(); await nextTick();
expect(["Child:willPatch", "Child:patched", "Child:willPatch", "Child:patched"]).toBeLogged();
expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><span>321</span></div>");
}); });
test("two independent components on different levels are updated in parallel", async () => { test("two independent components on different levels are updated in parallel", async () => {
const testContext = createReactive({ value: 123 }); const testContext = createReactive({ value: 123 });
const steps: string[] = [];
class Child extends Component { class Child extends Component {
static template = xml`<span><t t-esc="contextObj.value"/></span>`; static template = xml`<span><t t-esc="contextObj.value"/></span>`;
static components = {}; static components = {};
contextObj = useState(testContext); contextObj = useState(testContext);
setup() { setup() {
onWillRender(() => { useLogLifecycle();
steps.push("render");
});
} }
} }
class Parent extends Component { class Parent extends Component {
static template = xml`<div><Child /></div>`; static template = xml`<div><Child /></div>`;
static components = { Child }; static components = { Child };
setup() {
useLogLifecycle();
}
} }
class GrandFather extends Component { class GrandFather extends Component {
static template = xml`<div><Child /><Parent /></div>`; static template = xml`<div><Child /><Parent /></div>`;
static components = { Child, Parent }; static components = { Child, Parent };
setup() {
useLogLifecycle();
}
} }
await mount(GrandFather, fixture); await mount(GrandFather, fixture);
expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>");
expect(steps).toEqual(["render", "render"]); 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();
testContext.value = 321; testContext.value = 321;
await nextMicroTick(); await nextMicroTick();
await nextMicroTick(); await nextMicroTick();
expect(steps).toEqual(["render", "render", "render", "render"]);
expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span><div><span>123</span></div></div>");
expect([
"Child:willRender",
"Child:rendered",
"Child:willRender",
"Child:rendered",
]).toBeLogged();
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div><span>321</span><div><span>321</span></div></div>"); expect(fixture.innerHTML).toBe("<div><span>321</span><div><span>321</span></div></div>");
expect(["Child:willPatch", "Child:patched", "Child:willPatch", "Child:patched"]).toBeLogged();
}); });
test("one components can subscribe twice to same context", async () => { test("one components can subscribe twice to same context", async () => {
@@ -1374,15 +1449,12 @@ describe("Reactivity: useState", () => {
test("destroyed component is inactive", async () => { test("destroyed component is inactive", async () => {
const testContext = createReactive({ a: 123 }); const testContext = createReactive({ a: 123 });
const steps: string[] = [];
class Child extends Component { class Child extends Component {
static template = xml`<span><t t-esc="contextObj.a"/></span>`; static template = xml`<span><t t-esc="contextObj.a"/></span>`;
contextObj = useState(testContext); contextObj = useState(testContext);
setup() { setup() {
onWillRender(() => { useLogLifecycle();
steps.push("child");
});
} }
} }
class Parent extends Component { class Parent extends Component {
@@ -1390,27 +1462,43 @@ describe("Reactivity: useState", () => {
static components = { Child }; static components = { Child };
state = useState({ flag: true }); state = useState({ flag: true });
setup() { setup() {
onWillRender(() => { useLogLifecycle();
steps.push("parent");
});
} }
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.innerHTML).toBe("<div><span>123</span></div>"); expect(fixture.innerHTML).toBe("<div><span>123</span></div>");
expect(steps).toEqual(["parent", "child"]); expect([
"Parent:setup",
"Parent:willStart",
"Parent:willRender",
"Child:setup",
"Child:willStart",
"Parent:rendered",
"Child:willRender",
"Child:rendered",
"Child:mounted",
"Parent:mounted",
]).toBeLogged();
testContext.a = 321; testContext.a = 321;
await nextTick(); await nextTick();
expect(steps).toEqual(["parent", "child", "child"]); expect(["Child:willRender", "Child:rendered", "Child:willPatch", "Child:patched"]).toBeLogged();
parent.state.flag = false; parent.state.flag = false;
await nextTick(); await nextTick();
expect(fixture.innerHTML).toBe("<div></div>"); expect(fixture.innerHTML).toBe("<div></div>");
expect(steps).toEqual(["parent", "child", "child", "parent"]); expect([
"Parent:willRender",
"Parent:rendered",
"Parent:willPatch",
"Child:willUnmount",
"Child:destroyed",
"Parent:patched",
]).toBeLogged();
testContext.a = 456; testContext.a = 456;
await nextTick(); await nextTick();
expect(steps).toEqual(["parent", "child", "child", "parent"]); expect([]).toBeLogged();
}); });
test("destroyed component before being mounted is inactive", async () => { test("destroyed component before being mounted is inactive", async () => {