[FIX] components: throw on duplicate t-key instead of hanging the app

This commit is contained in:
Samuel Degueldre
2021-11-22 11:01:17 +01:00
committed by Aaron Bohy
parent db9658c140
commit c0cf2c9e3d
3 changed files with 98 additions and 2 deletions
@@ -39,6 +39,61 @@ exports[`list of components components in a node in a t-foreach 2`] = `
}"
`;
exports[`list of components crash on duplicate key in dev mode 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, safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]);
const keys1 = new Set();
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
let key1 = 'child';
if (keys1.has(key1)) { throw new Error(\`Got duplicate key in t-foreach: \${key1}\`)}
keys1.add(key1);
const props2 = {}
helpers.validateProps(\`Child\`, props2, ctx)
c_block1[i1] = withKey(component(\`Child\`, props2, key + \`__1__\${key1}\`, node, ctx), key1);
}
return list(c_block1);
}
}"
`;
exports[`list of components crash on duplicate key in dev mode 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, safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
return text(\`\`);
}
}"
`;
exports[`list of components crash on duplicate key in dev mode 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, safeOutput } = helpers;
return function template(ctx, node, key = \\"\\") {
ctx = Object.create(ctx);
const [k_block1, v_block1, l_block1, c_block1] = prepareList([1,2]);
for (let i1 = 0; i1 < l_block1; i1++) {
ctx[\`item\`] = v_block1[i1];
let key1 = 'child';
c_block1[i1] = withKey(component(\`Child\`, {}, key + \`__1__\${key1}\`, node, ctx), key1);
}
return list(c_block1);
}
}"
`;
exports[`list of components list of sub components inside other nodes 1`] = `
"function anonymous(bdom, helpers
) {
+32 -2
View File
@@ -1,5 +1,11 @@
import { Component, mount, onMounted, useState, xml } from "../../src/index";
import { makeTestFixture, nextTick, snapshotEverything, useLogLifecycle } from "../helpers";
import { App, Component, mount, onMounted, useState, xml } from "../../src/index";
import {
makeTestFixture,
nextTick,
snapshotApp,
snapshotEverything,
useLogLifecycle,
} from "../helpers";
snapshotEverything();
@@ -291,4 +297,28 @@ describe("list of components", () => {
expect((parent.el as HTMLElement).innerHTML).toBe("<div>2</div><div>1</div>");
expect(childInstances.length).toBe(2);
});
test("crash on duplicate key in dev mode", async () => {
const consoleInfo = console.info;
console.info = jest.fn();
class Child extends Component {
static template = xml``;
}
class Parent extends Component {
static template = xml`
<t t-foreach="[1, 2]" t-as="item" t-key="'child'">
<Child/>
</t>
`;
static components = { Child };
}
const app = new App(Parent);
app.configure({ dev: true });
await expect(async () => {
await app.mount(fixture);
}).rejects.toThrowError("Got duplicate key in t-foreach: child");
snapshotApp(app);
console.info = consoleInfo;
});
});