From 9106c1906639de408e739146db6c96c3ad334d5e Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Mon, 14 Oct 2019 15:09:17 +0200 Subject: [PATCH] [IMP] component: simplify constructor API It now takes two arguments: parent (optional, only for non-root components) and props (optional). In the case of the root component, the env is taken from the config (config.defaultEnv). If it doesn't exists, the default env is created on the fly. Closes #306 --- src/component/component.ts | 32 +- src/config.ts | 23 +- tests/animations.test.ts | 14 +- tests/component/component.test.ts | 373 ++++++++++++----------- tests/component/props_validation.test.ts | 76 ++--- tests/context.test.ts | 26 +- tests/hooks.test.ts | 86 +++--- tests/misc/async_root.test.ts | 14 +- tests/router/link.test.ts | 6 +- tests/router/route_component.test.ts | 8 +- tests/store_hooks.test.ts | 48 +-- tools/benchmarks/owl-master/app.js | 4 +- tools/playground/app.js | 13 +- tools/playground/samples.js | 69 ++--- 14 files changed, 406 insertions(+), 386 deletions(-) diff --git a/src/component/component.ts b/src/component/component.ts index b283edf7..2a43c11d 100644 --- a/src/component/component.ts +++ b/src/component/component.ts @@ -1,6 +1,7 @@ import { Observer } from "../core/observer"; import { CompiledTemplate, QWeb } from "../qweb/index"; import { h, patch, VNode } from "../vdom/index"; +import { config } from "../config"; import "./directive"; import { Fiber } from "./fiber"; import "./props_validation"; @@ -106,25 +107,14 @@ export class Component { /** * Creates an instance of Component. * - * The root component of a component tree needs an environment: - * - * ```javascript - * const root = new RootComponent(env, props); - * ``` - * - * Every other component simply needs a reference to its parent: - * - * ```javascript - * const child = new SomeComponent(parent, props); - * ``` - * * Note that most of the time, only the root component needs to be created by * hand. Other components should be created automatically by the framework (with * the t-component directive in a template) */ - constructor(parent: Component | T, props?: Props) { - const defaultProps = (this.constructor).defaultProps; + constructor(parent?: Component, props?: Props) { Component.current = this; + + const defaultProps = (this.constructor).defaultProps; if (defaultProps) { props = this.__applyDefaultProps(props, defaultProps); } @@ -136,17 +126,18 @@ export class Component { if (QWeb.dev) { QWeb.utils.validateProps(this.constructor, this.props); } - let id: number = nextId++; + + const id: number = nextId++; + let depth; - let p: Component | null = null; - if (parent instanceof Component) { - p = parent; + if (parent) { this.env = parent.env; const __powl__ = parent.__owl__; __powl__.children[id] = this; depth = __powl__.depth + 1; } else { - this.env = parent; + // we are the root component + this.env = config.env as T; this.env.qweb.on("update", this, () => { if (this.__owl__.isMounted) { this.render(true); @@ -162,6 +153,7 @@ export class Component { }); depth = 0; } + const qweb = this.env.qweb; this.__owl__ = { @@ -171,7 +163,7 @@ export class Component { pvnode: null, isMounted: false, isDestroyed: false, - parent: p, + parent: parent || null, children: {}, cmap: {}, currentFiber: null, diff --git a/src/config.ts b/src/config.ts index 0c39c60c..9056a923 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,17 +1,20 @@ import { QWeb } from "./qweb/index"; +import { Env } from "./component/component"; /** * This file creates and exports the OWL 'config' object, with keys: * - 'mode': 'prod' or 'dev', + * - 'env': the environment to use in root components. */ interface Config { + env: Env; mode: string; } -const _config:Partial = {}; +export const config = {} as Config; -Object.defineProperty(_config, "mode", { +Object.defineProperty(config, "mode", { get() { return QWeb.dev ? "dev" : "prod"; }, @@ -28,4 +31,18 @@ Object.defineProperty(_config, "mode", { }, }); -export const config:Config = _config as Config; +let env:Env; +Object.defineProperty(config, "env", { + get() { + if (!env) { + env = {} as Env; + } + if (!env.qweb) { + env.qweb = new QWeb(); + } + return env; + }, + set(newEnv: Env) { + env = newEnv; + }, +}); diff --git a/tests/animations.test.ts b/tests/animations.test.ts index d6138955..2326f8aa 100644 --- a/tests/animations.test.ts +++ b/tests/animations.test.ts @@ -1,4 +1,5 @@ import { Component, Env } from "../src/component/component"; +import { config } from "../src/config"; import { QWeb } from "../src/qweb/index"; import { useState, useRef } from "../src/hooks"; import { @@ -29,6 +30,7 @@ let cssEl: HTMLElement; beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; qweb = new QWeb(); }); @@ -108,7 +110,7 @@ describe("animations", () => { class TestWidget extends Widget { state = useState({ hide: false }); } - const widget = new TestWidget(env); + const widget = new TestWidget(); // insert widget into the DOM let def = makeDeferred(); @@ -151,7 +153,7 @@ describe("animations", () => { state = useState({ hide: false }); span = useRef("span"); } - const widget = new TestWidget(env); + const widget = new TestWidget(); // insert widget into the DOM let def = makeDeferred(); @@ -180,7 +182,7 @@ describe("animations", () => { class Parent extends Widget { static components = { Child: Child }; } - const widget = new Parent(env); + const widget = new Parent(); let def = makeDeferred(); var spanNode; @@ -220,7 +222,7 @@ describe("animations", () => { static components = { Child: Child }; state = useState({ display: true }); } - const widget = new Parent(env); + const widget = new Parent(); let def = makeDeferred(); var spanNode; @@ -283,7 +285,7 @@ describe("animations", () => { } } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); let button = widget.el!.querySelector("button"); @@ -341,7 +343,7 @@ describe("animations", () => { } } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); let button = widget.el!.querySelector("button"); diff --git a/tests/component/component.test.ts b/tests/component/component.test.ts index 67c873b2..a0841f68 100644 --- a/tests/component/component.test.ts +++ b/tests/component/component.test.ts @@ -3,6 +3,7 @@ import { QWeb } from "../../src/qweb/qweb"; import { xml } from "../../src/tags"; import { useState, useRef } from "../../src/hooks"; import { EventBus } from "../../src/core/event_bus"; +import { config } from "../../src/config"; import { makeDeferred, makeTestFixture, @@ -35,6 +36,7 @@ beforeEach(() => { ); env.qweb.addTemplate("WidgetA", `
Hello
`); env.qweb.addTemplate("WidgetB", `
world
`); + config.env = env; }); afterEach(() => { @@ -71,12 +73,12 @@ class WidgetA extends Widget { describe("basic widget properties", () => { test("props is properly defined", async () => { - const widget = new Widget(env); + const widget = new Widget(); expect(widget.props).toEqual({}); }); test("has no el after creation", async () => { - const widget = new Widget(env); + const widget = new Widget(); expect(widget.el).toBe(null); }); @@ -84,7 +86,7 @@ describe("basic widget properties", () => { class SomeWidget extends Component { static template = xml`
content
`; } - const widget = new SomeWidget(env); + const widget = new SomeWidget(); widget.mount(fixture); await nextTick(); expect(fixture.innerHTML).toBe("
content
"); @@ -94,14 +96,14 @@ describe("basic widget properties", () => { expect.assertions(1); class SomeWidget extends Component {} try { - new SomeWidget(env); + new SomeWidget(); } catch (e) { expect(e.message).toBe('Could not find template for component "SomeWidget"'); } }); test("can be clicked on and updated", async () => { - const counter = new Counter(env); + const counter = new Counter(); counter.mount(fixture); await nextTick(); expect(fixture.innerHTML).toBe("
0
"); @@ -112,7 +114,7 @@ describe("basic widget properties", () => { }); test("cannot be clicked on and updated if not in DOM", async () => { - const counter = new Counter(env); + const counter = new Counter(); const target = document.createElement("div"); await counter.mount(target); expect(target.innerHTML).toBe("
0
"); @@ -129,7 +131,7 @@ describe("basic widget properties", () => {
world
`; } - const widget = new StyledWidget(env); + const widget = new StyledWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
world
`); }); @@ -152,7 +154,7 @@ describe("basic widget properties", () => { steps.push("patched"); } } - const widget = new TestW(env); + const widget = new TestW(); await widget.mount(fixture); expect(steps).toEqual(["__render", "mounted"]); }); @@ -181,7 +183,7 @@ describe("basic widget properties", () => { static components = { TestW }; static template = xml`
`; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -198,7 +200,7 @@ describe("basic widget properties", () => { static template = xml`
`; state = { drinks: 1 }; } - const widget = new TestW(env); + const widget = new TestW(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); @@ -211,12 +213,12 @@ describe("basic widget properties", () => { }); test("keeps a reference to env", async () => { - const widget = new Widget(env); + const widget = new Widget(); expect(widget.env).toBe(env); }); test("do not remove previously rendered dom if not necessary", async () => { - const widget = new Widget(env); + const widget = new Widget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
`); widget.el!.appendChild(document.createElement("span")); @@ -242,7 +244,7 @@ describe("basic widget properties", () => { static components = { Child }; } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
childchild
"); }); @@ -267,7 +269,7 @@ describe("basic widget properties", () => { state = { s: [{ blips: ["a1", "a2"] }, { blips: ["b1"] }] }; } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
a1
a2
b1
"); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); @@ -288,7 +290,7 @@ describe("basic widget properties", () => { static components = { Child }; } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
1
2
"); }); @@ -302,7 +304,7 @@ describe("lifecycle hooks", () => { willstart = true; } } - const widget = new HookWidget(env); + const widget = new HookWidget(); await widget.mount(fixture); expect(willstart).toBe(true); }); @@ -314,7 +316,7 @@ describe("lifecycle hooks", () => { mounted = true; } } - const widget = new HookWidget(env); + const widget = new HookWidget(); const target = document.createElement("div"); await widget.mount(target); expect(mounted).toBe(false); @@ -327,7 +329,7 @@ describe("lifecycle hooks", () => { mounted = true; } } - const widget = new HookWidget(env); + const widget = new HookWidget(); await widget.mount(fixture); expect(mounted).toBe(true); }); @@ -344,7 +346,7 @@ describe("lifecycle hooks", () => { static template = xml`
`; static components = { child: ChildWidget }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(ok).toBe(true); }); @@ -366,7 +368,7 @@ describe("lifecycle hooks", () => { steps.push("parent:mounted"); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual(["child:mounted", "parent:mounted"]); }); @@ -405,7 +407,7 @@ describe("lifecycle hooks", () => { steps.push("parent:willUnmount"); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual(["parent:mounted"]); widget.state.flag = true; @@ -457,7 +459,7 @@ describe("lifecycle hooks", () => { } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual([]); widget.state.n = 2; @@ -503,7 +505,7 @@ describe("lifecycle hooks", () => { state = useState({ ok: false }); static components = { child: ChildWidget }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual([]); widget.state.ok = true; @@ -529,7 +531,7 @@ describe("lifecycle hooks", () => { expect(this.el).toBeTruthy(); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); // wait for ParentWidget await nextTick(); // wait for ChildWidget }); @@ -562,7 +564,7 @@ describe("lifecycle hooks", () => { state = useState({ ok: true }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual(["init", "willstart", "mounted"]); widget.state.ok = false; @@ -598,7 +600,7 @@ describe("lifecycle hooks", () => { } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); widget.increment(); @@ -631,7 +633,7 @@ describe("lifecycle hooks", () => { class ParentWidget extends Widget { static template = xml`
`; static components = { child: ChildWidget }; - constructor(parent) { + constructor(parent?) { super(parent); steps.push("p init"); } @@ -646,7 +648,7 @@ describe("lifecycle hooks", () => { } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); widget.destroy(); expect(steps).toEqual([ @@ -675,7 +677,7 @@ describe("lifecycle hooks", () => { static components = { Child: HookWidget }; } env.qweb.addTemplate("HookWidget", ''); - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("1"); widget.state.n = 2; @@ -696,7 +698,7 @@ describe("lifecycle hooks", () => { n++; } } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(n).toBe(0); @@ -723,7 +725,7 @@ describe("lifecycle hooks", () => { static components = { Child: TestWidget }; } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(n).toBe(0); @@ -746,7 +748,7 @@ describe("lifecycle hooks", () => { state = useState({ val: 42 }); } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
42
"); widget.state.val = 123; @@ -782,7 +784,7 @@ describe("lifecycle hooks", () => { static components = { child: ChildWidget }; state = useState({ flag: false }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(created).toBe(false); expect(mounted).toBe(false); @@ -820,7 +822,7 @@ describe("lifecycle hooks", () => { } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(steps).toEqual([]); widget.state.n = 2; @@ -864,7 +866,7 @@ describe("lifecycle hooks", () => { state = useState({ n: 1, flag: true }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(env.qweb.templates[ParentWidget.template].fn.toString()).toMatchSnapshot(); @@ -880,7 +882,7 @@ describe("lifecycle hooks", () => { describe("destroy method", () => { test("destroy remove the widget from the DOM", async () => { - const widget = new Widget(env); + const widget = new Widget(); await widget.mount(fixture); expect(document.contains(widget.el)).toBe(true); widget.destroy(); @@ -890,7 +892,7 @@ describe("destroy method", () => { }); test("destroying a parent also destroys its children", async () => { - const parent = new WidgetA(env); + const parent = new WidgetA(); await parent.mount(fixture); const child = children(parent)[0]; @@ -901,7 +903,7 @@ describe("destroy method", () => { }); test("destroy remove the parent/children link", async () => { - const parent = new WidgetA(env); + const parent = new WidgetA(); await parent.mount(fixture); const child = children(parent)[0]; @@ -921,7 +923,7 @@ describe("destroy method", () => { } } expect(fixture.innerHTML).toBe(""); - const widget = new DelayedWidget(env); + const widget = new DelayedWidget(); widget.mount(fixture); expect(widget.__owl__.isMounted).toBe(false); expect(widget.__owl__.isDestroyed).toBe(false); @@ -977,7 +979,7 @@ describe("destroy method", () => { } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
"); fixture.querySelector("button")!.click(); @@ -988,7 +990,7 @@ describe("destroy method", () => { describe("composition", () => { test("a widget with a sub widget", async () => { - const widget = new WidgetA(env); + const widget = new WidgetA(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
Hello
world
"); expect(children(widget)[0].__owl__.parent).toBe(widget); @@ -998,7 +1000,7 @@ describe("composition", () => { QWeb.registerComponent("WidgetB", WidgetB); env.qweb.addTemplate("ParentWidget", `
`); class ParentWidget extends Widget {} - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
world
"); delete QWeb.components["WidgetB"]; @@ -1020,7 +1022,7 @@ describe("composition", () => { return this.state.child === "a" ? A : B; } } - const widget = new App(env); + const widget = new App(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("child a"); widget.state.child = "b"; @@ -1044,7 +1046,7 @@ describe("composition", () => { return this.state.child === "a" ? A : B; } } - const widget = new App(env); + const widget = new App(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("child a"); widget.state.child = "b"; @@ -1060,7 +1062,7 @@ describe("composition", () => { class ParentWidget extends Widget { static components = { WidgetB: AnotherWidgetB }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
Belgium
"); delete QWeb.components["WidgetB"]; @@ -1076,7 +1078,7 @@ describe("composition", () => { class P extends Widget { static components = { C }; } - const parent = new P(env); + const parent = new P(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); }); @@ -1089,7 +1091,7 @@ describe("composition", () => { class Parent extends Widget { static components = { SomeWidget: Widget }; } - const parent = new Parent(env); + const parent = new Parent(); let error; try { await parent.mount(fixture); @@ -1109,7 +1111,7 @@ describe("composition", () => { widget = useRef("mywidgetb"); } - const widget = new WidgetC(env); + const widget = new WidgetC(); await widget.mount(fixture); expect(widget.widget.comp).toBeInstanceOf(WidgetB); }); @@ -1133,7 +1135,7 @@ describe("composition", () => { } } - const parent = new ParentWidget(env); + const parent = new ParentWidget(); await parent.mount(fixture); parent.state.list.push(1); await nextTick(); @@ -1182,7 +1184,7 @@ describe("composition", () => { } } - const parent = new ParentWidget(env); + const parent = new ParentWidget(); await parent.mount(fixture); parent.state.child2 = true; await nextTick(); @@ -1195,7 +1197,7 @@ describe("composition", () => { class ParentWidget extends Widget { static components = { Counter }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); const button = fixture.getElementsByTagName("button")[0]; @@ -1221,7 +1223,7 @@ describe("composition", () => { elem4 = useRef("4"); state = useState({ items: [1, 2, 3] }); } - const parent = new ParentWidget(env); + const parent = new ParentWidget(); await parent.mount(fixture); expect(parent.elem1.comp).toBeDefined(); expect(parent.elem2.comp).toBeDefined(); @@ -1230,7 +1232,7 @@ describe("composition", () => { }); test("parent's elm for a children === children's elm, even after rerender", async () => { - const widget = new WidgetA(env); + const widget = new WidgetA(); await widget.mount(fixture); expect((widget.__owl__.vnode!.children![1]).elm).toBe( @@ -1243,7 +1245,7 @@ describe("composition", () => { }); test("parent env is propagated to child components", async () => { - const widget = new WidgetA(env); + const widget = new WidgetA(); await widget.mount(fixture); expect(children(widget)[0].env).toBe(env); @@ -1254,7 +1256,7 @@ describe("composition", () => { class ParentWidget extends Widget { static components = { Counter }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const button = fixture.getElementsByTagName("button")[0]; await button.click(); @@ -1270,7 +1272,7 @@ describe("composition", () => { state = useState({ ok: true }); static components = { Counter }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const button = fixture.getElementsByTagName("button")[0]; await button.click(); @@ -1294,7 +1296,7 @@ describe("composition", () => { state = useState({ ok: true }); static components = { Counter }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const button = fixture.getElementsByTagName("button")[0]; await button.click(); @@ -1325,7 +1327,7 @@ describe("composition", () => { static components = { InputWidget }; } env.qweb.addTemplate("InputWidget", ""); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const input = fixture.getElementsByTagName("input")[0]; input.value = "test"; @@ -1356,7 +1358,7 @@ describe("composition", () => { state = useState({ ok: true }); child = useRef("child"); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; @@ -1395,7 +1397,7 @@ describe("composition", () => { }); static components = { ChildWidget }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(normalize(fixture.innerHTML)).toBe( normalize(` @@ -1435,7 +1437,7 @@ describe("composition", () => { }); static components = { ChildWidget }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); parent.state.numbers = [1, 3]; await nextTick(); @@ -1467,7 +1469,7 @@ describe("composition", () => { static components = { ChildWidget }; state = useState({ flag: false }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); const child = children(parent)[0]; expect(normalize(fixture.innerHTML)).toBe( @@ -1513,7 +1515,7 @@ describe("composition", () => { static components = { SubWidget }; state = useState({ blips: [{ a: "a", id: 1 }, { b: "b", id: 2 }, { c: "c", id: 4 }] }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe( "
asdf
asdf
asdf
" @@ -1545,7 +1547,7 @@ describe("composition", () => { static components = { SubWidget }; state = useState({ blips: [{ a: "a", id: 1 }] }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
asdfasdf
"); }); @@ -1556,7 +1558,7 @@ describe("composition", () => { static components = { WidgetB }; state = useState({ widget: "WidgetB" }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
world
"); expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot(); @@ -1568,7 +1570,7 @@ describe("composition", () => { static components = { WidgetB }; state = useState({ widget: "B" }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
world
"); expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot(); @@ -1597,7 +1599,7 @@ describe("composition", () => { }); static components = { ChildWidget }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(normalize(fixture.innerHTML)).toBe( "
123
" @@ -1630,7 +1632,7 @@ describe("props evaluation ", () => { env.qweb.addTemplate("Child", ``); - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
42
"); }); @@ -1646,7 +1648,7 @@ describe("props evaluation ", () => { return `hello ${this.props.name}`; } } - const widget = new Parent(env, { name: "aaron" }); + const widget = new Parent(undefined, { name: "aaron" }); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
hello aaron
"); }); @@ -1672,7 +1674,7 @@ describe("props evaluation ", () => { ` ); - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(normalize(fixture.innerHTML)).toBe("
42
"); }); @@ -1687,7 +1689,7 @@ describe("class and style attributes with t-component", () => { static template = xml`
`; static components = { Child }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
`); }); @@ -1701,7 +1703,7 @@ describe("class and style attributes with t-component", () => { static components = { Child }; state = useState({ a: true, b: false }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
`); expect(QWeb.TEMPLATES[ParentWidget.template].fn.toString()); @@ -1724,7 +1726,7 @@ describe("class and style attributes with t-component", () => { static components = { Child }; } env.qweb.addTemplate("Child", `
`); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
`); }); @@ -1746,7 +1748,7 @@ describe("class and style attributes with t-component", () => { state = useState({ b: true }); child = useRef("child"); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const span = fixture.querySelector("span")!; @@ -1788,7 +1790,7 @@ describe("class and style attributes with t-component", () => { state = useState({ b: true }); child = useRef("child"); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const span = fixture.querySelector("span")!; @@ -1826,7 +1828,7 @@ describe("class and style attributes with t-component", () => { } } - const widget = new App(env); + const widget = new App(); await widget.mount(fixture); expect(fixture.innerHTML).toBe('
'); @@ -1848,7 +1850,7 @@ describe("class and style attributes with t-component", () => { class ParentWidget extends Widget { static components = { child: Widget }; } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe(`
`); }); @@ -1865,7 +1867,7 @@ describe("class and style attributes with t-component", () => { static components = { child: Widget }; state = useState({ style: "font-size: 20px" }); } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot(); @@ -1896,7 +1898,7 @@ describe("other directives with t-component", () => { this.n++; } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; expect(widget.n).toBe(0); @@ -1922,7 +1924,7 @@ describe("other directives with t-component", () => { expect(ev.detail).toBe(43); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; child.trigger("ev", 43); @@ -1944,7 +1946,7 @@ describe("other directives with t-component", () => { expect(ev.detail).toBe(43); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; child.trigger("ev", 43); @@ -1966,7 +1968,7 @@ describe("other directives with t-component", () => { expect(ev.detail).toBe(43); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; child.trigger("ev", 43); @@ -1988,7 +1990,7 @@ describe("other directives with t-component", () => { expect(ev.detail).toBe(43); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); let child = children(widget)[0]; child.trigger("ev", 43); @@ -2023,7 +2025,7 @@ describe("other directives with t-component", () => { expect(ev.cancelBubble).toBe(true); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const child = children(widget)[0]; @@ -2056,7 +2058,7 @@ describe("other directives with t-component", () => { steps.push("onEv2"); } } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); const child = children(widget)[0]; @@ -2088,7 +2090,7 @@ describe("other directives with t-component", () => { static components = { child: Child }; onEv() {} } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); (fixture).addEventListener("ev", function(e) { steps.push(e.defaultPrevented); @@ -2120,7 +2122,7 @@ describe("other directives with t-component", () => { static components = { Child }; onEv() {} } - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); (fixture).addEventListener("ev", function(e) { steps.push(e.defaultPrevented); @@ -2151,7 +2153,7 @@ describe("other directives with t-component", () => { return () => {}; } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); @@ -2176,7 +2178,7 @@ describe("other directives with t-component", () => { static components = { Child }; state = useState({ counter: 0 }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); @@ -2204,7 +2206,7 @@ describe("other directives with t-component", () => { expect(ev.defaultPrevented).toBe(true); } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); let componentB = children(children(parent)[0])[0]; @@ -2222,7 +2224,7 @@ describe("other directives with t-component", () => { } env.qweb.addTemplate("Child", "hey"); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); @@ -2252,7 +2254,7 @@ describe("other directives with t-component", () => { } env.qweb.addTemplate("Child", "hey"); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(normalize(fixture.innerHTML)).toBe("
somediv
"); @@ -2278,7 +2280,7 @@ describe("other directives with t-component", () => { } env.qweb.addTemplate("Child", "hey"); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(normalize(fixture.innerHTML)).toBe("
somediv
"); @@ -2304,7 +2306,7 @@ describe("other directives with t-component", () => { } env.qweb.addTemplate("Child", "hey"); - const widget = new ParentWidget(env); + const widget = new ParentWidget(); await widget.mount(fixture); expect(normalize(fixture.innerHTML)).toBe("
somediv
"); @@ -2327,7 +2329,7 @@ describe("random stuff/miscellaneous", () => { class Test extends Widget { static components = { widget: Widget }; } - const widget = new Test(env); + const widget = new Test(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
txttxt
"); }); @@ -2354,7 +2356,7 @@ describe("random stuff/miscellaneous", () => { } } - const widget = new ParentWidget(env, { items }); + const widget = new ParentWidget(undefined, { items }); await widget.mount(fixture); children(widget)[0].trigger("ev", 43); expect(env.qweb.templates.ParentWidget.fn.toString()).toMatchSnapshot(); @@ -2373,7 +2375,7 @@ describe("random stuff/miscellaneous", () => { env.qweb.addTemplate("Child", `abcdef`); - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
abc
"); widget.state.flag = true; @@ -2394,7 +2396,7 @@ describe("random stuff/miscellaneous", () => { env.qweb.addTemplate("Child", `abcdef`); - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot(); }); @@ -2498,7 +2500,7 @@ describe("random stuff/miscellaneous", () => { name = "A"; } - const a = new A(env); + const a = new A(); await a.mount(fixture); expect(fixture.innerHTML).toBe(`
A
B
C
D
E
`); expect(steps).toEqual([ @@ -2559,7 +2561,7 @@ describe("random stuff/miscellaneous", () => { state = useState({ n: 42 }); } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot(); expect(fixture.innerHTML).toBe("
42
"); @@ -2574,7 +2576,7 @@ describe("async rendering", () => { return def; } } - const w = new W(env); + const w = new W(); w.mount(fixture); expect(w.__owl__.isDestroyed).toBe(false); expect(w.__owl__.isMounted).toBe(false); @@ -2604,7 +2606,7 @@ describe("async rendering", () => { state = useState({ val: 1 }); } - const w = new W(env); + const w = new W(); await w.mount(fixture); expect(n).toBe(0); w.state.val = 2; @@ -2651,7 +2653,7 @@ describe("async rendering", () => { static components = { ChildA, ChildB }; state = useState({ flagA: false, flagB: false }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
"); parent.state.flagA = true; @@ -2696,7 +2698,7 @@ describe("async rendering", () => { static components = { ChildA, ChildB }; state = useState({ valA: 1, valB: 2, flagB: false }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
a1
"); parent.state.valA = 2; @@ -2739,7 +2741,7 @@ describe("async rendering", () => { static components = { ChildA, ChildB }; state = useState({ valA: 1, valB: 2, flagB: false }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
a1
"); parent.state.valA = 2; @@ -2774,7 +2776,7 @@ describe("async rendering", () => { static components = { ChildA }; state = useState({ valA: 1 }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); parent.state.valA = 2; @@ -2809,7 +2811,7 @@ describe("async rendering", () => { static components = { ChildA }; state = useState({ valA: 1 }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); parent.state.valA = 2; @@ -2853,7 +2855,7 @@ describe("async rendering", () => {
`); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe( "
  • 1
  • 2
" @@ -2885,7 +2887,7 @@ describe("async rendering", () => { static components = { Child }; state = useState({ flag: true, val: "Framboise Lindemans" }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -2938,7 +2940,7 @@ describe("async rendering", () => { static components = { ChildA, ChildB }; state = useState({ valA: 1, valB: 2, flag: false }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(destroyCount).toBe(0); @@ -2973,7 +2975,7 @@ describe("async rendering", () => { } } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
"); fixture.querySelector("button")!.click(); @@ -3013,7 +3015,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1b

"); @@ -3065,7 +3067,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
1

1b

"); @@ -3115,7 +3117,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1b

"); @@ -3179,7 +3181,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1c

"); @@ -3249,7 +3251,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1c

"); @@ -3298,7 +3300,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1

"); @@ -3343,7 +3345,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1

"); @@ -3386,7 +3388,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1b

"); @@ -3419,7 +3421,7 @@ describe("async rendering", () => { state = useState({ fromA: 1 }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1b

"); @@ -3482,7 +3484,7 @@ describe("async rendering", () => { state = useState({ fromA: "a1" }); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
a1a1

a1b1

"); @@ -3507,7 +3509,7 @@ describe("widget and observable state", () => { static template = xml`
`; state = useState({ drink: "water" }); } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
water
"); @@ -3531,7 +3533,7 @@ describe("widget and observable state", () => { state = useState({ obj: { coffee: 1 } }); static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); let error; try { await parent.mount(fixture); @@ -3549,7 +3551,7 @@ describe("can deduce template from name", () => { test("can find template if name of component", async () => { class ABC extends Widget {} env.qweb.addTemplate("ABC", "Orval"); - const abc = new ABC(env); + const abc = new ABC(); await abc.mount(fixture); expect(fixture.innerHTML).toBe("Orval"); }); @@ -3558,7 +3560,7 @@ describe("can deduce template from name", () => { class ABC extends Widget {} class DEF extends ABC {} env.qweb.addTemplate("ABC", "Orval"); - const def = new DEF(env); + const def = new DEF(); await def.mount(fixture); expect(fixture.innerHTML).toBe("Orval"); }); @@ -3569,7 +3571,7 @@ describe("can deduce template from name", () => { } class DEF extends ABC {} env.qweb.addTemplate("Achel", "Orval"); - const def = new DEF(env); + const def = new DEF(); await def.mount(fixture); expect(fixture.innerHTML).toBe("Orval"); }); @@ -3579,11 +3581,12 @@ describe("can deduce template from name", () => { env.qweb.addTemplate("ABC", "Rochefort 8"); env2.qweb.addTemplate("ABC", "Rochefort 10"); class ABC extends Widget {} - const abc = new ABC(env); + const abc = new ABC(); await abc.mount(fixture); expect(fixture.innerHTML).toBe("Rochefort 8"); abc.destroy(); - const abc2 = new ABC(env2); + config.env = env2; + const abc2 = new ABC(); await abc2.mount(fixture); expect(fixture.innerHTML).toBe("Rochefort 10"); }); @@ -3609,7 +3612,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe( @@ -3641,7 +3644,7 @@ describe("t-slot directive", () => { this.state.val++; } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe( @@ -3677,7 +3680,7 @@ describe("t-slot directive", () => { static components = { Link }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe( @@ -3716,7 +3719,7 @@ describe("t-slot directive", () => { static components = { Link }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe( @@ -3753,7 +3756,7 @@ describe("t-slot directive", () => { static components = { Link }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe(''); @@ -3787,7 +3790,7 @@ describe("t-slot directive", () => { this.state.val++; } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe( @@ -3818,7 +3821,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
sts rocks
"); @@ -3838,7 +3841,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
sts rocks
"); @@ -3863,7 +3866,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
stsrocks
"); @@ -3886,7 +3889,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
stsrocks
"); @@ -3910,7 +3913,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
some content
"); @@ -3934,7 +3937,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Dialog }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(console.log).toHaveBeenCalledTimes(0); console.log = consoleLog; @@ -3957,7 +3960,7 @@ describe("t-slot directive", () => { class Parent extends Widget { static components = { Child, GrandChild }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
Grand Child
"); @@ -4001,7 +4004,7 @@ describe("t-slot directive", () => { this.state.val++; } } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
SC:4
"); @@ -4023,7 +4026,7 @@ describe("t-slot directive", () => { static components = { Link: Link }; } - const a = new A(env); + const a = new A(); await a.mount(fixture); expect(fixture.innerHTML).toBe(`hey`); @@ -4045,7 +4048,7 @@ describe("t-slot directive", () => { static components = { SlotComponent, Child }; state = useState({ value: 3 }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
3
"); @@ -4067,7 +4070,7 @@ describe("t-model directive", () => { `; state = useState({ text: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -4090,7 +4093,7 @@ describe("t-model directive", () => { class SomeComponent extends Widget { some = useState({ text: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -4116,7 +4119,7 @@ describe("t-model directive", () => { class SomeComponent extends Widget { state = useState({ flag: false }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe('
no
'); @@ -4144,7 +4147,7 @@ describe("t-model directive", () => { class SomeComponent extends Widget { state = useState({ text: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -4167,7 +4170,7 @@ describe("t-model directive", () => { class SomeComponent extends Widget { state = useState({ choice: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe( @@ -4207,7 +4210,7 @@ describe("t-model directive", () => { class SomeComponent extends Widget { state = useState({ color: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe( @@ -4240,7 +4243,7 @@ describe("t-model directive", () => { `; state = useState({ color: "red" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); const select = fixture.querySelector("select")!; expect(select.value).toBe("red"); @@ -4256,7 +4259,7 @@ describe("t-model directive", () => { `; state = useState({ something: { text: "" } }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -4278,7 +4281,7 @@ describe("t-model directive", () => { `; state = useState({ text: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -4306,7 +4309,7 @@ describe("t-model directive", () => { `; state = useState({ text: "" }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); const input = fixture.querySelector("input")!; @@ -4325,7 +4328,7 @@ describe("t-model directive", () => { `; state = useState({ number: 0 }); } - const comp = new SomeComponent(env); + const comp = new SomeComponent(); await comp.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); @@ -4364,7 +4367,7 @@ describe("environment and plugins", () => { `; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
Red
"); @@ -4413,7 +4416,7 @@ describe("component error handling (catchError)", () => { state = useState({ flag: false }); static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); app.state.flag = true; @@ -4450,7 +4453,7 @@ describe("component error handling (catchError)", () => { } } } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); app.state.flag = true; @@ -4492,7 +4495,7 @@ describe("component error handling (catchError)", () => { `; static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); await nextTick(); await nextTick(); @@ -4536,7 +4539,7 @@ describe("component error handling (catchError)", () => { class App extends Widget { static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); await nextTick(); await nextTick(); @@ -4575,7 +4578,7 @@ describe("component error handling (catchError)", () => { static template = xml`
`; static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); await nextTick(); await nextTick(); @@ -4615,7 +4618,7 @@ describe("component error handling (catchError)", () => { class App extends Widget { static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); await nextTick(); await nextTick(); @@ -4654,7 +4657,7 @@ describe("component error handling (catchError)", () => { state = useState({ message: "abc" }); static components = { ErrorBoundary, ErrorComponent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
abc
abc
"); app.state.message = "def"; @@ -4674,7 +4677,7 @@ describe("component error handling (catchError)", () => { static template = xml`
`; } - const app = new App(env); + const app = new App(); let error; try { await app.mount(fixture); @@ -4700,7 +4703,7 @@ describe("component error handling (catchError)", () => { static components = { Child }; } - const app = new App(env); + const app = new App(); let error; try { await app.mount(fixture); @@ -4723,7 +4726,7 @@ describe("component error handling (catchError)", () => { flag = false; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
"); app.flag = true; @@ -4751,7 +4754,7 @@ describe("component error handling (catchError)", () => { let error; try { - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); } catch (e) { error = e; @@ -4774,7 +4777,7 @@ describe("top level sub widgets", () => { class Parent extends Widget { static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("child1"); expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot(); @@ -4797,7 +4800,7 @@ describe("top level sub widgets", () => { class Parent extends Widget { static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("child1"); const button = fixture.querySelector("button")!; @@ -4823,12 +4826,12 @@ describe("top level sub widgets", () => { static components = { Child, OtherChild }; } (env).flag = true; - let parent = new Parent(env); + let parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("CHILD 1"); parent.destroy(); (env).flag = false; - parent = new Parent(env); + parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
CHILD 2
"); @@ -4852,7 +4855,7 @@ describe("top level sub widgets", () => { state = useState({ flag: true }); static components = { Child, OtherChild }; } - let parent = new Parent(env); + let parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("CHILD 1"); parent.state.flag = false; @@ -4873,7 +4876,7 @@ describe("top level sub widgets", () => { static components = { ComponentB }; } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
Hello
"); @@ -4899,7 +4902,7 @@ describe("unmounting and remounting", () => { } } - const w = new MyWidget(env); + const w = new MyWidget(); await w.mount(fixture); expect(fixture.innerHTML).toBe("
Hey
"); expect(steps).toEqual(["willstart", "mounted"]); @@ -4928,7 +4931,7 @@ describe("unmounting and remounting", () => { } } - const w = new MyWidget(env); + const w = new MyWidget(); await w.mount(fixture); await w.mount(fixture); expect(fixture.innerHTML).toBe("
Hey
"); @@ -4969,7 +4972,7 @@ describe("unmounting and remounting", () => { state = useState({ val: 1, flag: true }); } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(steps).toEqual(["render"]); expect(fixture.innerHTML).toBe("
12
"); @@ -4990,7 +4993,7 @@ describe("unmounting and remounting", () => { } } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); widget.unmount(); @@ -5014,7 +5017,7 @@ describe("dynamic root nodes", () => { `; } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("hey"); @@ -5030,7 +5033,7 @@ describe("dynamic root nodes", () => { `; } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
abc
"); @@ -5047,7 +5050,7 @@ describe("dynamic root nodes", () => { state = useState({ flag: true }); } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("hey"); @@ -5075,7 +5078,7 @@ describe("dynamic root nodes", () => { state = useState({ flag: true }); } - const widget = new TestWidget(env); + const widget = new TestWidget(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("hey"); @@ -5113,7 +5116,7 @@ describe("dynamic t-props", () => { some = { obj: { a: 1, b: 2 } }; } - const widget = new Parent(env); + const widget = new Parent(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
3
"); @@ -5137,7 +5140,7 @@ describe("support svg components", () => { `; static components = { GComp }; } - const widget = new Svg(env); + const widget = new Svg(); await widget.mount(fixture); expect(fixture.innerHTML).toBe( @@ -5152,7 +5155,7 @@ describe("t-raw in components", () => { static template = xml`
`; state = useState({ value: "content" }); } - const widget = new TestW(env); + const widget = new TestW(); await widget.mount(fixture); expect(fixture.innerHTML).toBe("
content
"); @@ -5173,7 +5176,7 @@ describe("t-raw in components", () => { `; state = useState({ items: ["one", "two", "tree"] }); } - const widget = new TestW(env); + const widget = new TestW(); await widget.mount(fixture); expect(fixture.innerHTML).toBe( diff --git a/tests/component/props_validation.test.ts b/tests/component/props_validation.test.ts index 15237b8a..efe17ea8 100644 --- a/tests/component/props_validation.test.ts +++ b/tests/component/props_validation.test.ts @@ -1,6 +1,7 @@ import { Component, Env } from "../../src/component/component"; import { makeTestFixture, makeTestEnv, nextTick } from "../helpers"; import { useState } from "../../src/hooks"; +import { config } from "../../src/config"; import { QWeb } from "../../src/qweb"; import { xml } from "../../src/tags"; @@ -15,6 +16,7 @@ let dev: boolean = false; beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; dev = QWeb.dev; QWeb.dev = true; }); @@ -38,13 +40,13 @@ describe("props validation", () => { QWeb.dev = true; expect(() => { - new TestWidget(env); + new TestWidget(); }).toThrow(); QWeb.dev = false; expect(() => { - new TestWidget(env); + new TestWidget(); }).not.toThrow(); }); @@ -55,7 +57,7 @@ describe("props validation", () => { } expect(() => { - new TestWidget(env); + new TestWidget(); }).toThrow("Missing props 'message' (component 'TestWidget')"); }); @@ -76,15 +78,15 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env); + new TestWidget(); }).toThrow("Missing props 'p'"); expect(() => { - new TestWidget(env, { p: test.ok }); + new TestWidget(undefined, { p: test.ok }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: test.ko }); + new TestWidget(undefined, { p: test.ko }); }).toThrow("Props 'p' of invalid type in component"); } }); @@ -106,15 +108,15 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env); + new TestWidget(); }).toThrow("Missing props 'p'"); expect(() => { - new TestWidget(env, { p: test.ok }); + new TestWidget(undefined, { p: test.ok }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: test.ko }); + new TestWidget(undefined, { p: test.ko }); }).toThrow("Props 'p' of invalid type in component"); } }); @@ -126,12 +128,12 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: "string" }); - new TestWidget(env, { p: true }); + new TestWidget(undefined, { p: "string" }); + new TestWidget(undefined, { p: true }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: 1 }); + new TestWidget(undefined, { p: 1 }); }).toThrow("Props 'p' of invalid type in component"); }); @@ -142,12 +144,12 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: "hey" }); - new TestWidget(env, {}); + new TestWidget(undefined, { p: "hey" }); + new TestWidget(undefined, {}); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: 1 }); + new TestWidget(undefined, { p: 1 }); }).toThrow(); }); @@ -158,16 +160,16 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: [] }); - new TestWidget(env, { p: ["string"] }); + new TestWidget(undefined, { p: [] }); + new TestWidget(undefined, { p: ["string"] }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: [1] }); + new TestWidget(undefined, { p: [1] }); }).toThrow(); expect(() => { - new TestWidget(env, { p: ["string", 1] }); + new TestWidget(undefined, { p: ["string", 1] }); }).toThrow(); }); @@ -178,13 +180,13 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: [] }); - new TestWidget(env, { p: ["string"] }); - new TestWidget(env, { p: [false, true, "string"] }); + new TestWidget(undefined, { p: [] }); + new TestWidget(undefined, { p: ["string"] }); + new TestWidget(undefined, { p: [false, true, "string"] }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: [true, 1] }); + new TestWidget(undefined, { p: [true, 1] }); }).toThrow(); }); @@ -197,16 +199,16 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: { id: 1, url: "url" } }); - new TestWidget(env, { p: { id: 1, url: "url", extra: true } }); + new TestWidget(undefined, { p: { id: 1, url: "url" } }); + new TestWidget(undefined, { p: { id: 1, url: "url", extra: true } }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: { id: "1", url: "url" } }); + new TestWidget(undefined, { p: { id: "1", url: "url" } }); }).toThrow(); expect(() => { - new TestWidget(env, { p: { id: 1 } }); + new TestWidget(undefined, { p: { id: 1 } }); }).toThrow(); }); @@ -225,12 +227,12 @@ describe("props validation", () => { }; expect(() => { - new TestWidget(env, { p: { id: 1, url: true } }); - new TestWidget(env, { p: { id: 1, url: [12] } }); + new TestWidget(undefined, { p: { id: 1, url: true } }); + new TestWidget(undefined, { p: { id: 1, url: [12] } }); }).not.toThrow(); expect(() => { - new TestWidget(env, { p: { id: 1, url: [12, true] } }); + new TestWidget(undefined, { p: { id: 1, url: [12, true] } }); }).toThrow(); }); @@ -249,7 +251,7 @@ describe("props validation", () => { class App extends Widget { static components = { Child }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); // need to make sure there are 2 call to update props. one at component @@ -334,7 +336,7 @@ describe("props validation", () => { static components = { TestWidget }; } - const w = new App(env, {}); + const w = new App(undefined, {}); let error; try { await w.mount(fixture); @@ -365,7 +367,7 @@ describe("props validation", () => { state: any = useState({ p: 1 }); } - const w = new Parent(env); + const w = new Parent(); await w.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); @@ -387,7 +389,7 @@ describe("props validation", () => { state: any = useState({ p: 1 }); } - const w = new Parent(env); + const w = new Parent(); await w.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); @@ -404,7 +406,7 @@ describe("default props", () => { static template = xml`
hey
`; } - const w = new TestWidget(env, {}); + const w = new TestWidget(undefined, {}); expect(w.props.p).toBe(4); }); @@ -419,7 +421,7 @@ describe("default props", () => { state: any = useState({ p: 1 }); } - const w = new Parent(env); + const w = new Parent(); await w.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); @@ -440,7 +442,7 @@ describe("default props", () => { static components = { TestWidget }; } - const w = new App(env, {}); + const w = new App(undefined, {}); await w.mount(fixture); expect(fixture.innerHTML).toBe("
heyhey
"); }); diff --git a/tests/context.test.ts b/tests/context.test.ts index 6556ba7a..6e0e3460 100644 --- a/tests/context.test.ts +++ b/tests/context.test.ts @@ -1,6 +1,7 @@ import { makeDeferred, makeTestEnv, makeTestFixture, nextTick } from "./helpers"; -import { Component, Env } from "../src/component/component"; +import { Component } from "../src/component/component"; import { Context, useContext } from "../src/context"; +import { config } from "../src/config"; import { xml } from "../src/tags"; import { useState } from "../src/hooks"; @@ -11,14 +12,13 @@ import { useState } from "../src/hooks"; // We create before each test: // - fixture: a div, appended to the DOM, intended to be the target of dom // manipulations. Note that it is removed after each test. -// - env: a WEnv, necessary to create new components +// - a test env, necessary to create components, that is set as env let fixture: HTMLElement; -let env: Env; beforeEach(() => { fixture = makeTestFixture(); - env = makeTestEnv(); + config.env = makeTestEnv(); }); afterEach(() => { @@ -37,7 +37,7 @@ describe("Context", () => { static template = xml`
`; contextObj = useContext(testContext); } - const test = new Test(env); + const test = new Test(); await test.mount(fixture); expect(fixture.innerHTML).toBe("
123
"); }); @@ -49,7 +49,7 @@ describe("Context", () => { static template = xml`
`; contextObj = useContext(testContext); } - const test = new Test(env); + const test = new Test(); await test.mount(fixture); expect(fixture.innerHTML).toBe("
123
"); test.contextObj.value = 321; @@ -68,7 +68,7 @@ describe("Context", () => { static template = xml`
`; static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
123123
"); testContext.state.value = 321; @@ -95,7 +95,7 @@ describe("Context", () => { static template = xml`
`; static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
123123
"); testContext.state.value = 321; @@ -139,7 +139,7 @@ describe("Context", () => { static components = { Child, Parent }; } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe( "

123

123

123

" @@ -175,7 +175,7 @@ describe("Context", () => { static template = xml`
`; static components = { Child }; } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
12
"); expect(steps).toEqual(["child"]); @@ -206,7 +206,7 @@ describe("Context", () => { return super.__render(fiber); } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
123321
"); expect(steps).toEqual(["parent", "child"]); @@ -240,7 +240,7 @@ describe("Context", () => { return super.__render(fiber); } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
123
"); expect(steps).toEqual(["parent", "child"]); @@ -284,7 +284,7 @@ describe("Context", () => { context = useContext(testContext); } - const component = new ComponentA(env); + const component = new ComponentA(); await component.mount(fixture); expect(fixture.innerHTML).toBe("

1a

"); diff --git a/tests/hooks.test.ts b/tests/hooks.test.ts index 33ccc76e..810bdfc5 100644 --- a/tests/hooks.test.ts +++ b/tests/hooks.test.ts @@ -1,5 +1,6 @@ import { makeTestEnv, makeTestFixture, nextTick } from "./helpers"; import { Component, Env } from "../src/component/component"; +import { config } from "../src/config"; import { useState, onMounted, @@ -28,6 +29,7 @@ let env: Env; beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; }); afterEach(() => { @@ -44,7 +46,7 @@ describe("hooks", () => { static template = xml`
`; counter = useState({ value: 42 }); } - const counter = new Counter(env); + const counter = new Counter(); await counter.mount(fixture); expect(fixture.innerHTML).toBe("
42
"); counter.counter.value = 3; @@ -64,12 +66,12 @@ describe("hooks", () => { } class MyComponent extends Component { static template = xml`
hey
`; - constructor(env) { - super(env); + constructor() { + super(); useMyHook(); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(component).not.toHaveProperty("mounted"); expect(component).not.toHaveProperty("willUnmount"); @@ -92,8 +94,8 @@ describe("hooks", () => { } class MyComponent extends Component { static template = xml`
hey
`; - constructor(env) { - super(env); + constructor(parent, props) { + super(parent, props); useMyHook(); } } @@ -103,7 +105,7 @@ describe("hooks", () => { static components = { MyComponent }; state = useState({ flag: true }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); expect(steps).toEqual(["mounted"]); @@ -126,8 +128,8 @@ describe("hooks", () => { } class MyComponent extends Component { static template = xml`
hey
`; - constructor(env) { - super(env); + constructor() { + super(); useMyHook(); } mounted() { @@ -137,7 +139,7 @@ describe("hooks", () => { steps.push("comp:willunmount"); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); component.unmount(); @@ -157,8 +159,8 @@ describe("hooks", () => { } class MyComponent extends Component { static template = xml`
hey
`; - constructor(env) { - super(env); + constructor(parent, props) { + super(parent, props); useMyHook(); } mounted() { @@ -175,7 +177,7 @@ describe("hooks", () => { state = useState({ flag: true }); } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); parent.state.flag = false; @@ -197,13 +199,13 @@ describe("hooks", () => { } class MyComponent extends Component { static template = xml`
hey
`; - constructor(env) { - super(env); + constructor() { + super(); useMyHook(1); useMyHook(2); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); component.unmount(); @@ -226,7 +228,7 @@ describe("hooks", () => { (this.button.el as HTMLButtonElement).innerHTML = String(this.value); } } - const counter = new Counter(env); + const counter = new Counter(); await counter.mount(fixture); expect(fixture.innerHTML).toBe("
"); counter.increment(); @@ -247,7 +249,7 @@ describe("hooks", () => { expect(this.spanRef.el).toBeNull(); } } - const component = new TestRef(env); + const component = new TestRef(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
owl
"); component.state.flag = false; @@ -270,13 +272,13 @@ describe("hooks", () => { static template = xml`
hey
`; state = useState({ flag: true }); - constructor(env) { - super(env); + constructor() { + super(); useMyHook(); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(component).not.toHaveProperty("patched"); expect(component).not.toHaveProperty("willPatch"); @@ -304,8 +306,8 @@ describe("hooks", () => { static template = xml`
hey
`; state = useState({ flag: true }); - constructor(env) { - super(env); + constructor() { + super(); useMyHook(); } willPatch() { @@ -315,7 +317,7 @@ describe("hooks", () => { steps.push("comp:patched"); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
hey
"); component.state.flag = false; @@ -337,13 +339,13 @@ describe("hooks", () => { class MyComponent extends Component { static template = xml`
hey
`; state = useState({ value: 1 }); - constructor(env) { - super(env); + constructor() { + super(); useMyHook(1); useMyHook(2); } } - const component = new MyComponent(env); + const component = new MyComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
hey1
"); component.state.value++; @@ -377,13 +379,13 @@ describe("hooks", () => { `; - constructor(env) { - super(env); + constructor() { + super(); useAutofocus("input2"); } } - const component = new SomeComponent(env); + const component = new SomeComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
"); const input2 = fixture.querySelectorAll("input")[1]; @@ -399,13 +401,13 @@ describe("hooks", () => { `; state = useState({ flag: false }); - constructor(env) { - super(env); + constructor() { + super(); useAutofocus("input2"); } } - const component = new SomeComponent(env); + const component = new SomeComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
"); expect(document.activeElement).toBe(document.body); @@ -420,12 +422,12 @@ describe("hooks", () => { test("can use sub env", async () => { class TestComponent extends Component { static template = xml`
`; - constructor(env) { - super(env); + constructor() { + super(); useSubEnv({ val: 3 }); } } - const component = new TestComponent(env); + const component = new TestComponent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
3
"); expect(env).not.toHaveProperty("val"); @@ -435,8 +437,8 @@ describe("hooks", () => { test("parent and child env", async () => { class Child extends Component { static template = xml`
`; - constructor(env) { - super(env); + constructor(parent, props) { + super(parent, props); useSubEnv({ val: 5 }); } } @@ -444,12 +446,12 @@ describe("hooks", () => { class Parent extends Component { static template = xml`
`; static components = { Child }; - constructor(env) { - super(env); + constructor() { + super(); useSubEnv({ val: 3 }); } } - const component = new Parent(env); + const component = new Parent(); await component.mount(fixture); expect(fixture.innerHTML).toBe("
3
5
"); }); @@ -478,7 +480,7 @@ describe("hooks", () => { state = useState({ value: 1 }); } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(app).not.toHaveProperty("willStart"); expect(app).not.toHaveProperty("willUpdateProps"); diff --git a/tests/misc/async_root.test.ts b/tests/misc/async_root.test.ts index 4bae5238..66a6c9ee 100644 --- a/tests/misc/async_root.test.ts +++ b/tests/misc/async_root.test.ts @@ -1,8 +1,9 @@ import { AsyncRoot } from "../../src/misc/async_root"; +import { config } from "../../src/config"; import { useState } from "../../src/hooks"; import { xml } from "../../src/tags"; import { makeDeferred, makeTestFixture, makeTestEnv, nextTick } from "../helpers"; -import { Env, Component } from "../../src/component/component"; +import { Component } from "../../src/component/component"; //------------------------------------------------------------------------------ // Setup and helpers @@ -11,14 +12,13 @@ import { Env, Component } from "../../src/component/component"; // We create before each test: // - fixture: a div, appended to the DOM, intended to be the target of dom // manipulations. Note that it is removed after each test. -// - env: a WEnv, necessary to create new components +// - a test env, necessary to create components, that is set as env let fixture: HTMLElement; -let env: Env; beforeEach(() => { fixture = makeTestFixture(); - env = makeTestEnv(); + config.env = makeTestEnv(); }); afterEach(() => { @@ -55,7 +55,7 @@ describe("Asyncroot", () => { } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.querySelector(".children")!.innerHTML).toBe("00"); @@ -103,7 +103,7 @@ describe("Asyncroot", () => { } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.querySelector(".children")!.innerHTML).toBe("00"); @@ -158,7 +158,7 @@ describe("Asyncroot", () => { } } - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(fixture.querySelector(".children")!.innerHTML).toBe("0/00/0"); diff --git a/tests/router/link.test.ts b/tests/router/link.test.ts index 6afabb71..58a3761b 100644 --- a/tests/router/link.test.ts +++ b/tests/router/link.test.ts @@ -1,4 +1,5 @@ import { Component } from "../../src/component/component"; +import { config } from "../../src/config"; import { Link } from "../../src/router/link"; import { RouterEnv } from "../../src/router/router"; import { makeTestEnv, makeTestFixture, nextTick } from "../helpers"; @@ -12,6 +13,7 @@ describe("Link component", () => { beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; }); afterEach(() => { @@ -38,7 +40,7 @@ describe("Link component", () => { router = new TestRouter(env, routes, { mode: "history" }); router.navigate({ to: "users" }); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe(''); @@ -69,7 +71,7 @@ describe("Link component", () => { router = new TestRouter(env, routes, { mode: "history" }); router.navigate({ to: "users" }); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(window.location.pathname).toBe("/users"); diff --git a/tests/router/route_component.test.ts b/tests/router/route_component.test.ts index 3f5e8b29..0ec00183 100644 --- a/tests/router/route_component.test.ts +++ b/tests/router/route_component.test.ts @@ -1,4 +1,5 @@ import { Component } from "../../src/component/component"; +import { config } from "../../src/config"; import { RouterEnv } from "../../src/router/router"; import { RouteComponent } from "../../src/router/route_component"; import { makeTestEnv, makeTestFixture, nextTick } from "../helpers"; @@ -12,6 +13,7 @@ describe("RouteComponent", () => { beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; }); afterEach(() => { @@ -45,7 +47,7 @@ describe("RouteComponent", () => { router = new TestRouter(env, routes, { mode: "history" }); await router.navigate({ to: "about" }); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
About
"); @@ -72,7 +74,7 @@ describe("RouteComponent", () => { const routes = [{ name: "book", path: "/book/{{title}}", component: Book }]; router = new TestRouter(env, routes, { mode: "history" }); await router.navigate({ to: "book", params: { title: "1984" } }); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
Book 1984
"); }); @@ -98,7 +100,7 @@ describe("RouteComponent", () => { const routes = [{ name: "book", path: "/book/{{title}}/{{val.number}}", component: Book }]; router = new TestRouter(env, routes, { mode: "history" }); await router.navigate({ to: "book", params: { title: "1984", val: "123" } }); - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
Book 1984|124
"); }); diff --git a/tests/store_hooks.test.ts b/tests/store_hooks.test.ts index 49c5275e..e904f004 100644 --- a/tests/store_hooks.test.ts +++ b/tests/store_hooks.test.ts @@ -1,4 +1,5 @@ import { Component, Env } from "../src/component/component"; +import { config } from "../src/config"; import { Store, useStore, useDispatch, useGetters } from "../src/store"; import { useState } from "../src/hooks"; import { xml } from "../src/tags"; @@ -12,6 +13,7 @@ describe("connecting a component to store", () => { beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; }); afterEach(() => { @@ -37,7 +39,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -69,7 +71,7 @@ describe("connecting a component to store", () => { App.prototype.__render = jest.fn(App.prototype.__render); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
12
"); @@ -101,7 +103,7 @@ describe("connecting a component to store", () => { App.prototype.__render = jest.fn(App.prototype.__render); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -134,7 +136,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); @@ -163,7 +165,7 @@ describe("connecting a component to store", () => { App.prototype.__render = jest.fn(App.prototype.__render); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); @@ -198,7 +200,7 @@ describe("connecting a component to store", () => { todos = useStore(state => state.todos, { store }); } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
"); @@ -228,7 +230,7 @@ describe("connecting a component to store", () => { storeState = useStore(state => state); dispatch = useDispatch(); } - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
1
"); @@ -257,7 +259,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
jupiler
"); @@ -294,7 +296,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new TodoList(env); + const app = new TodoList(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
jupiler
"); @@ -347,7 +349,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new TodoList(env); + const app = new TodoList(); await app.mount(fixture); expect(fixture.innerHTML).toBe( @@ -370,7 +372,7 @@ describe("connecting a component to store", () => { const state = { beers: { 1: { name: "jupiler" }, 2: { name: "kwak" } } }; const store = new Store({ state }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
jupiler
"); @@ -401,7 +403,7 @@ describe("connecting a component to store", () => { const store = new Store({ state, actions }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
jupiler
"); @@ -446,7 +448,7 @@ describe("connecting a component to store", () => { }; const store = new Store({ state, actions }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
taster:aaron
"); @@ -513,7 +515,7 @@ describe("connecting a component to store", () => { }; const store = new Store({ state, actions }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
taster:aaron
"); @@ -588,7 +590,7 @@ describe("connecting a component to store", () => { const store = new Store({ state, actions }); (env).store = store; - const app = new Parent(env); + const app = new Parent(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
a
"); @@ -639,7 +641,7 @@ describe("connecting a component to store", () => { const store = new Store({ state, actions }); (env).store = store; - const app = new Parent(env); + const app = new Parent(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
abc
"); @@ -713,7 +715,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new TodoApp(env); + const app = new TodoApp(); await app.mount(fixture); expect(fixture.innerHTML).toBe( @@ -787,7 +789,7 @@ describe("connecting a component to store", () => { } (env).store = store; - const app = new TodoApp(env); + const app = new TodoApp(); await app.mount(fixture); expect(fixture.innerHTML).toBe( @@ -833,7 +835,7 @@ describe("connecting a component to store", () => { const store = new Store({ state, actions }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
a
"); @@ -870,7 +872,7 @@ describe("connecting a component to store", () => { } const store = new TestStore({ state: { val: 1 } }); (env).store = store; - const parent = new Parent(env); + const parent = new Parent(); await parent.mount(fixture); expect(steps).toEqual(["on:update"]); @@ -901,7 +903,7 @@ describe("connecting a component to store", () => { const store = new Store({ state, actions }); (env).store = store; - const app = new App(env); + const app = new App(); await app.mount(fixture); expect(fixture.innerHTML).toBe("
0
"); @@ -920,6 +922,7 @@ describe("various scenarios", () => { beforeEach(() => { fixture = makeTestFixture(); env = makeTestEnv(); + config.env = env; }); afterEach(() => { @@ -978,7 +981,8 @@ describe("various scenarios", () => { } (env).store = store; - const message = new Message(env); + const message = new Message(); + await message.mount(fixture); expect(fixture.innerHTML).toMatchSnapshot(); diff --git a/tools/benchmarks/owl-master/app.js b/tools/benchmarks/owl-master/app.js index d3f89de2..e49ade35 100644 --- a/tools/benchmarks/owl-master/app.js +++ b/tools/benchmarks/owl-master/app.js @@ -145,10 +145,10 @@ class App extends owl.Component { //------------------------------------------------------------------------------ async function start() { const templates = await owl.utils.loadFile("templates.xml"); - const env = { + owl.config.env = { qweb: new owl.QWeb({ templates }) }; - const app = new App(env); + const app = new App(); app.mount(document.body); } diff --git a/tools/playground/app.js b/tools/playground/app.js index 9beed851..e5d1535c 100644 --- a/tools/playground/app.js +++ b/tools/playground/app.js @@ -90,7 +90,14 @@ function makeCodeIframe(js, css, xml, errorHandler) { owlScript.addEventListener("load", () => { const script = doc.createElement("script"); script.type = "text/javascript"; - const content = `owl.__info__.mode = 'dev';\nwindow.TEMPLATES = \`${sanitizedXML}\`;\n${js}`; + const content = ` + { + owl.__info__.mode = 'dev'; + let templates = \`${sanitizedXML}\`; + const qweb = new owl.QWeb({ templates }); + owl.config.env = { qweb }; + } + ${js}`; script.innerHTML = content; iframe.contentWindow.addEventListener("error", errorHandler); iframe.contentWindow.addEventListener("unhandledrejection", errorHandler); @@ -436,7 +443,9 @@ async function start() { owl.utils.whenReady() ]); const qweb = new owl.QWeb({ templates }); - const app = new App({ qweb }); + debugger; + owl.config.env = { qweb }; + const app = new App(); app.mount(document.body); } diff --git a/tools/playground/samples.js b/tools/playground/samples.js index 3ada1bea..b47f8e35 100644 --- a/tools/playground/samples.js +++ b/tools/playground/samples.js @@ -16,9 +16,7 @@ class App extends Component { App.components = { Greeter }; // Application setup -// Note that the xml templates are injected into the global TEMPLATES variable. -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({ qweb }); +const app = new App(); app.mount(document.body); `; @@ -70,8 +68,7 @@ class App extends Component { } App.components = { Counter }; -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({qweb}); +const app = new App(); app.mount(document.body); `; @@ -228,8 +225,7 @@ class App extends Component { } App.components = { DemoComponent }; -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({ qweb }); +const app = new App(); app.mount(document.body); `; @@ -298,8 +294,7 @@ class App extends owl.Component { } // Application setup -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({ qweb }); +const app = new App(); app.mount(document.body); `; @@ -349,11 +344,9 @@ const themeContext = new Context({ background: '#000', foreground: '#fff', }); -const env = { - qweb: new owl.QWeb({ templates: TEMPLATES}), - themeContext: themeContext, -}; -const app = new App(env); +// Add the themeContext the environment to make it available to all components +owl.config.env.themeContext = themeContext; +const app = new App(); app.mount(document.body); `; @@ -534,26 +527,25 @@ TodoApp.components = { TodoItem }; //------------------------------------------------------------------------------ // App Initialization //------------------------------------------------------------------------------ -function saveState(state) { - const str = JSON.stringify(state); - window.localStorage.setItem(LOCALSTORAGE_KEY, str); -} -function loadState() { - const localState = window.localStorage.getItem(LOCALSTORAGE_KEY); - return localState ? JSON.parse(localState) : initialState; -} +function makeStore() { + function saveState(state) { + const str = JSON.stringify(state); + window.localStorage.setItem(LOCALSTORAGE_KEY, str); + } + function loadState() { + const localState = window.localStorage.getItem(LOCALSTORAGE_KEY); + return localState ? JSON.parse(localState) : initialState; + } -function makeEnv() { const state = loadState(); const store = new owl.Store({ state, actions }); store.on("update", null, () => saveState(store.state)); - const qweb = new owl.QWeb({ templates: TEMPLATES}); - return { qweb, store }; + return store; } -const env = makeEnv(); -const app = new TodoApp(env); +owl.config.env.store = makeStore(); +const app = new TodoApp(); app.mount(document.body); `; @@ -1040,12 +1032,9 @@ function setupResponsivePlugin(env) { //------------------------------------------------------------------------------ // Application Startup //------------------------------------------------------------------------------ -const env = { - qweb: new owl.QWeb({ templates: TEMPLATES}), -}; -setupResponsivePlugin(env); +setupResponsivePlugin(owl.config.env); -const app = new App(env); +const app = new App(); app.mount(document.body); `; @@ -1187,8 +1176,7 @@ class App extends Component { App.components = {Card, Counter}; // Application setup -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({ qweb }); +const app = new App(); app.mount(document.body);`; const SLOTS_XML = ` @@ -1301,10 +1289,9 @@ class App extends Component { }, 3000); } } -App.components = {SlowComponent, NotificationList}; +App.components = {SlowComponent, NotificationList, AsyncRoot}; -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const app = new App({ qweb }); +const app = new App(); app.mount(document.body); `; @@ -1373,8 +1360,7 @@ class Form extends Component { } // Application setup -const qweb = new owl.QWeb({ templates: TEMPLATES}); -const form = new Form({ qweb }); +const form = new Form(); form.mount(document.body); `; @@ -1540,7 +1526,6 @@ class App extends Component { } App.components = { WindowManager }; -const qweb = new owl.QWeb({ templates: TEMPLATES}); const windows = [ { name: "Hello", @@ -1558,8 +1543,8 @@ const windows = [ } ]; -const env = { qweb, windows }; -const app = new App(env); +owl.config.env.windows = windows; +const app = new App(); app.mount(document.body); `;