mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] env: env is now frozen, useSubEnv does not affect user env
This commit is contained in:
+7
-4
@@ -6,9 +6,13 @@ import { TemplateSet } from "./template_set";
|
|||||||
|
|
||||||
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
|
// reimplement dev mode stuff see last change in 0f7a8289a6fb8387c3c1af41c6664b2a8448758f
|
||||||
|
|
||||||
|
export interface Env {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
dev?: boolean;
|
dev?: boolean;
|
||||||
env?: { [key: string]: any };
|
env?: Env;
|
||||||
translatableAttributes?: string[];
|
translatableAttributes?: string[];
|
||||||
translateFn?: (s: string) => string;
|
translateFn?: (s: string) => string;
|
||||||
}
|
}
|
||||||
@@ -21,7 +25,7 @@ See https://github.com/odoo/owl/blob/master/doc/reference/config.md#mode for mor
|
|||||||
export class App<T extends typeof Component = any> extends TemplateSet {
|
export class App<T extends typeof Component = any> extends TemplateSet {
|
||||||
Root: T;
|
Root: T;
|
||||||
props: any;
|
props: any;
|
||||||
env: any = {};
|
env: Env = Object.freeze({});
|
||||||
scheduler = new Scheduler(window.requestAnimationFrame.bind(window));
|
scheduler = new Scheduler(window.requestAnimationFrame.bind(window));
|
||||||
root: ComponentNode | null = null;
|
root: ComponentNode | null = null;
|
||||||
|
|
||||||
@@ -36,9 +40,8 @@ export class App<T extends typeof Component = any> extends TemplateSet {
|
|||||||
this.dev = config.dev;
|
this.dev = config.dev;
|
||||||
console.info(DEV_MSG);
|
console.info(DEV_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.env) {
|
if (config.env) {
|
||||||
this.env = config.env;
|
this.env = Object.freeze(Object.assign({}, config.env));
|
||||||
}
|
}
|
||||||
if (config.translateFn) {
|
if (config.translateFn) {
|
||||||
this.translateFn = config.translateFn;
|
this.translateFn = config.translateFn;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { Env } from "../app/app";
|
||||||
import type { ComponentNode } from "./component_node";
|
import type { ComponentNode } from "./component_node";
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@@ -9,10 +10,10 @@ export class Component {
|
|||||||
static style: string = "";
|
static style: string = "";
|
||||||
|
|
||||||
props: any;
|
props: any;
|
||||||
env: any;
|
env: Env;
|
||||||
__owl__: ComponentNode;
|
__owl__: ComponentNode;
|
||||||
|
|
||||||
constructor(props: any, env: any, node: ComponentNode) {
|
constructor(props: any, env: Env, node: ComponentNode) {
|
||||||
this.props = props;
|
this.props = props;
|
||||||
this.env = env;
|
this.env = env;
|
||||||
this.__owl__ = node;
|
this.__owl__ = node;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { App } from "../app/app";
|
import type { App, Env } from "../app/app";
|
||||||
import { BDom, VNode } from "../blockdom";
|
import { BDom, VNode } from "../blockdom";
|
||||||
import { Component } from "./component";
|
import { Component } from "./component";
|
||||||
import {
|
import {
|
||||||
@@ -83,6 +83,7 @@ export class ComponentNode<T extends typeof Component = any> implements VNode<Co
|
|||||||
renderFn: Function;
|
renderFn: Function;
|
||||||
parent: ComponentNode | null;
|
parent: ComponentNode | null;
|
||||||
level: number;
|
level: number;
|
||||||
|
childEnv: Env;
|
||||||
children: { [key: string]: ComponentNode } = Object.create(null);
|
children: { [key: string]: ComponentNode } = Object.create(null);
|
||||||
slots: any = {};
|
slots: any = {};
|
||||||
refs: any = {};
|
refs: any = {};
|
||||||
@@ -101,7 +102,9 @@ export class ComponentNode<T extends typeof Component = any> implements VNode<Co
|
|||||||
this.parent = parent || null;
|
this.parent = parent || null;
|
||||||
this.level = parent ? parent.level + 1 : 0;
|
this.level = parent ? parent.level + 1 : 0;
|
||||||
applyDefaultProps(props, C);
|
applyDefaultProps(props, C);
|
||||||
this.component = new C(props, app.env, this) as any;
|
const env = (parent && parent.childEnv) || app.env;
|
||||||
|
this.childEnv = env;
|
||||||
|
this.component = new C(props, env, this) as any;
|
||||||
this.renderFn = app.getTemplate(C.template).bind(this.component, this.component, this);
|
this.renderFn = app.getTemplate(C.template).bind(this.component, this.component, this);
|
||||||
if (C.style) {
|
if (C.style) {
|
||||||
applyStyles(C);
|
applyStyles(C);
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import type { Env } from "./app/app";
|
||||||
|
import { getCurrent } from "./component/component_node";
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// useRef
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of this hook is to allow components to get a reference to a sub
|
||||||
|
* html node or component.
|
||||||
|
*/
|
||||||
|
export function useRef<T extends HTMLElement = HTMLElement>(name: string): { el: T | null } {
|
||||||
|
const node = getCurrent()!;
|
||||||
|
return {
|
||||||
|
get el(): T | null {
|
||||||
|
return node.refs[name] || null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// useEnv and useSubEnv
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This hook is useful as a building block for some customized hooks, that may
|
||||||
|
* need a reference to the env of the component calling them.
|
||||||
|
*/
|
||||||
|
export function useEnv<E extends Env>(): E {
|
||||||
|
return getCurrent()!.component.env as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This hook is a simple way to let components use a sub environment. Note that
|
||||||
|
* like for all hooks, it is important that this is only called in the
|
||||||
|
* constructor method.
|
||||||
|
*/
|
||||||
|
export function useSubEnv(envExtension: Env) {
|
||||||
|
const node = getCurrent()!;
|
||||||
|
node.childEnv = Object.freeze(Object.assign({}, node.childEnv, envExtension));
|
||||||
|
}
|
||||||
+1
-3
@@ -31,11 +31,9 @@ export const blockDom = {
|
|||||||
html,
|
html,
|
||||||
};
|
};
|
||||||
|
|
||||||
// import { makeBlockClass } from "./_old_bdom/element";
|
|
||||||
import { App } from "./app/app";
|
import { App } from "./app/app";
|
||||||
import { Component } from "./component/component";
|
import { Component } from "./component/component";
|
||||||
import { getCurrent } from "./component/component_node";
|
import { getCurrent } from "./component/component_node";
|
||||||
// import { getCurrent } from "./b_node";
|
|
||||||
|
|
||||||
export { App, Component };
|
export { App, Component };
|
||||||
|
|
||||||
@@ -57,7 +55,7 @@ export { Portal } from "./misc/portal";
|
|||||||
export { Memo } from "./misc/memo";
|
export { Memo } from "./misc/memo";
|
||||||
export { css, xml } from "./tags";
|
export { css, xml } from "./tags";
|
||||||
export { useState } from "./reactivity";
|
export { useState } from "./reactivity";
|
||||||
export { useRef } from "./refs";
|
export { useRef, useEnv, useSubEnv } from "./hooks";
|
||||||
export const utils = { EventBus, whenReady, loadFile };
|
export const utils = { EventBus, whenReady, loadFile };
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
// -----------------------------------------------------------------------------
|
|
||||||
// useRef
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
import { getCurrent } from "./component/component_node";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The purpose of this hook is to allow components to get a reference to a sub
|
|
||||||
* html node or component.
|
|
||||||
*/
|
|
||||||
export function useRef<T extends HTMLElement = HTMLElement>(name: string): { el: T | null } {
|
|
||||||
const node = getCurrent()!;
|
|
||||||
return {
|
|
||||||
get el(): T | null {
|
|
||||||
return node.refs[name] || null;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1132,7 +1132,7 @@ exports[`rendering component again in next microtick 2`] = `
|
|||||||
let b2;
|
let b2;
|
||||||
const v1 = ctx['onClick'];
|
const v1 = ctx['onClick'];
|
||||||
let d1 = [v1, ctx];
|
let d1 = [v1, ctx];
|
||||||
if (ctx['env'].flag) {
|
if (ctx['env'].config.flag) {
|
||||||
b2 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
|
b2 = component(\`Child\`, {}, key + \`__2\`, node, ctx);
|
||||||
}
|
}
|
||||||
return block1([d1], [b2]);
|
return block1([d1], [b2]);
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ exports[`basics can select a sub widget 3`] = `
|
|||||||
|
|
||||||
return function template(ctx, node, key = \\"\\") {
|
return function template(ctx, node, key = \\"\\") {
|
||||||
let b2,b3;
|
let b2,b3;
|
||||||
if (ctx['env'].flag) {
|
if (ctx['env'].options.flag) {
|
||||||
b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
b2 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||||
}
|
}
|
||||||
if (!ctx['env'].flag) {
|
if (!ctx['env'].options.flag) {
|
||||||
b3 = component(\`OtherChild\`, {}, key + \`__2\`, node, ctx);
|
b3 = component(\`OtherChild\`, {}, key + \`__2\`, node, ctx);
|
||||||
}
|
}
|
||||||
return multi([b2, b3]);
|
return multi([b2, b3]);
|
||||||
|
|||||||
@@ -66,6 +66,21 @@ exports[`hooks can use onWillStart, onWillUpdateProps 2`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`hooks can use sub env 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 } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let d1 = ctx['env'].val;
|
||||||
|
return block1([d1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`hooks can use useComponent 1`] = `
|
exports[`hooks can use useComponent 1`] = `
|
||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
@@ -80,6 +95,21 @@ exports[`hooks can use useComponent 1`] = `
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`hooks can use useEnv 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 } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let d1 = ctx['env'].val;
|
||||||
|
return block1([d1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`hooks mounted callbacks should be called in reverse order from willUnmount callbacks 1`] = `
|
exports[`hooks mounted callbacks should be called in reverse order from willUnmount callbacks 1`] = `
|
||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
@@ -95,6 +125,35 @@ exports[`hooks mounted callbacks should be called in reverse order from willUnmo
|
|||||||
}"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`hooks parent and child env 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 } = helpers;
|
||||||
|
|
||||||
|
let block1 = createBlock(\`<div><block-text-0/></div>\`);
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let d1 = ctx['env'].val;
|
||||||
|
return block1([d1]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`hooks parent and child env 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 } = helpers;
|
||||||
|
|
||||||
|
return function template(ctx, node, key = \\"\\") {
|
||||||
|
let b2 = text(ctx['env'].val);
|
||||||
|
let b3 = component(\`Child\`, {}, key + \`__1\`, node, ctx);
|
||||||
|
return multi([b2, b3]);
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`hooks two different call to willPatch/patched should work 1`] = `
|
exports[`hooks two different call to willPatch/patched should work 1`] = `
|
||||||
"function anonymous(bdom, helpers
|
"function anonymous(bdom, helpers
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -587,7 +587,7 @@ test("rendering component again in next microtick", async () => {
|
|||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="onClick">Click</button>
|
<button t-on-click="onClick">Click</button>
|
||||||
<t t-if="env.flag"><Child/></t>
|
<t t-if="env.config.flag"><Child/></t>
|
||||||
</div>`;
|
</div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
|
|
||||||
@@ -595,14 +595,15 @@ test("rendering component again in next microtick", async () => {
|
|||||||
useLogLifecycle(steps);
|
useLogLifecycle(steps);
|
||||||
}
|
}
|
||||||
async onClick() {
|
async onClick() {
|
||||||
this.env.flag = true;
|
this.env.config.flag = true;
|
||||||
this.render();
|
this.render();
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await mount(Parent, fixture);
|
const env = { config: { flag: false } };
|
||||||
|
await new App(Parent).configure({ env }).mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div><button>Click</button></div>");
|
expect(fixture.innerHTML).toBe("<div><button>Click</button></div>");
|
||||||
fixture.querySelector("button")!.click();
|
fixture.querySelector("button")!.click();
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|||||||
@@ -8,17 +8,6 @@ beforeEach(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("env handling", () => {
|
describe("env handling", () => {
|
||||||
test("keeps a reference to env", async () => {
|
|
||||||
const env = {};
|
|
||||||
class Test extends Component {
|
|
||||||
static template = xml`<div/>`;
|
|
||||||
}
|
|
||||||
const app = new App(Test);
|
|
||||||
app.configure({ env });
|
|
||||||
const component = await app.mount(fixture);
|
|
||||||
expect(component.env).toBe(env);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("has an env by default", async () => {
|
test("has an env by default", async () => {
|
||||||
class Test extends Component {
|
class Test extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
@@ -27,8 +16,23 @@ describe("env handling", () => {
|
|||||||
expect(component.env).toEqual({});
|
expect(component.env).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("env is shallow frozen", async () => {
|
||||||
|
const env = { foo: 42, bar: { value: 42 } };
|
||||||
|
class Test extends Component {
|
||||||
|
static template = xml`<div/>`;
|
||||||
|
}
|
||||||
|
const component = await new App(Test).configure({ env }).mount(fixture);
|
||||||
|
expect(Object.isFrozen(component.env)).toBeTruthy();
|
||||||
|
expect(component.env).toEqual({ foo: 42, bar: { value: 42 } });
|
||||||
|
expect(() => {
|
||||||
|
component.env.foo = 23;
|
||||||
|
}).toThrow(/Cannot assign to read only property 'foo' of object/);
|
||||||
|
component.env.bar.value = 23;
|
||||||
|
expect(component.env).toEqual({ foo: 42, bar: { value: 23 } });
|
||||||
|
});
|
||||||
|
|
||||||
test("parent env is propagated to child components", async () => {
|
test("parent env is propagated to child components", async () => {
|
||||||
const env = {};
|
const env = { foo: 42, bar: { value: 42 } };
|
||||||
let child: any = null;
|
let child: any = null;
|
||||||
|
|
||||||
class Child extends Component {
|
class Child extends Component {
|
||||||
@@ -43,9 +47,7 @@ describe("env handling", () => {
|
|||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new App(Test);
|
await new App(Test).configure({ env }).mount(fixture);
|
||||||
app.configure({ env });
|
expect(child.env).toEqual(env);
|
||||||
await app.mount(fixture);
|
|
||||||
expect(child.env).toBe(env);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -58,19 +58,17 @@ describe("basics", () => {
|
|||||||
class Parent extends Component {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<t>
|
<t>
|
||||||
<t t-if="env.flag"><Child /></t>
|
<t t-if="env.options.flag"><Child /></t>
|
||||||
<t t-if="!env.flag"><OtherChild /></t>
|
<t t-if="!env.options.flag"><OtherChild /></t>
|
||||||
</t>
|
</t>
|
||||||
`;
|
`;
|
||||||
static components = { Child, OtherChild };
|
static components = { Child, OtherChild };
|
||||||
}
|
}
|
||||||
const env = { flag: true };
|
const env = { options: { flag: true } };
|
||||||
const app = new App(Parent);
|
const parent = await new App(Parent).configure({ env }).mount(fixture);
|
||||||
app.configure({ env });
|
|
||||||
const parent = await app.mount(fixture);
|
|
||||||
expect(fixture.innerHTML).toBe("<span>CHILD 1</span>");
|
expect(fixture.innerHTML).toBe("<span>CHILD 1</span>");
|
||||||
|
|
||||||
env.flag = false;
|
env.options.flag = false;
|
||||||
await parent.render();
|
await parent.render();
|
||||||
expect(fixture.innerHTML).toBe("<div>CHILD 2</div>");
|
expect(fixture.innerHTML).toBe("<div>CHILD 2</div>");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
useComponent,
|
useComponent,
|
||||||
|
useEnv,
|
||||||
|
useSubEnv,
|
||||||
onMounted,
|
onMounted,
|
||||||
onPatched,
|
onPatched,
|
||||||
onWillStart,
|
onWillStart,
|
||||||
@@ -12,7 +14,7 @@ import {
|
|||||||
onWillPatch,
|
onWillPatch,
|
||||||
xml,
|
xml,
|
||||||
onWillUnmount,
|
onWillUnmount,
|
||||||
} from "../../src";
|
} from "../../src/index";
|
||||||
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
|
import { makeTestFixture, nextTick, snapshotEverything } from "../helpers";
|
||||||
|
|
||||||
let fixture: HTMLElement;
|
let fixture: HTMLElement;
|
||||||
@@ -163,27 +165,30 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.skip("can use useEnv", async () => {
|
test("can use useEnv", async () => {
|
||||||
expect.assertions(2);
|
expect.assertions(3);
|
||||||
class Test extends Component {
|
class Test extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
setup() {
|
setup() {
|
||||||
//expect(useEnv()).toBe(this.env);
|
expect(useEnv()).toBe(this.env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await mount(Test, fixture);
|
const env = { val: 1 };
|
||||||
|
await new App(Test).configure({ env }).mount(fixture);
|
||||||
|
expect(fixture.innerHTML).toBe("<div>1</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
test.skip("can use sub env", async () => {
|
test("use sub env does not pollute user env", async () => {
|
||||||
class Test extends Component {
|
class Test extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
setup() {
|
setup() {
|
||||||
//useSubEnv({ val: 3 });
|
useSubEnv({ val2: 1 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const component = await mount(Test, fixture);
|
const env = { val: 3 };
|
||||||
|
const component = await new App(Test).configure({ env }).mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("<div>3</div>");
|
expect(fixture.innerHTML).toBe("<div>3</div>");
|
||||||
expect(component.env).not.toHaveProperty("val");
|
expect(component.env).not.toHaveProperty("val2");
|
||||||
expect(component.env).toHaveProperty("val");
|
expect(component.env).toHaveProperty("val");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -198,22 +203,20 @@ describe("hooks", () => {
|
|||||||
await mount(Test, fixture);
|
await mount(Test, fixture);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.skip("parent and child env", async () => {
|
test("parent and child env", async () => {
|
||||||
class Child extends Component {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
super() {
|
|
||||||
//useSubEnv({ val: 5 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component {
|
class Parent extends Component {
|
||||||
static template = xml`<t t-esc="env.val"/><Child/>`;
|
static template = xml`<t t-esc="env.val"/><Child/>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
setup() {
|
setup() {
|
||||||
//useSubEnv({ val: 3 });
|
useSubEnv({ val: 5 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mount(Parent, fixture);
|
const env = { val: 3 };
|
||||||
|
await new App(Parent).configure({ env }).mount(fixture);
|
||||||
expect(fixture.innerHTML).toBe("3<div>5</div>");
|
expect(fixture.innerHTML).toBe("3<div>5</div>");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user