[IMP] misc: update typescript to 4.5.2

This commit is contained in:
Samuel Degueldre
2021-11-19 14:35:25 +01:00
committed by Géry Debongnie
parent 757dffefac
commit 7f49796a07
12 changed files with 214 additions and 214 deletions
+1 -1
View File
@@ -56,7 +56,7 @@
"sass": "^1.16.1", "sass": "^1.16.1",
"source-map-support": "^0.5.10", "source-map-support": "^0.5.10",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "3.9.6", "typescript": "4.5.2",
"uglify-es": "^3.3.9" "uglify-es": "^3.3.9"
}, },
"jest": { "jest": {
+1
View File
@@ -8,6 +8,7 @@ import type { ComponentNode } from "./component_node";
export class Component { export class Component {
static template: string = ""; static template: string = "";
static style: string = ""; static style: string = "";
static props?: any;
props: any; props: any;
env: Env; env: Env;
+9 -10
View File
@@ -26,26 +26,23 @@ export function applyDefaultProps(props: { [key: string]: any }, ComponentClass:
* visit recursively the props and all the children to check if they are valid. * visit recursively the props and all the children to check if they are valid.
* This is why it is only done in 'dev' mode. * This is why it is only done in 'dev' mode.
*/ */
// message: { type: String, default: "hello" };
export const validateProps = function (name: string | typeof Component, props: any, parent?: any) { export const validateProps = function (name: string | typeof Component, props: any, parent?: any) {
const ComponentClass = const ComponentClass = (
typeof name !== "string" ? name : parent.constructor.components[name as string]; typeof name !== "string" ? name : parent.constructor.components[name]
) as typeof Component;
applyDefaultProps(props, ComponentClass); applyDefaultProps(props, ComponentClass);
const propsDef = (<any>ComponentClass).props; const propsDef = ComponentClass.props;
if (propsDef instanceof Array) { if (propsDef instanceof Array) {
// list of strings (prop names) // list of strings (prop names)
for (let i = 0, l = propsDef.length; i < l; i++) { for (const propName of propsDef) {
const propName = propsDef[i];
if (propName[propName.length - 1] === "?") { if (propName[propName.length - 1] === "?") {
// optional prop // optional prop
break; break;
} }
if (!(propName in props)) { if (!(propName in props)) {
throw new Error(`Missing props '${propsDef[i]}' (component '${ComponentClass.name}')`); throw new Error(`Missing props '${propName}' (component '${ComponentClass.name}')`);
} }
} }
for (let key in props) { for (let key in props) {
@@ -67,7 +64,9 @@ export const validateProps = function (name: string | typeof Component, props: a
try { try {
isValid = isValidProp(props[propName], propsDef[propName]); isValid = isValidProp(props[propName], propsDef[propName]);
} catch (e) { } catch (e) {
e.message = `Invalid prop '${propName}' in component ${ComponentClass.name} (${e.message})`; (e as Error).message = `Invalid prop '${propName}' in component ${ComponentClass.name} (${
(e as Error).message
})`;
throw e; throw e;
} }
if (!isValid) { if (!isValid) {
+16 -16
View File
@@ -40,14 +40,14 @@ describe("basics", () => {
class SomeWidget extends Component { class SomeWidget extends Component {
static template = xml`<div>content</div>`; static template = xml`<div>content</div>`;
} }
let error; let error: Error;
try { try {
await mount(SomeWidget, document.createDocumentFragment() as any); await mount(SomeWidget, document.createDocumentFragment() as any);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Cannot mount component: the target is not a valid DOM element"); expect(error!.message).toBe("Cannot mount component: the target is not a valid DOM element");
}); });
test("can mount a simple component with props", async () => { test("can mount a simple component with props", async () => {
@@ -160,28 +160,28 @@ describe("basics", () => {
static template = xml`<span>simple vnode</span>`; static template = xml`<span>simple vnode</span>`;
} }
let error; let error: Error;
try { try {
await mount(Test, null as any); await mount(Test, null as any);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Cannot mount component: the target is not a valid DOM element"); expect(error!.message).toBe("Cannot mount component: the target is not a valid DOM element");
}); });
test("a component cannot be mounted in a detached node", async () => { test("a component cannot be mounted in a detached node", async () => {
class Test extends Component { class Test extends Component {
static template = xml`<div/>`; static template = xml`<div/>`;
} }
let error; let error: Error;
try { try {
await mount(Test, document.createElement("div")); await mount(Test, document.createElement("div"));
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Cannot mount a component on a detached dom node"); expect(error!.message).toBe("Cannot mount a component on a detached dom node");
}); });
test("crashes if it cannot find a template", async () => { test("crashes if it cannot find a template", async () => {
@@ -189,14 +189,14 @@ describe("basics", () => {
static template = "wrongtemplate"; static template = "wrongtemplate";
} }
let error; let error: Error;
try { try {
await mount(Test, fixture); await mount(Test, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe('Missing template: "wrongtemplate"'); expect(error!.message).toBe('Missing template: "wrongtemplate"');
}); });
test("class component with dynamic text", async () => { test("class component with dynamic text", async () => {
+38 -38
View File
@@ -35,18 +35,18 @@ describe("basics", () => {
expect(fixture.innerHTML).toBe("<div><div>heyfalse</div></div>"); expect(fixture.innerHTML).toBe("<div><div>heyfalse</div></div>");
parent.state.flag = true; parent.state.flag = true;
let error; let error: Error;
try { try {
await parent.render(); await parent.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect(status(parent)).toBe("destroyed"); expect(status(parent)).toBe("destroyed");
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'this'\)|Cannot read property 'this' of undefined/g; /Cannot read properties of undefined \(reading 'this'\)|Cannot read property 'this' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
}); });
test("display a nice error if it cannot find component", async () => { test("display a nice error if it cannot find component", async () => {
@@ -58,14 +58,14 @@ describe("basics", () => {
static template = xml`<SomeMispelledComponent />`; static template = xml`<SomeMispelledComponent />`;
static components = { SomeComponent }; static components = { SomeComponent };
} }
let error; let error: Error;
try { try {
await mount(Parent, fixture); await mount(Parent, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe('Cannot find the definition of component "SomeMispelledComponent"'); expect(error!.message).toBe('Cannot find the definition of component "SomeMispelledComponent"');
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
console.error = consoleError; console.error = consoleError;
}); });
@@ -108,16 +108,16 @@ describe("errors and promises", () => {
static template = xml`<div><t t-esc="this.will.crash"/></div>`; static template = xml`<div><t t-esc="this.will.crash"/></div>`;
} }
let error; let error: Error;
try { try {
await mount(App, fixture); await mount(App, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g; /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
console.error = consoleError; console.error = consoleError;
@@ -136,14 +136,14 @@ describe("errors and promises", () => {
} }
} }
let error; let error: Error;
try { try {
await mount(App, fixture); await mount(App, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("boom"); expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
@@ -166,14 +166,14 @@ describe("errors and promises", () => {
const app = await mount(App, fixture); const app = await mount(App, fixture);
app.val = 4; app.val = 4;
let error; let error: Error;
try { try {
await app.render(); await app.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("boom"); expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
@@ -196,14 +196,14 @@ describe("errors and promises", () => {
const app = await mount(App, fixture); const app = await mount(App, fixture);
app.val = 4; app.val = 4;
let error; let error: Error;
try { try {
await app.render(); await app.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("boom"); expect(error!.message).toBe("boom");
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
@@ -222,16 +222,16 @@ describe("errors and promises", () => {
static components = { Child }; static components = { Child };
} }
let error; let error: Error;
try { try {
await mount(App, fixture); await mount(App, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g; /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
console.error = consoleError; console.error = consoleError;
@@ -249,16 +249,16 @@ describe("errors and promises", () => {
const app = await mount(App, fixture); const app = await mount(App, fixture);
expect(fixture.innerHTML).toBe("<div></div>"); expect(fixture.innerHTML).toBe("<div></div>");
app.flag = true; app.flag = true;
let error; let error: Error;
try { try {
await app.render(); await app.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g; /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
expect(console.error).toBeCalledTimes(0); expect(console.error).toBeCalledTimes(0);
console.error = consoleError; console.error = consoleError;
@@ -273,20 +273,20 @@ describe("errors and promises", () => {
static components = { Child }; static components = { Child };
} }
let error; let error: Error;
try { try {
await mount(Parent, fixture); await mount(Parent, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'y'\)|Cannot read property 'y' of undefined/g; /Cannot read properties of undefined \(reading 'y'\)|Cannot read property 'y' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
}); });
test("errors in mounted and in willUnmount", async () => { test("errors in mounted and in willUnmount", async () => {
expect.assertions(2); // apparently this expect count in assertions... expect.assertions(2);
class Example extends Component { class Example extends Component {
static template = xml`<div/>`; static template = xml`<div/>`;
val: any; val: any;
@@ -305,7 +305,7 @@ describe("errors and promises", () => {
try { try {
await mount(Example, fixture); await mount(Example, fixture);
} catch (e) { } catch (e) {
expect(e.message).toBe("Error in mounted"); expect((e as Error).message).toBe("Error in mounted");
} }
}); });
}); });
+116 -116
View File
@@ -46,23 +46,23 @@ describe("props validation", () => {
static components = { SubComp }; static components = { SubComp };
static template = xml`<div><SubComp /></div>`; static template = xml`<div><SubComp /></div>`;
} }
let error; let error: Error | undefined;
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Missing props 'message' (component 'SubComp')`); expect(error!.message).toBe(`Missing props 'message' (component 'SubComp')`);
error = undefined; error = undefined;
try { try {
await mountApp(Parent, false); await mountApp(Parent, false);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
}); });
test("props: list of strings", async () => { test("props: list of strings", async () => {
@@ -75,14 +75,14 @@ describe("props validation", () => {
static template = xml`<div><SubComp /></div>`; static template = xml`<div><SubComp /></div>`;
} }
let error; let error: Error;
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Missing props 'message' (component 'SubComp')`); expect(error!.message).toBe(`Missing props 'message' (component 'SubComp')`);
}); });
test("validate simple types", async () => { test("validate simple types", async () => {
@@ -108,32 +108,32 @@ describe("props validation", () => {
}; };
(Parent as any).components = { SubComp }; (Parent as any).components = { SubComp };
let error; let error: Error | undefined;
props = {}; props = {};
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Missing props 'p' (component '_a')`); expect(error!.message).toBe(`Missing props 'p' (component '_a')`);
error = undefined; error = undefined;
props = { p: test.ok }; props = { p: test.ok };
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
props = { p: test.ko }; props = { p: test.ko };
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component '_a'"); expect(error!.message).toBe("Invalid Prop 'p' in component '_a'");
} }
}); });
@@ -159,31 +159,31 @@ describe("props validation", () => {
static template = xml`<div>hey</div>`; static template = xml`<div>hey</div>`;
}; };
(Parent as any).components = { SubComp }; (Parent as any).components = { SubComp };
let error; let error: Error | undefined;
props = {}; props = {};
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Missing props 'p' (component '_a')`); expect(error!.message).toBe(`Missing props 'p' (component '_a')`);
error = undefined; error = undefined;
props = { p: test.ok }; props = { p: test.ok };
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
props = { p: test.ko }; props = { p: test.ko };
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component '_a'"); expect(error!.message).toBe("Invalid Prop 'p' in component '_a'");
} }
}); });
@@ -199,30 +199,30 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: "string" }; props = { p: "string" };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: true }; props = { p: true };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: 1 }; props = { p: 1 };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
}); });
test("can validate an optional props", async () => { test("can validate an optional props", async () => {
@@ -237,30 +237,30 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: "key" }; props = { p: "key" };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = {}; props = {};
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: 1 }; props = { p: 1 };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
}); });
test("can validate an array with given primitive type", async () => { test("can validate an array with given primitive type", async () => {
@@ -275,35 +275,35 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error | undefined;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: [] }; props = { p: [] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: ["string"] }; props = { p: ["string"] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: [1] }; props = { p: [1] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
error = undefined; error = undefined;
try { try {
props = { p: ["string", 1] }; props = { p: ["string", 1] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
}); });
@@ -319,37 +319,37 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: [] }; props = { p: [] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: ["string"] }; props = { p: ["string"] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: [false, true, "string"] }; props = { p: [false, true, "string"] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: [true, 1] }; props = { p: [true, 1] };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
}); });
test("can validate an object with simple shape", async () => { test("can validate an object with simple shape", async () => {
@@ -366,40 +366,40 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error | undefined;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: { id: 1, url: "url" } }; props = { p: { id: 1, url: "url" } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: { id: 1, url: "url", extra: true } }; props = { p: { id: 1, url: "url", extra: true } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid prop 'p' in component SubComp (unknown prop 'extra')"); expect(error!.message).toBe("Invalid prop 'p' in component SubComp (unknown prop 'extra')");
try { try {
props = { p: { id: "1", url: "url" } }; props = { p: { id: "1", url: "url" } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
error = undefined; error = undefined;
try { try {
props = { p: { id: 1 } }; props = { p: { id: 1 } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
}); });
test("can validate recursively complicated prop def", async () => { test("can validate recursively complicated prop def", async () => {
@@ -422,30 +422,30 @@ describe("props validation", () => {
return props.p; return props.p;
} }
} }
let error; let error: Error;
let props: { p?: any }; let props: { p?: any };
try { try {
props = { p: { id: 1, url: true } }; props = { p: { id: 1, url: true } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: { id: 1, url: [12] } }; props = { p: { id: 1, url: [12] } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
props = { p: { id: 1, url: [12, true] } }; props = { p: { id: 1, url: [12, true] } };
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'p' in component 'SubComp'"); expect(error!.message).toBe("Invalid Prop 'p' in component 'SubComp'");
}); });
test("can validate optional attributes in nested sub props", () => { test("can validate optional attributes in nested sub props", () => {
@@ -462,20 +462,20 @@ describe("props validation", () => {
}, },
}; };
} }
let error; let error: Error;
try { try {
validateProps(TestComponent as any, { myprop: [{}] }); validateProps(TestComponent as any, { myprop: [{}] });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
validateProps(TestComponent as any, { myprop: [{ a: 1 }] }); validateProps(TestComponent as any, { myprop: [{ a: 1 }] });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe( expect(error!.message).toBe(
"Invalid prop 'myprop' in component TestComponent (unknown prop 'a')" "Invalid prop 'myprop' in component TestComponent (unknown prop 'a')"
); );
}); });
@@ -488,20 +488,20 @@ describe("props validation", () => {
}, },
}; };
} }
let error; let error: Error;
try { try {
validateProps(TestComponent as any, { size: "small" }); validateProps(TestComponent as any, { size: "small" });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
try { try {
validateProps(TestComponent as any, { size: "abcdef" }); validateProps(TestComponent as any, { size: "abcdef" });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'size' in component 'TestComponent'"); expect(error!.message).toBe("Invalid Prop 'size' in component 'TestComponent'");
}); });
test("can validate with a custom validator, and a type", () => { test("can validate with a custom validator, and a type", () => {
@@ -514,30 +514,30 @@ describe("props validation", () => {
}, },
}; };
} }
let error; let error: Error | undefined;
try { try {
validateProps(TestComponent as any, { n: 3 }); validateProps(TestComponent as any, { n: 3 });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeUndefined(); expect(error!).toBeUndefined();
expect(validator).toBeCalledTimes(1); expect(validator).toBeCalledTimes(1);
try { try {
validateProps(TestComponent as any, { n: "str" }); validateProps(TestComponent as any, { n: "str" });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'n' in component 'TestComponent'"); expect(error!.message).toBe("Invalid Prop 'n' in component 'TestComponent'");
expect(validator).toBeCalledTimes(1); expect(validator).toBeCalledTimes(1);
error = null; error = undefined;
try { try {
validateProps(TestComponent as any, { n: 100 }); validateProps(TestComponent as any, { n: 100 });
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Invalid Prop 'n' in component 'TestComponent'"); expect(error!.message).toBe("Invalid Prop 'n' in component 'TestComponent'");
expect(validator).toBeCalledTimes(2); expect(validator).toBeCalledTimes(2);
}); });
@@ -647,18 +647,18 @@ describe("props validation", () => {
static template = xml`<div><SubComp/></div>`; static template = xml`<div><SubComp/></div>`;
static components = { SubComp }; static components = { SubComp };
} }
let error; let error: Error;
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Missing props 'p' (component 'SubComp')"); expect(error!.message).toBe("Missing props 'p' (component 'SubComp')");
}); });
test("props are validated whenever component is updated", async () => { test("props are validated whenever component is updated", async () => {
let error; let error: Error;
class SubComp extends Component { class SubComp extends Component {
static props = { p: { type: Number } }; static props = { p: { type: Number } };
static template = xml`<div><t t-esc="props.p"/></div>`; static template = xml`<div><t t-esc="props.p"/></div>`;
@@ -674,10 +674,10 @@ describe("props validation", () => {
(app as any).root.component.state.p = undefined; (app as any).root.component.state.p = undefined;
await (app as any).root.component.render(); await (app as any).root.component.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Missing props 'p' (component 'SubComp')"); expect(error!.message).toBe("Missing props 'p' (component 'SubComp')");
}); });
test("default values are applied before validating props at update", async () => { test("default values are applied before validating props at update", async () => {
@@ -712,14 +712,14 @@ describe("props validation", () => {
static components = { Child }; static components = { Child };
static template = xml`<div><Child/></div>`; static template = xml`<div><Child/></div>`;
} }
let error; let error: Error;
try { try {
await mountApp(Parent); await mountApp(Parent);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("Missing props 'mandatory' (component 'Child')"); expect(error!.message).toBe("Missing props 'mandatory' (component 'Child')");
}); });
}); });
+4 -4
View File
@@ -338,16 +338,16 @@ describe("style and class handling", () => {
static template = xml`<Child class="'a'"/>`; static template = xml`<Child class="'a'"/>`;
static components = { Child }; static components = { Child };
} }
let error; let error: Error;
try { try {
await mount(ParentWidget, fixture); await mount(ParentWidget, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g; /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
expect(fixture.innerHTML).toBe(""); expect(fixture.innerHTML).toBe("");
}); });
}); });
+4 -4
View File
@@ -87,14 +87,14 @@ describe("styles and component", () => {
static template = xml`<div class="app">text</div>`; static template = xml`<div class="app">text</div>`;
static style = `.app {color: red;}`; static style = `.app {color: red;}`;
} }
let error; let error: Error;
try { try {
await mount(App, fixture); await mount(App, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe( expect(error!.message).toBe(
"Invalid css stylesheet for component 'App'. Did you forget to use the 'css' tag helper?" "Invalid css stylesheet for component 'App'. Did you forget to use the 'css' tag helper?"
); );
}); });
+4 -4
View File
@@ -205,14 +205,14 @@ describe("t-component", () => {
static components = { Child }; static components = { Child };
static template = xml`<div><div t-component="Child"/></div>`; static template = xml`<div><div t-component="Child"/></div>`;
} }
let error; let error: Error;
try { try {
await mount(Parent, fixture); await mount(Parent, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe( expect(error!.message).toBe(
`Directive 't-component' can only be used on <t> nodes (used on a <div>)` `Directive 't-component' can only be used on <t> nodes (used on a <div>)`
); );
}); });
+4 -4
View File
@@ -57,14 +57,14 @@ describe("t-model directive", () => {
</div>`; </div>`;
state = useState({ text: "" }); state = useState({ text: "" });
} }
let error; let error: Error;
try { try {
await mount(SomeComponent, fixture); await mount(SomeComponent, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Invalid t-model expression: "state" (it should be assignable)`); expect(error!.message).toBe(`Invalid t-model expression: "state" (it should be assignable)`);
}); });
test("basic use, on another key in component", async () => { test("basic use, on another key in component", async () => {
+1 -1
View File
@@ -42,7 +42,7 @@ describe("t-props", () => {
a: "first", a: "first",
b: "second", b: "second",
}); });
a = "third"; a? = "third";
} }
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
expect(fixture.textContent).toBe("thirdsecond"); expect(fixture.textContent).toBe("thirdsecond");
+16 -16
View File
@@ -160,15 +160,15 @@ describe("Portal", () => {
</div>`; </div>`;
} }
let error; let error: Error;
try { try {
await mount(Parent, fixture); await mount(Parent, fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe("invalid portal target"); expect(error!.message).toBe("invalid portal target");
expect(fixture.innerHTML).toBe(`<div></div>`); expect(fixture.innerHTML).toBe(`<div></div>`);
}); });
@@ -396,16 +396,16 @@ describe("Portal", () => {
const parent = await mount(Parent, fixture); const parent = await mount(Parent, fixture);
parent.state.error = true; parent.state.error = true;
let error; let error: Error;
try { try {
await parent.render(); await parent.render();
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
const regexp = const regexp =
/Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g; /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g;
expect(error.message).toMatch(regexp); expect(error!.message).toMatch(regexp);
}); });
test("portal's parent's env is not polluted", async () => { test("portal's parent's env is not polluted", async () => {
@@ -519,16 +519,16 @@ describe("Portal: Props validation", () => {
</Portal> </Portal>
</div>`; </div>`;
} }
let error; let error: Error;
let app = new App(Parent); let app = new App(Parent);
app.configure({ dev: true }); app.configure({ dev: true });
try { try {
await app.mount(fixture); await app.mount(fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Missing props 'target' (component 'Portal')`); expect(error!.message).toBe(`Missing props 'target' (component 'Portal')`);
console.info = consoleInfo; console.info = consoleInfo;
}); });
@@ -544,16 +544,16 @@ describe("Portal: Props validation", () => {
</Portal> </Portal>
</div>`; </div>`;
} }
let error; let error: Error;
let app = new App(Parent); let app = new App(Parent);
app.configure({ dev: true }); app.configure({ dev: true });
try { try {
await app.mount(fixture); await app.mount(fixture);
} catch (e) { } catch (e) {
error = e; error = e as Error;
} }
expect(error).toBeDefined(); expect(error!).toBeDefined();
expect(error.message).toBe(`Invalid Prop 'target' in component 'Portal'`); expect(error!.message).toBe(`Invalid Prop 'target' in component 'Portal'`);
console.info = consoleInfo; console.info = consoleInfo;
}); });
}); });