[REF] initial prototype of owl 2

This commit is contained in:
Géry Debongnie
2020-11-26 16:45:25 +01:00
parent 4e3b7c74da
commit 7ac20f4fc2
187 changed files with 29162 additions and 32486 deletions
@@ -0,0 +1,87 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Memo if no prop change, prevent renderings from above 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
return function template(ctx, node, key = \\"\\") {
return text(ctx['props'].value);
}
}"
`;
exports[`Memo if no prop change, prevent renderings from above 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
const slot2 = ctx => (node, key) => {
let b6 = text(ctx['state'].a);
let b7 = text(ctx['state'].b);
let b8 = text(ctx['state'].c);
return multi([b6, b7, b8]);
}
return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['state'].a);
let b3 = text(ctx['state'].b);
let b4 = text(ctx['state'].c);
let b9 = assign(component(\`Memo\`, {a: ctx['state'].a,b: ctx['state'].b}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return multi([b2, b3, b4, b9]);
}
}"
`;
exports[`Memo if no props, prevent renderings from above 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
return function template(ctx, node, key = \\"\\") {
return text(ctx['props'].value);
}
}"
`;
exports[`Memo if no props, prevent renderings from above 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
const slot3 = ctx => (node, key) => {
return component(\`Child\`, {value: ctx['state'].value}, key + \`__4\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b2 = component(\`Child\`, {value: ctx['state'].value}, key + \`__1\`, node, ctx);
let b4 = assign(component(\`Memo\`, {}, key + \`__2\`, node, ctx), {slots: {'default': slot3(ctx)}});
return multi([b2, b4]);
}
}"
`;
exports[`Memo if no props, prevent renderings from above (work with simple html) 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
const slot2 = ctx => (node, key) => {
return text(ctx['state'].value);
}
return function template(ctx, node, key = \\"\\") {
let b2 = text(ctx['state'].value);
let b4 = assign(component(\`Memo\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return multi([b2, b4]);
}
}"
`;
@@ -0,0 +1,466 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Portal Portal composed with t-slot 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<div>child2</div>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`Portal Portal composed with t-slot 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
const slot2 = ctx => (node, key) => {
return callSlot(ctx, node, key, 'default');
}
return function template(ctx, node, key = \\"\\") {
return assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
}
}"
`;
exports[`Portal Portal composed with t-slot 3`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
let h4 = [\`custom\`, ctx, '_handled'];
return assign(component(\`Child2\`, {}, key + \`__3\`, node, ctx), {handlers: [h4]});
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Child\`, {}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal basic use of portal 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><span>1</span><block-child-0/></div>\`);
let block2 = createBlock(\`<p>2</p>\`);
const slot2 = ctx => (node, key) => {
return block2();
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal conditional use of Portal (with sub Component) 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<p><block-text-0/></p>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['props'].val;
return block1([d1]);
}
}"
`;
exports[`Portal conditional use of Portal (with sub Component) 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block2 = createBlock(\`<span>1</span>\`);
const slot2 = ctx => (node, key) => {
return component(\`Child\`, {val: ctx['state'].val}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b2,b4;
b2 = block2();
if (ctx['state'].hasPortal) {
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
}
return multi([b2, b4]);
}
}"
`;
exports[`Portal conditional use of Portal 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block2 = createBlock(\`<span>1</span>\`);
let block3 = createBlock(\`<p>2</p>\`);
const slot2 = ctx => (node, key) => {
return block3();
}
return function template(ctx, node, key = \\"\\") {
let b2,b4;
b2 = block2();
if (ctx['state'].hasPortal) {
b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
}
return multi([b2, b4]);
}
}"
`;
exports[`Portal lifecycle hooks of portal sub component are properly called 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['props'].val;
return block1([d1]);
}
}"
`;
exports[`Portal lifecycle hooks of portal sub component are properly called 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
return component(\`Child\`, {val: ctx['state'].val}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b3;
if (ctx['state'].hasChild) {
b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
}
return block1([], [b3]);
}
}"
`;
exports[`Portal portal could have dynamically no content 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span><block-text-0/></span>\`);
const slot2 = ctx => (node, key) => {
let b3;
if (ctx['state'].val) {
let d1 = ctx['state'].val;
b3 = block3([d1]);
}
return multi([b3]);
}
return function template(ctx, node, key = \\"\\") {
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b4]);
}
}"
`;
exports[`Portal portal with child and props 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<span><block-text-0/></span>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['props'].val;
return block1([d1]);
}
}"
`;
exports[`Portal portal with child and props 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
return component(\`Child\`, {val: ctx['state'].val}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal portal with dynamic body 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<span><block-text-0/></span>\`);
let block4 = createBlock(\`<div/>\`);
const slot2 = ctx => (node, key) => {
let b3,b4;
if (ctx['state'].val) {
let d1 = ctx['state'].val;
b3 = block3([d1]);
} else {
b4 = block4();
}
return multi([b3, b4]);
}
return function template(ctx, node, key = \\"\\") {
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b5]);
}
}"
`;
exports[`Portal portal with many children 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
let block3 = createBlock(\`<div>1</div>\`);
let block4 = createBlock(\`<p>2</p>\`);
const slot2 = ctx => (node, key) => {
let b3 = block3();
let b4 = block4();
return multi([b3, b4]);
}
return function template(ctx, node, key = \\"\\") {
let b5 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b5]);
}
}"
`;
exports[`Portal portal with no content 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
let b3;
if (false) {
b3 = text('ABC');
}
return multi([b3]);
}
return function template(ctx, node, key = \\"\\") {
let b4 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b4]);
}
}"
`;
exports[`Portal portal with only text as content 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
return text('only text');
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal portal with target not in dom 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><owl-child-0/></div>\`);
let block2 = createBlock(\`<div>2</div>\`);
const slot2 = ctx => (node, key) => {
return block2();
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(node.getChild(\`Portal\`, {target: '#does-not-exist'}, key + \`__1\`, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal portal's parent's env is not polluted 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<button>child</button>\`);
return function template(ctx, node, key = \\"\\") {
return block1();
}
}"
`;
exports[`Portal portal's parent's env is not polluted 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
return component(\`Child\`, {}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal with target in template (after portal) 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><span>1</span><block-child-0/><div id=\\"local-target\\"/></div>\`);
let block2 = createBlock(\`<p>2</p>\`);
const slot2 = ctx => (node, key) => {
return block2();
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal with target in template (before portal) 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><div id=\\"local-target\\"/><span>1</span><block-child-0/></div>\`);
let block2 = createBlock(\`<p>2</p>\`);
const slot2 = ctx => (node, key) => {
return block2();
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#local-target'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
exports[`Portal: UI/UX focus is kept across re-renders 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let block1 = createBlock(\`<input id=\\"target-me\\" block-attribute-0=\\"placeholder\\"/>\`);
return function template(ctx, node, key = \\"\\") {
let d1 = ctx['props'].val;
return block1([d1]);
}
}"
`;
exports[`Portal: UI/UX focus is kept across re-renders 2`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component } = bdom;
let { withDefault, getTemplate, prepareList, withKey, zero, call, callSlot, capture, shallowEqual } = helpers;
let assign = Object.assign;
let block1 = createBlock(\`<div><block-child-0/></div>\`);
const slot2 = ctx => (node, key) => {
return component(\`Child\`, {val: ctx['state'].val}, key + \`__3\`, node, ctx);
}
return function template(ctx, node, key = \\"\\") {
let b3 = assign(component(\`Portal\`, {target: '#outside'}, key + \`__1\`, node, ctx), {slots: {'default': slot2(ctx)}});
return block1([], [b3]);
}
}"
`;
-188
View File
@@ -1,188 +0,0 @@
import { AsyncRoot } from "../../src/misc/async_root";
import { useState } from "../../src/hooks";
import { xml } from "../../src/tags";
import { makeDeferred, makeTestFixture, makeTestEnv, nextTick } from "../helpers";
import { Component } from "../../src/component/component";
//------------------------------------------------------------------------------
// Setup and helpers
//------------------------------------------------------------------------------
// We create before each test:
// - fixture: a div, appended to the DOM, intended to be the target of dom
// manipulations. Note that it is removed after each test.
// - a test env, necessary to create components, that is set as env
let fixture: HTMLElement;
beforeEach(() => {
fixture = makeTestFixture();
Component.env = makeTestEnv();
});
afterEach(() => {
fixture.remove();
});
describe("Asyncroot", () => {
test("delayed component with AsyncRoot component", async () => {
let def;
class Child extends Component {
static template = xml`<span><t t-esc="props.val"/></span>`;
}
class AsyncChild extends Child {
willUpdateProps() {
return def;
}
}
class Parent extends Component {
static template = xml`
<div>
<button t-on-click="updateApp">Update App State</button>
<div class="children">
<Child val="state.val"/>
<AsyncRoot>
<AsyncChild val="state.val"/>
</AsyncRoot>
</div>
</div>`;
static components = { Child, AsyncChild, AsyncRoot };
state = useState({ val: 0 });
updateApp() {
this.state.val++;
}
}
const parent = new Parent();
await parent.mount(fixture);
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
// click on button to increment Parent counter
def = makeDeferred();
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1</span><span>0</span>");
def.resolve();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1</span><span>1</span>");
});
test("fast component with AsyncRoot", async () => {
let def;
class Child extends Component {
static template = xml`<span><t t-esc="props.val"/></span>`;
}
class AsyncChild extends Child {
willUpdateProps() {
return def;
}
}
class Parent extends Component {
static template = xml`
<div>
<button t-on-click="updateApp">Update App State</button>
<div class="children">
<AsyncRoot>
<Child val="state.val"/>
</AsyncRoot>
<AsyncChild val="state.val"/>
</div>
</div>`;
static components = { Child, AsyncChild, AsyncRoot };
state = useState({ val: 0 });
updateApp() {
this.state.val++;
}
}
const parent = new Parent();
await parent.mount(fixture);
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0</span><span>0</span>");
// click on button to increment Parent counter
def = makeDeferred();
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1</span><span>0</span>");
def.resolve();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1</span><span>1</span>");
});
test("asyncroot component: mixed re-renderings", async () => {
let def;
class Child extends Component {
static template = xml`
<span t-on-click="increment">
<t t-esc="state.val"/>/<t t-esc="props.val"/>
</span>`;
state = useState({ val: 0 });
increment() {
this.state.val++;
}
}
class AsyncChild extends Child {
willUpdateProps() {
return def;
}
}
class Parent extends Component {
static template = xml`
<div>
<button t-on-click="updateApp">Update App State</button>
<div class="children">
<Child val="state.val"/>
<AsyncRoot>
<AsyncChild val="state.val"/>
</AsyncRoot>
</div>
</div>`;
static components = { Child, AsyncChild, AsyncRoot };
state = useState({ val: 0 });
updateApp() {
this.state.val++;
}
}
const parent = new Parent();
await parent.mount(fixture);
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0/0</span><span>0/0</span>");
// click on button to increment Parent counter
def = makeDeferred();
fixture.querySelector("button")!.click();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>0/1</span><span>0/0</span>");
// click on each Child to increment their local counter
const children = parent.el!.querySelectorAll("span");
children[0]!.click();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1/1</span><span>0/0</span>");
children[1]!.click();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1/1</span><span>0/0</span>");
// finalize first re-rendering (coming from the props update)
def.resolve();
await nextTick();
expect(fixture.querySelector(".children")!.innerHTML).toBe("<span>1/1</span><span>1/1</span>");
});
});
+93
View File
@@ -0,0 +1,93 @@
import { Component, mount, useState } from "../../src";
import { Memo } from "../../src/";
import { xml } from "../../src/tags";
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
let fixture: HTMLElement;
snapshotEverything();
beforeEach(() => {
fixture = makeTestFixture();
});
describe("Memo", () => {
test("if no props, prevent renderings from above ", async () => {
class Child extends Component {
static template = xml`<t t-esc="props.value"/>`;
}
class Test extends Component {
static template = xml`
<Child value="state.value"/>
<Memo>
<Child value="state.value"/>
</Memo>`;
static components = { Memo, Child };
state = useState({ value: 1 });
}
const component = await mount(Test, fixture);
expect(fixture.innerHTML).toBe("11");
component.state.value = 2;
await nextTick();
expect(fixture.innerHTML).toBe("21");
});
test("if no props, prevent renderings from above (work with simple html) ", async () => {
class Test extends Component {
static template = xml`
<t t-esc="state.value"/>
<Memo>
<t t-esc="state.value"/>
</Memo>`;
static components = { Memo };
state = useState({ value: 1 });
}
const component = await mount(Test, fixture);
expect(fixture.innerHTML).toBe("11");
component.state.value = 2;
await nextTick();
expect(fixture.innerHTML).toBe("21");
});
test("if no prop change, prevent renderings from above ", async () => {
class Child extends Component {
static template = xml`<t t-esc="props.value"/>`;
}
class Test extends Component {
static template = xml`
<t t-esc="state.a"/>
<t t-esc="state.b"/>
<t t-esc="state.c"/>
<Memo a="state.a" b="state.b">
<t t-esc="state.a"/>
<t t-esc="state.b"/>
<t t-esc="state.c"/>
</Memo>`;
static components = { Memo, Child };
state = useState({ a: "a", b: "b", c: "c" });
}
const component = await mount(Test, fixture);
expect(fixture.innerHTML).toBe("abcabc");
component.state.c = "C";
await nextTick();
expect(fixture.innerHTML).toBe("abCabc");
component.state.a = "A";
await nextTick();
expect(fixture.innerHTML).toBe("AbCAbC");
});
});
+440 -579
View File
File diff suppressed because it is too large Load Diff