[IMP] component: render does not return a promise anymore

This commit is contained in:
Géry Debongnie
2021-11-29 16:02:51 +01:00
parent 777b2aae5e
commit e946967867
14 changed files with 103 additions and 208 deletions
@@ -800,71 +800,6 @@ exports[`concurrent renderings scenario 15 3`] = `
}"
`;
exports[`concurrent renderings scenario 16 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber } = helpers;
let block1 = createBlock(\`<ul>DDD</ul>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`concurrent renderings scenario 16 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber } = helpers;
let block1 = createBlock(\`<p><span><block-text-0/></span><span><block-text-1/></span><span><block-text-2/></span><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
let b2;
let d1 = ctx['props'].fromA;
let d2 = ctx['props'].fromB;
let d3 = ctx['state'].fromC;
if (ctx['state'].fromC===13) {
b2 = component(\`D\`, {}, key + \`__1\`, node, ctx);
}
return block1([d1, d2, d3], [b2]);
}
}"
`;
exports[`concurrent renderings scenario 16 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber } = helpers;
let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
let b2 = component(\`C\`, {fromB: ctx['state'].fromB,fromA: ctx['props'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]);
}
}"
`;
exports[`concurrent renderings scenario 16 4`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber } = helpers;
let block1 = createBlock(\`<p><block-child-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
let b2 = component(\`B\`, {fromA: ctx['state'].fromA}, key + \`__1\`, node, ctx);
return block1([], [b2]);
}
}"
`;
exports[`creating two async components, scenario 1 1`] = `
"function anonymous(bdom, helpers
) {
@@ -1115,21 +1050,6 @@ exports[`properly behave when destroyed/unmounted while rendering 3`] = `
}"
`;
exports[`render method wait until rendering is done 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, isBoundary, shallowEqual, setContextValue, toNumber, safeOutput } = helpers;
let block1 = createBlock(\`<div><block-text-0/></div>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['state'].drinks;
return block1([d1]);
}
}"
`;
exports[`rendering component again in next microtick 1`] = `
"function anonymous(bdom, helpers
) {
+6 -3
View File
@@ -106,7 +106,8 @@ describe("basics", () => {
expect(fixture.innerHTML).toBe("<span>1</span>");
component.value = 2;
await component.render();
component.render();
await nextTick();
expect(fixture.innerHTML).toBe("<span>2</span>");
});
@@ -123,7 +124,8 @@ describe("basics", () => {
expect(fixture.innerHTML).toBe("onetwothree");
component.items = ["two", "three", "one"];
await component.render();
component.render();
await nextTick();
expect(fixture.innerHTML).toBe("twothreeone");
});
@@ -258,7 +260,8 @@ describe("basics", () => {
const test = await mount(Test, fixture);
expect(fixture.innerHTML).toBe("<div>3</div>");
test.value = 5;
await test.render();
test.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div>5</div>");
});
+7 -19
View File
@@ -1758,7 +1758,9 @@ test("concurrent renderings scenario 11", async () => {
def.resolve();
}, 20);
child.val = 5;
await child.render();
child.render();
await def;
await nextTick();
expect(fixture.innerHTML).toBe("<div><span>2|5</span></div>");
expect([
"Parent:willRender",
@@ -2315,7 +2317,8 @@ test("calling render in destroy", async () => {
a.state = "A";
a.key = 2;
await a.render();
a.render();
await nextTick();
// this nextTick is critical, otherwise jest may silently swallow errors
await nextTick();
expect([
@@ -2362,7 +2365,8 @@ test("change state and call manually render: no unnecessary rendering", async ()
expect(numberOfRender).toBe(1);
test.state.val = 2;
await test.render();
test.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div>2</div>");
expect(numberOfRender).toBe(2);
expect(["Test:willRender", "Test:rendered", "Test:willPatch", "Test:patched"]).toBeLogged();
@@ -2456,22 +2460,6 @@ test("changing state before first render does not trigger a render (with parent)
]).toBeLogged();
});
test("render method wait until rendering is done", async () => {
class TestW extends Component {
static template = xml`<div><t t-esc="state.drinks"/></div>`;
state = { drinks: 1 };
}
const widget = await mount(TestW, fixture);
expect(fixture.innerHTML).toBe("<div>1</div>");
widget.state.drinks = 2;
const renderPromise = widget.render();
expect(fixture.innerHTML).toBe("<div>1</div>");
await renderPromise;
expect(fixture.innerHTML).toBe("<div>2</div>");
});
test("two renderings initiated between willPatch and patched", async () => {
let parent: any = null;
+25 -43
View File
@@ -1,16 +1,15 @@
import { Component, mount } from "../../src";
import { status } from "../../src/component/status";
import { xml } from "../../src/tags";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
import {
onError,
onMounted,
onPatched,
onWillPatch,
onWillStart,
onWillUnmount,
useState,
onError,
} from "../../src/index";
import { xml } from "../../src/tags";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
let fixture: HTMLElement;
@@ -35,18 +34,9 @@ describe("basics", () => {
expect(fixture.innerHTML).toBe("<div><div>heyfalse</div></div>");
parent.state.flag = true;
let error: Error;
try {
await parent.render();
} catch (e) {
error = e as Error;
}
parent.render();
await nextTick();
expect(fixture.innerHTML).toBe("");
expect(status(parent)).toBe("destroyed");
expect(error!).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'this'\)|Cannot read property 'this' of undefined/g;
expect(error!.message).toMatch(regexp);
});
test("display a nice error if it cannot find component", async () => {
@@ -154,28 +144,24 @@ describe("errors and promises", () => {
const consoleError = console.error;
console.error = jest.fn(() => {});
class App extends Component {
class Root extends Component {
static template = xml`<div><t t-esc="val"/></div>`;
val = 3;
setup() {
onWillPatch(() => {
throw new Error("boom");
});
onError((e) => (error = e));
}
}
const app = await mount(App, fixture);
app.val = 4;
const root = await mount(Root, fixture);
root.val = 4;
let error: Error;
try {
await app.render();
} catch (e) {
error = e as Error;
}
root.render();
await nextTick();
expect(error!).toBeDefined();
expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe("");
expect(console.error).toBeCalledTimes(0);
console.error = consoleError;
});
@@ -184,28 +170,24 @@ describe("errors and promises", () => {
const consoleError = console.error;
console.error = jest.fn(() => {});
class App extends Component {
class Root extends Component {
static template = xml`<div><t t-esc="val"/></div>`;
val = 3;
setup() {
onPatched(() => {
throw new Error("boom");
});
onError((e) => (error = e));
}
}
const app = await mount(App, fixture);
app.val = 4;
const root = await mount(Root, fixture);
root.val = 4;
let error: Error;
try {
await app.render();
} catch (e) {
error = e as Error;
}
root.render();
await nextTick();
expect(error!).toBeDefined();
expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe("");
expect(console.error).toBeCalledTimes(0);
console.error = consoleError;
});
@@ -241,20 +223,20 @@ describe("errors and promises", () => {
const consoleError = console.error;
console.error = jest.fn(() => {});
// we do not catch error in willPatch anymore
class App extends Component {
class Root extends Component {
static template = xml`<div><t t-if="flag" t-esc="this.will.crash"/></div>`;
flag = false;
setup() {
onError((e) => (error = e));
}
}
const app = await mount(App, fixture);
const root = await mount(Root, fixture);
expect(fixture.innerHTML).toBe("<div></div>");
app.flag = true;
root.flag = true;
let error: Error;
try {
await app.render();
} catch (e) {
error = e as Error;
}
root.render();
await nextTick();
expect(error!).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
@@ -69,7 +69,8 @@ describe("basics", () => {
expect(fixture.innerHTML).toBe("<span>CHILD 1</span>");
env.options.flag = false;
await parent.render();
parent.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div>CHILD 2</div>");
});
+12 -10
View File
@@ -1,5 +1,5 @@
import { makeTestFixture, snapshotApp } from "../helpers";
import { Component, xml } from "../../src";
import { makeTestFixture, nextTick, snapshotApp } from "../helpers";
import { Component, onError, xml } from "../../src";
import { App, DEV_MSG } from "../../src/app/app";
import { validateProps } from "../../src/component/props_validation";
@@ -667,15 +667,15 @@ describe("props validation", () => {
static template = xml`<div><SubComp p="state.p"/></div>`;
static components = { SubComp };
state: any = { p: 1 };
setup() {
onError((e) => (error = e));
}
}
const app = await mountApp(Parent);
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
try {
(app as any).root.component.state.p = undefined;
await (app as any).root.component.render();
} catch (e) {
error = e as Error;
}
(app as any).root.component.state.p = undefined;
(app as any).root.component.render();
await nextTick();
expect(error!).toBeDefined();
expect(error!.message).toBe("Missing props 'p' (component 'SubComp')");
});
@@ -696,7 +696,8 @@ describe("props validation", () => {
const app = await mountApp(Parent);
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
(app as any).root.component.state.p = undefined;
await (app as any).root.component.render();
(app as any).root.component.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><div>4</div></div>");
});
@@ -754,7 +755,8 @@ describe("default props", () => {
const app = await mountApp(Parent);
expect(fixture.innerHTML).toBe("<div><div>1</div></div>");
(app as any).root.component.state.p = undefined;
await (app as any).root.component.render();
(app as any).root.component.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><div>4</div></div>");
});
+2 -1
View File
@@ -291,7 +291,8 @@ describe("list of components", () => {
const parent = await mount(Parent, fixture);
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div><div>2</div>");
parent.clist = [2, 1];
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
expect(childInstances.length).toBe(2);
});
+15 -8
View File
@@ -1,4 +1,4 @@
import { snapshotEverything, makeTestFixture, addTemplate } from "../helpers";
import { snapshotEverything, makeTestFixture, addTemplate, nextTick } from "../helpers";
import { Component, mount, xml } from "../../src/index";
snapshotEverything();
@@ -32,7 +32,8 @@ describe("t-key", () => {
const oldChild = childInstance;
parent.key = 2;
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div>");
expect(oldChild === childInstance).toBeFalsy();
});
@@ -65,7 +66,8 @@ describe("t-key", () => {
const oldChild = childInstance;
__key = 2;
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div>");
expect(oldChild === childInstance).toBeFalsy();
expect(keyCalls).toBe(4);
@@ -97,7 +99,8 @@ describe("t-key", () => {
parent.key1 = 2;
parent.key2 = 1;
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
expect(childInstances.length).toBe(4);
});
@@ -130,7 +133,8 @@ describe("t-key", () => {
parent.key1 = 2;
parent.key2 = 1;
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
expect(childInstances.length).toBe(4);
});
@@ -165,7 +169,8 @@ describe("t-key", () => {
parent.key1 = 2;
parent.key2 = 1;
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
expect(childInstances.length).toBe(4);
});
@@ -194,14 +199,16 @@ describe("t-key", () => {
const parent = await mount(Parent, fixture);
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1key1</div><div>2key1</div>");
parent.clist = [2, 1];
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2key1</div><div>1key1</div>");
expect(childInstances.length).toBe(2);
childInstances.length = 0;
parent.clist = [1, 2];
parent.key1 = "key2";
await parent.render();
parent.render();
await nextTick();
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1key2</div><div>2key2</div>");
expect(childInstances.length).toBe(2);
});
+9 -5
View File
@@ -1,5 +1,5 @@
import { Component, mount, xml } from "../../src";
import { makeTestFixture, snapshotEverything } from "../helpers";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
snapshotEverything();
@@ -37,10 +37,12 @@ describe("t-set", () => {
expect(fixture.innerHTML).toBe("<div><p>2</p></div>");
comp.state.flag = "elif";
await comp.render();
comp.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><p>3</p></div>");
comp.state.flag = "false";
await comp.render();
comp.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><p>4</p></div>");
});
@@ -68,10 +70,12 @@ describe("t-set", () => {
expect(fixture.innerHTML).toBe("<div><p>2</p></div>");
comp.state.flag = "elif";
await comp.render();
comp.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><p>3</p></div>");
comp.state.flag = "false";
await comp.render();
comp.render();
await nextTick();
expect(fixture.innerHTML).toBe("<div><p>4</p></div>");
});
+7 -6
View File
@@ -2,6 +2,7 @@ import {
App,
Component,
mount,
onError,
onMounted,
onPatched,
onWillPatch,
@@ -391,17 +392,17 @@ describe("Portal", () => {
</Portal>
</div>`;
state = { error: false };
setup() {
onError((e) => (error = e));
}
}
addOutsideDiv(fixture);
const parent = await mount(Parent, fixture);
parent.state.error = true;
let error: Error;
try {
await parent.render();
} catch (e) {
error = e as Error;
}
parent.state.error = true;
parent.render();
await nextTick();
expect(error!).toBeDefined();
const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;