From d5ed25cd1936a27ac4961e5d2a76472c01d4f779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Sat, 24 Sep 2022 07:54:25 +0200 Subject: [PATCH] [FIX] props validation: does not crash with t-call-context The code for props validation assumed that the rendering context was a component. This was actually true when it was written, but is no longer true since t-call-context was introduced. Because of that, it would crash when trying to access the internals of the component, such as the static components object. The fix is simple: instead of passing the context to the props validation code, which can now be anything, we pass the component node, which is guaranteed to give a reference to the component (and also to the app). This also make the code slightly simpler. closes #1261 --- src/compiler/code_generator.ts | 2 +- src/runtime/app.ts | 2 +- src/runtime/template_helpers.ts | 6 +- .../__snapshots__/error_handling.test.ts.snap | 2 +- .../__snapshots__/lifecycle.test.ts.snap | 2 +- .../props_validation.test.ts.snap | 140 +++++++++--------- .../__snapshots__/t_call.test.ts.snap | 45 ++++++ .../__snapshots__/t_foreach.test.ts.snap | 2 +- tests/components/t_call.test.ts | 28 ++++ 9 files changed, 151 insertions(+), 78 deletions(-) diff --git a/src/compiler/code_generator.ts b/src/compiler/code_generator.ts index e4bb897f..6d41f67a 100644 --- a/src/compiler/code_generator.ts +++ b/src/compiler/code_generator.ts @@ -1188,7 +1188,7 @@ export class CodeGenerator { } if (this.dev) { - this.addLine(`helpers.validateProps(${expr}, ${propVar!}, ctx);`); + this.addLine(`helpers.validateProps(${expr}, ${propVar!}, node);`); } if (block && (ctx.forceNewBlock === false || ctx.tKeyExpr)) { diff --git a/src/runtime/app.ts b/src/runtime/app.ts index 736f221d..f548088f 100644 --- a/src/runtime/app.ts +++ b/src/runtime/app.ts @@ -66,7 +66,7 @@ export class App< mount(target: HTMLElement, options?: MountOptions): Promise & InstanceType> { App.validateTarget(target); if (this.dev) { - validateProps(this.Root, this.props, { __owl__: { app: this } }); + validateProps(this.Root, this.props, { app: this }); } const node = this.makeNode(this.Root, this.props); const prom = this.mountNode(node, target, options); diff --git a/src/runtime/template_helpers.ts b/src/runtime/template_helpers.ts index 78db7e03..cf7a9181 100644 --- a/src/runtime/template_helpers.ts +++ b/src/runtime/template_helpers.ts @@ -207,11 +207,11 @@ function multiRefSetter(refs: RefMap, name: string): RefSetter { * visit recursively the props and all the children to check if they are valid. * This is why it is only done in 'dev' mode. */ -export function validateProps

