mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] qweb: compiler: support t-key on node and component without t-foreach
This commit is contained in:
committed by
Aaron Bohy
parent
16f1e2c237
commit
7c04cc425e
@@ -0,0 +1,208 @@
|
||||
import { snapshotEverything, makeTestFixture, addTemplate } from "../helpers";
|
||||
import { Component, mount, xml } from "../../src/index";
|
||||
|
||||
snapshotEverything();
|
||||
|
||||
let fixture: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = makeTestFixture();
|
||||
});
|
||||
|
||||
describe("t-key", () => {
|
||||
test("t-key on Component", async () => {
|
||||
let childInstance = null;
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
|
||||
setup() {
|
||||
childInstance = this;
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span><Child t-key="key" key="key" /></span>`;
|
||||
|
||||
key = 1;
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div>");
|
||||
|
||||
const oldChild = childInstance;
|
||||
parent.key = 2;
|
||||
await parent.render();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div>");
|
||||
expect(oldChild === childInstance).toBeFalsy();
|
||||
});
|
||||
|
||||
test("t-key on Component as a function", async () => {
|
||||
let childInstance = null;
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
|
||||
setup() {
|
||||
childInstance = this;
|
||||
}
|
||||
}
|
||||
|
||||
let keyCalls = 0;
|
||||
let __key = 1;
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span><Child t-key="key" key="key" /></span>`;
|
||||
|
||||
get key() {
|
||||
keyCalls++;
|
||||
return __key;
|
||||
}
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div>");
|
||||
expect(keyCalls).toBe(2); // one for t-key, the other for the props
|
||||
|
||||
const oldChild = childInstance;
|
||||
__key = 2;
|
||||
await parent.render();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div>");
|
||||
expect(oldChild === childInstance).toBeFalsy();
|
||||
expect(keyCalls).toBe(4);
|
||||
});
|
||||
|
||||
test("t-key on multiple Components", async () => {
|
||||
const childInstances = [];
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
|
||||
setup() {
|
||||
childInstances.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span>
|
||||
<Child t-key="key1" key="key1" />
|
||||
<Child t-key="key2" key="key2" />
|
||||
</span>`;
|
||||
|
||||
key1 = 1;
|
||||
key2 = 2;
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div><div>2</div>");
|
||||
|
||||
parent.key1 = 2;
|
||||
parent.key2 = 1;
|
||||
await parent.render();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
|
||||
expect(childInstances.length).toBe(4);
|
||||
});
|
||||
|
||||
test("t-key on multiple Components with t-call 1", async () => {
|
||||
const childInstances = [];
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
|
||||
setup() {
|
||||
childInstances.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
addTemplate("calledTemplate", `<Child t-key="key" key="key" />`);
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span>
|
||||
<t t-call="calledTemplate"><t t-set="key" t-value="key1" /></t>
|
||||
<t t-call="calledTemplate"><t t-set="key" t-value="key2" /></t>
|
||||
</span>`;
|
||||
|
||||
key1 = 1;
|
||||
key2 = 2;
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div><div>2</div>");
|
||||
|
||||
parent.key1 = 2;
|
||||
parent.key2 = 1;
|
||||
await parent.render();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
|
||||
expect(childInstances.length).toBe(4);
|
||||
});
|
||||
|
||||
test("t-key on multiple Components with t-call 2", async () => {
|
||||
const childInstances = [];
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
|
||||
setup() {
|
||||
childInstances.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
addTemplate(
|
||||
"calledTemplate",
|
||||
`<Child t-key="key1" key="key1" /><Child t-key="key2" key="key2" />`
|
||||
);
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span>
|
||||
<t t-call="calledTemplate" />
|
||||
</span>`;
|
||||
|
||||
key1 = 1;
|
||||
key2 = 2;
|
||||
}
|
||||
|
||||
const parent = await mount(Parent, fixture);
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1</div><div>2</div>");
|
||||
|
||||
parent.key1 = 2;
|
||||
parent.key2 = 1;
|
||||
await parent.render();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
|
||||
expect(childInstances.length).toBe(4);
|
||||
});
|
||||
|
||||
test("t-foreach with t-key switch component position", async () => {
|
||||
const childInstances = [];
|
||||
class Child extends Component {
|
||||
static template = xml`<div t-esc="props.key"></div>`;
|
||||
setup() {
|
||||
childInstances.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
class Parent extends Component {
|
||||
static components = { Child };
|
||||
static template = xml`<span>
|
||||
<t t-foreach="clist" t-as="c" t-key="c">
|
||||
<Child key="c + key1" t-key="key1"/>
|
||||
</t>
|
||||
</span>`;
|
||||
|
||||
key1 = "key1";
|
||||
clist = [1, 2];
|
||||
}
|
||||
|
||||
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();
|
||||
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();
|
||||
expect((parent.el as HTMLElement).innerHTML).toBe("<div>1key2</div><div>2key2</div>");
|
||||
expect(childInstances.length).toBe(2);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user