[IMP] portal: ensure that destroy is synchronous

This commit is contained in:
Géry Debongnie
2022-01-19 13:53:07 +01:00
committed by Aaron Bohy
parent 5a2c769eab
commit eab0caa6cb
3 changed files with 74 additions and 7 deletions
@@ -83,6 +83,36 @@ exports[`Portal Add and remove portals with t-foreach 1`] = `
}"
`;
exports[`Portal Add and remove portals with t-foreach and destroy 1`] = `
"function anonymous(bdom, helpers
) {
let { text, createBlock, list, multi, html, toggler, component, comment } = bdom;
let { prepareList, Portal, capture, withKey } = helpers;
let block2 = createBlock(\`<div><block-text-0/><block-child-0/></div>\`);
function slot1(ctx, node, key = \\"\\") {
let b4 = text(\` Portal\`);
let b5 = text(ctx['portalId']);
return multi([b4, b5]);
}
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList(ctx['portalIds']);
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`portalId\`] = v_block1[i1];
let key1 = ctx['portalId'];
let txt1 = ctx['portalId'];
const ctx1 = capture(ctx);
let b6 = component(Portal, {target: '#outside',slots: {'default': {__render: slot1, __ctx: ctx1}}}, key + \`__1__\${key1}\`, node, ctx);
c_block1[i1] = withKey(block2([txt1], [b6]), key1);
}
return list(c_block1);
}
}"
`;
exports[`Portal Add and remove portals with t-foreach inside div 1`] = `
"function anonymous(bdom, helpers
) {
+36
View File
@@ -1,4 +1,5 @@
import {
App,
Component,
mount,
onError,
@@ -653,6 +654,41 @@ describe("Portal", () => {
expect(fixture.innerHTML).toBe('<div id="outside"></div>');
});
test("Add and remove portals with t-foreach and destroy", async () => {
class Parent extends Component {
static template = xml`
<t t-foreach="portalIds" t-as="portalId" t-key="portalId">
<div>
<t t-esc="portalId"/>
<t t-portal="'#outside'">
Portal<t t-esc="portalId"/>
</t>
</div>
</t>`;
portalIds = useState([] as any);
}
addOutsideDiv(fixture);
const app = new App(Parent);
const parent = await app.mount(fixture);
expect(fixture.innerHTML).toBe('<div id="outside"></div>');
parent.portalIds.push(1);
await nextTick();
expect(fixture.innerHTML).toBe('<div id="outside"> Portal1</div><div>1</div>');
parent.portalIds.push(2);
await nextTick();
expect(fixture.innerHTML).toBe(
'<div id="outside"> Portal1 Portal2</div><div>1</div><div>2</div>'
);
app.destroy();
//This will test explicitly that we don't use an await nextTick(); after the destroy.
expect(fixture.innerHTML).toBe('<div id="outside"></div>');
});
test("conditional use of Portal with div", async () => {
class Parent extends Component {
static template = xml`