(name: string | ComponentConstructor

, props: P, parent?: any) { +export function validateProps

(name: string | ComponentConstructor

, props: P, node?: any) { const ComponentClass = typeof name !== "string" ? name - : (parent.constructor.components[name] as ComponentConstructor

| undefined); + : (node.component.constructor.components[name] as ComponentConstructor

| undefined); if (!ComponentClass) { // this is an error, wrong component. We silently return here instead so the @@ -221,7 +221,7 @@ export function validateProps

(name: string | ComponentConstructor

, props: const schema = ComponentClass.props; if (!schema) { - if (parent.__owl__.app.warnIfNoStaticProps) { + if (node.app.warnIfNoStaticProps) { console.warn(`Component '${ComponentClass.name}' does not have a static props description`); } return; diff --git a/tests/components/__snapshots__/error_handling.test.ts.snap b/tests/components/__snapshots__/error_handling.test.ts.snap index 7adf8fbb..9e48ca71 100644 --- a/tests/components/__snapshots__/error_handling.test.ts.snap +++ b/tests/components/__snapshots__/error_handling.test.ts.snap @@ -20,7 +20,7 @@ exports[`basics display a nice error if it cannot find component (in dev mode) 1 return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SomeMispelledComponent\`, props1, ctx); + helpers.validateProps(\`SomeMispelledComponent\`, props1, node); return comp1(props1, key + \`__1\`, node, this, null); } }" diff --git a/tests/components/__snapshots__/lifecycle.test.ts.snap b/tests/components/__snapshots__/lifecycle.test.ts.snap index 5418cbf3..8068056b 100644 --- a/tests/components/__snapshots__/lifecycle.test.ts.snap +++ b/tests/components/__snapshots__/lifecycle.test.ts.snap @@ -704,7 +704,7 @@ exports[`lifecycle hooks timeout in onWillUpdateProps emits a warning 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {prop: ctx['state'].prop}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); return comp1(props1, key + \`__1\`, node, this, null); } }" diff --git a/tests/components/__snapshots__/props_validation.test.ts.snap b/tests/components/__snapshots__/props_validation.test.ts.snap index 281e3a4c..37654493 100644 --- a/tests/components/__snapshots__/props_validation.test.ts.snap +++ b/tests/components/__snapshots__/props_validation.test.ts.snap @@ -8,7 +8,7 @@ exports[`default props a default prop cannot be defined on a mandatory prop 1`] return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); return comp1(props1, key + \`__1\`, node, this, null); } }" @@ -24,7 +24,7 @@ exports[`default props can set default boolean values 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -61,7 +61,7 @@ exports[`default props can set default values 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -92,7 +92,7 @@ exports[`default props default values are also set whenever component is updated return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['state'].p}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -121,7 +121,7 @@ exports[`props validation can specify that additional props are allowed (array) return function template(ctx, node, key = \\"\\") { const props1 = {message: 'm',otherProp: 'o'}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); return comp1(props1, key + \`__1\`, node, this, null); } }" @@ -148,7 +148,7 @@ exports[`props validation can specify that additional props are allowed (object) return function template(ctx, node, key = \\"\\") { const props1 = {message: 'm',otherProp: 'o'}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); return comp1(props1, key + \`__1\`, node, this, null); } }" @@ -177,7 +177,7 @@ exports[`props validation can validate a prop with multiple types 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -207,7 +207,7 @@ exports[`props validation can validate a prop with multiple types 3`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -237,7 +237,7 @@ exports[`props validation can validate a prop with multiple types 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -254,7 +254,7 @@ exports[`props validation can validate an array with given primitive type 1`] = return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -284,7 +284,7 @@ exports[`props validation can validate an array with given primitive type 3`] = return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -314,7 +314,7 @@ exports[`props validation can validate an array with given primitive type 5`] = return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -331,7 +331,7 @@ exports[`props validation can validate an array with given primitive type 6`] = return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -348,7 +348,7 @@ exports[`props validation can validate an array with multiple sub element types return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -378,7 +378,7 @@ exports[`props validation can validate an array with multiple sub element types return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -408,7 +408,7 @@ exports[`props validation can validate an array with multiple sub element types return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -438,7 +438,7 @@ exports[`props validation can validate an array with multiple sub element types return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -455,7 +455,7 @@ exports[`props validation can validate an object with simple shape 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -485,7 +485,7 @@ exports[`props validation can validate an object with simple shape 3`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -502,7 +502,7 @@ exports[`props validation can validate an object with simple shape 4`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -519,7 +519,7 @@ exports[`props validation can validate an object with simple shape 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -536,7 +536,7 @@ exports[`props validation can validate an optional props 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -566,7 +566,7 @@ exports[`props validation can validate an optional props 3`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -596,7 +596,7 @@ exports[`props validation can validate an optional props 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -613,7 +613,7 @@ exports[`props validation can validate recursively complicated prop def 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -643,7 +643,7 @@ exports[`props validation can validate recursively complicated prop def 3`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -673,7 +673,7 @@ exports[`props validation can validate recursively complicated prop def 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -690,7 +690,7 @@ exports[`props validation default values are applied before validating props at return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['state'].p}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -721,7 +721,7 @@ exports[`props validation missing required boolean prop causes an error 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -738,7 +738,7 @@ exports[`props validation mix of optional and mandatory 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -755,7 +755,7 @@ exports[`props validation props are validated in dev mode (code snapshot) 1`] = return function template(ctx, node, key = \\"\\") { const props1 = {message: 1}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -786,7 +786,7 @@ exports[`props validation props are validated whenever component is updated 1`] return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['state'].p}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -817,7 +817,7 @@ exports[`props validation props: list of strings 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -834,7 +834,7 @@ exports[`props validation validate simple types 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -851,7 +851,7 @@ exports[`props validation validate simple types 2`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -881,7 +881,7 @@ exports[`props validation validate simple types 4`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -898,7 +898,7 @@ exports[`props validation validate simple types 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -915,7 +915,7 @@ exports[`props validation validate simple types 6`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -945,7 +945,7 @@ exports[`props validation validate simple types 8`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -962,7 +962,7 @@ exports[`props validation validate simple types 9`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -979,7 +979,7 @@ exports[`props validation validate simple types 10`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1009,7 +1009,7 @@ exports[`props validation validate simple types 12`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1026,7 +1026,7 @@ exports[`props validation validate simple types 13`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1043,7 +1043,7 @@ exports[`props validation validate simple types 14`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1073,7 +1073,7 @@ exports[`props validation validate simple types 16`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1090,7 +1090,7 @@ exports[`props validation validate simple types 17`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1107,7 +1107,7 @@ exports[`props validation validate simple types 18`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1137,7 +1137,7 @@ exports[`props validation validate simple types 20`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1154,7 +1154,7 @@ exports[`props validation validate simple types 21`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1171,7 +1171,7 @@ exports[`props validation validate simple types 22`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1201,7 +1201,7 @@ exports[`props validation validate simple types 24`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1218,7 +1218,7 @@ exports[`props validation validate simple types, alternate form 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1235,7 +1235,7 @@ exports[`props validation validate simple types, alternate form 2`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1265,7 +1265,7 @@ exports[`props validation validate simple types, alternate form 4`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1282,7 +1282,7 @@ exports[`props validation validate simple types, alternate form 5`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1299,7 +1299,7 @@ exports[`props validation validate simple types, alternate form 6`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1329,7 +1329,7 @@ exports[`props validation validate simple types, alternate form 8`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1346,7 +1346,7 @@ exports[`props validation validate simple types, alternate form 9`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1363,7 +1363,7 @@ exports[`props validation validate simple types, alternate form 10`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1393,7 +1393,7 @@ exports[`props validation validate simple types, alternate form 12`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1410,7 +1410,7 @@ exports[`props validation validate simple types, alternate form 13`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1427,7 +1427,7 @@ exports[`props validation validate simple types, alternate form 14`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1457,7 +1457,7 @@ exports[`props validation validate simple types, alternate form 16`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1474,7 +1474,7 @@ exports[`props validation validate simple types, alternate form 17`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1491,7 +1491,7 @@ exports[`props validation validate simple types, alternate form 18`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1521,7 +1521,7 @@ exports[`props validation validate simple types, alternate form 20`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1538,7 +1538,7 @@ exports[`props validation validate simple types, alternate form 21`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1555,7 +1555,7 @@ exports[`props validation validate simple types, alternate form 22`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1585,7 +1585,7 @@ exports[`props validation validate simple types, alternate form 24`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {p: ctx['p']}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } @@ -1602,7 +1602,7 @@ exports[`props validation validation is only done in dev mode 1`] = ` return function template(ctx, node, key = \\"\\") { const props1 = {}; - helpers.validateProps(\`SubComp\`, props1, ctx); + helpers.validateProps(\`SubComp\`, props1, node); const b2 = comp1(props1, key + \`__1\`, node, this, null); return block1([], [b2]); } diff --git a/tests/components/__snapshots__/t_call.test.ts.snap b/tests/components/__snapshots__/t_call.test.ts.snap index aa4521d2..7dc6078f 100644 --- a/tests/components/__snapshots__/t_call.test.ts.snap +++ b/tests/components/__snapshots__/t_call.test.ts.snap @@ -444,6 +444,51 @@ exports[`t-call t-call with t-call-context and subcomponent 3`] = ` }" `; +exports[`t-call t-call with t-call-context and subcomponent, in dev mode 1`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + const callTemplate_1 = app.getTemplate(\`someTemplate\`); + + return function template(ctx, node, key = \\"\\") { + let ctx1 = ctx['subctx']; + return callTemplate_1.call(this, ctx1, node, key + \`__1\`); + } +}" +`; + +exports[`t-call t-call with t-call-context and subcomponent, in dev mode 2`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + const comp1 = app.createComponent(\`Child\`, true, false, false, false); + const comp2 = app.createComponent(\`Child\`, true, false, false, false); + + return function template(ctx, node, key = \\"\\") { + const props1 = {name: ctx['aab']}; + helpers.validateProps(\`Child\`, props1, node); + const b2 = comp1(props1, key + \`__1\`, node, this, null); + const props2 = {name: ctx['lpe']}; + helpers.validateProps(\`Child\`, props2, node); + const b3 = comp2(props2, key + \`__2\`, node, this, null); + return multi([b2, b3]); + } +}" +`; + +exports[`t-call t-call with t-call-context and subcomponent, in dev mode 3`] = ` +"function anonymous(app, bdom, helpers +) { + let { text, createBlock, list, multi, html, toggler, comment } = bdom; + + return function template(ctx, node, key = \\"\\") { + const b2 = text(\`child\`); + const b3 = text(ctx['props'].name); + return multi([b2, b3]); + } +}" +`; + exports[`t-call t-call with t-call-context, simple use 1`] = ` "function anonymous(app, bdom, helpers ) { diff --git a/tests/components/__snapshots__/t_foreach.test.ts.snap b/tests/components/__snapshots__/t_foreach.test.ts.snap index fecb2dfe..9e8ef827 100644 --- a/tests/components/__snapshots__/t_foreach.test.ts.snap +++ b/tests/components/__snapshots__/t_foreach.test.ts.snap @@ -56,7 +56,7 @@ exports[`list of components crash on duplicate key in dev mode 1`] = ` if (keys1.has(key1)) { throw new OwlError(\`Got duplicate key in t-foreach: \${key1}\`)} keys1.add(key1); const props1 = {}; - helpers.validateProps(\`Child\`, props1, ctx); + helpers.validateProps(\`Child\`, props1, node); c_block1[i1] = withKey(comp1(props1, key + \`__1__\${key1}\`, node, this, null), key1); } return list(c_block1); diff --git a/tests/components/t_call.test.ts b/tests/components/t_call.test.ts index 4d5bd476..24801afe 100644 --- a/tests/components/t_call.test.ts +++ b/tests/components/t_call.test.ts @@ -287,4 +287,32 @@ describe("t-call", () => { }); expect(fixture.innerHTML).toBe("childaaronchildlucas"); }); + + test("t-call with t-call-context and subcomponent, in dev mode", async () => { + class Child extends Component { + static template = xml`child`; + static props = ["name"]; + } + + class Root extends Component { + static template = xml` + `; + + static components = { Child }; + + subctx = { aab: "aaron", lpe: "lucas" }; + } + + await mount(Root, fixture, { + dev: true, + templates: ` + + + + + + `, + }); + expect(fixture.innerHTML).toBe("childaaronchildlucas"); + }); });