mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] types: make component generic types optional
In most cases, we just want Component<any, Env>. But since it was so annoying to have always the type Env, we actually used Component<any,any> everywhere. With this commit, the generic types have a default (and their order is swapped), so we can simply use Component in most cases, and Component<Props> when we want to type the props.
This commit is contained in:
@@ -41,4 +41,3 @@ Each component has an internal `id`, which is very useful when debugging.
|
|||||||
|
|
||||||
Note that it is certainly useful to run this code at some point in an application,
|
Note that it is certainly useful to run this code at some point in an application,
|
||||||
just to get a feel of what each user action implies, for the framework.
|
just to get a feel of what each user action implies, for the framework.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# 🦉 Quick Overview 🦉
|
# 🦉 Quick Overview 🦉
|
||||||
|
|
||||||
|
|
||||||
Owl components in an application are used to define a (dynamic) tree of components.
|
Owl components in an application are used to define a (dynamic) tree of components.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -110,7 +109,10 @@ class Parent extends Component {
|
|||||||
line="line" />
|
line="line" />
|
||||||
</div>`;
|
</div>`;
|
||||||
static components = { OrderLine };
|
static components = { OrderLine };
|
||||||
orders = useState([{ id: 1, name: "Coffee", quantity: 0 }, { id: 2, name: "Tea", quantity: 0 }]);
|
orders = useState([
|
||||||
|
{ id: 1, name: "Coffee", quantity: 0 },
|
||||||
|
{ id: 2, name: "Tea", quantity: 0 }
|
||||||
|
]);
|
||||||
|
|
||||||
addToOrder(event) {
|
addToOrder(event) {
|
||||||
const line = event.detail.line;
|
const line = event.detail.line;
|
||||||
|
|||||||
+15
-29
@@ -9,16 +9,16 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Each software project has its specific needs. Many of these needs can be solved
|
Each software project has its specific needs. Many of these needs can be solved
|
||||||
with some tooling: `webpack`, `gulp`, css preprocessor, bundlers, transpilers, ...
|
with some tooling: `webpack`, `gulp`, css preprocessor, bundlers, transpilers, ...
|
||||||
|
|
||||||
Because of that, it is usually not simple to just start a project. Some
|
Because of that, it is usually not simple to just start a project. Some
|
||||||
frameworks provide their own tooling to help with that. But then, you have to
|
frameworks provide their own tooling to help with that. But then, you have to
|
||||||
integrate and learn how these applications work.
|
integrate and learn how these applications work.
|
||||||
|
|
||||||
Owl is designed to be used with no tooling at all. Because of that, Owl can
|
Owl is designed to be used with no tooling at all. Because of that, Owl can
|
||||||
"easily" be integrated in a modern build toolchain. In this section, we will
|
"easily" be integrated in a modern build toolchain. In this section, we will
|
||||||
discuss a few different setups to start a project. Each of these setups has
|
discuss a few different setups to start a project. Each of these setups has
|
||||||
advantages and disadvantages in different situations.
|
advantages and disadvantages in different situations.
|
||||||
|
|
||||||
## Simple html file
|
## Simple html file
|
||||||
@@ -74,8 +74,7 @@ whenReady(setup);
|
|||||||
|
|
||||||
Now, simply loading this html file in a browser should display a welcome message.
|
Now, simply loading this html file in a browser should display a welcome message.
|
||||||
This setup is not fancy, but it is extremely simple. There are no tooling at
|
This setup is not fancy, but it is extremely simple. There are no tooling at
|
||||||
all required. It can be slightly optimized by using the minified build of Owl.
|
all required. It can be slightly optimized by using the minified build of Owl.
|
||||||
|
|
||||||
|
|
||||||
## With a static server
|
## With a static server
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ variables and we lose autocompletion across files.
|
|||||||
|
|
||||||
There is a low tech solution to this issue: using native javascript modules.
|
There is a low tech solution to this issue: using native javascript modules.
|
||||||
This however has a requirement: for security reasons, browsers will not accept
|
This however has a requirement: for security reasons, browsers will not accept
|
||||||
modules on content served through the `file` protocol. This means that we need
|
modules on content served through the `file` protocol. This means that we need
|
||||||
to use a static server.
|
to use a static server.
|
||||||
|
|
||||||
Let us start a new project with the following file structure:
|
Let us start a new project with the following file structure:
|
||||||
@@ -101,7 +100,6 @@ hello_owl/
|
|||||||
owl.js
|
owl.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
As previously, the file `owl.js` can be downloaded from the last release published at
|
As previously, the file `owl.js` can be downloaded from the last release published at
|
||||||
[https://github.com/odoo/owl/releases](https://github.com/odoo/owl/releases).
|
[https://github.com/odoo/owl/releases](https://github.com/odoo/owl/releases).
|
||||||
|
|
||||||
@@ -130,10 +128,9 @@ const { Component } = owl;
|
|||||||
const { xml } = owl.tags;
|
const { xml } = owl.tags;
|
||||||
|
|
||||||
export class App extends Component {
|
export class App extends Component {
|
||||||
static template = xml`<div>Hello Owl</div>`;
|
static template = xml`<div>Hello Owl</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// main.js ---------------------------------------------------------------------
|
// main.js ---------------------------------------------------------------------
|
||||||
import { App } from "./app.js";
|
import { App } from "./app.js";
|
||||||
|
|
||||||
@@ -145,11 +142,11 @@ function setup() {
|
|||||||
owl.utils.whenReady(setup);
|
owl.utils.whenReady(setup);
|
||||||
```
|
```
|
||||||
|
|
||||||
The `main.js` file import the `app.js` file. Note that the import statement has
|
The `main.js` file import the `app.js` file. Note that the import statement has
|
||||||
a `.js` suffix, which is important. Most text editor can understand this syntax
|
a `.js` suffix, which is important. Most text editor can understand this syntax
|
||||||
and will provide autocompletion.
|
and will provide autocompletion.
|
||||||
|
|
||||||
Now, to execute this code, we need to serve the `src` folder statically. A low
|
Now, to execute this code, we need to serve the `src` folder statically. A low
|
||||||
tech way to do that is to use for example the python `SimpleHTTPServer` feature:
|
tech way to do that is to use for example the python `SimpleHTTPServer` feature:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -180,18 +177,16 @@ that, we can add the following `package.json` file at the root of the project:
|
|||||||
We can now install the `serve` tool with the command `npm install`, and then,
|
We can now install the `serve` tool with the command `npm install`, and then,
|
||||||
start a static server with the simple `npm run serve` command.
|
start a static server with the simple `npm run serve` command.
|
||||||
|
|
||||||
|
|
||||||
## Standard Javascript project
|
## Standard Javascript project
|
||||||
|
|
||||||
The previous setup works, and is certainly good for some usecases, including
|
The previous setup works, and is certainly good for some usecases, including
|
||||||
quick prototyping. However, it lacks some useful features, such as livereload,
|
quick prototyping. However, it lacks some useful features, such as livereload,
|
||||||
a test suite, or bundling the code in a single file.
|
a test suite, or bundling the code in a single file.
|
||||||
|
|
||||||
Each of these features, and many others, can be done in many different ways.
|
Each of these features, and many others, can be done in many different ways.
|
||||||
Since it is really not trivial to configure such a project, we provide here an
|
Since it is really not trivial to configure such a project, we provide here an
|
||||||
example that can be used as a starting point.
|
example that can be used as a starting point.
|
||||||
|
|
||||||
|
|
||||||
Our standard Owl project has the following file structure:
|
Our standard Owl project has the following file structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -244,7 +239,6 @@ export class App extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// src/main.js -----------------------------------------------------------------
|
// src/main.js -----------------------------------------------------------------
|
||||||
import { utils } from "@odoo/owl";
|
import { utils } from "@odoo/owl";
|
||||||
import { App } from "./components/App";
|
import { App } from "./components/App";
|
||||||
@@ -256,7 +250,6 @@ function setup() {
|
|||||||
|
|
||||||
utils.whenReady(setup);
|
utils.whenReady(setup);
|
||||||
|
|
||||||
|
|
||||||
// tests/components/App.test.js ------------------------------------------------
|
// tests/components/App.test.js ------------------------------------------------
|
||||||
import { App } from "../../src/components/App";
|
import { App } from "../../src/components/App";
|
||||||
import { makeTestFixture, nextTick, click } from "../helpers";
|
import { makeTestFixture, nextTick, click } from "../helpers";
|
||||||
@@ -283,16 +276,13 @@ describe("App", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// tests/helpers.js ------------------------------------------------------------
|
// tests/helpers.js ------------------------------------------------------------
|
||||||
import { Component } from "@odoo/owl";
|
import { Component } from "@odoo/owl";
|
||||||
import "regenerator-runtime/runtime";
|
import "regenerator-runtime/runtime";
|
||||||
|
|
||||||
export async function nextTick() {
|
export async function nextTick() {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
setTimeout(() =>
|
setTimeout(() => Component.scheduler.requestAnimationFrame(() => resolve()));
|
||||||
Component.scheduler.requestAnimationFrame(() => resolve())
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,9 +337,7 @@ dist/
|
|||||||
"@odoo/owl": "^1.0.4"
|
"@odoo/owl": "^1.0.4"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"plugins": [
|
"plugins": ["@babel/plugin-proposal-class-properties"],
|
||||||
"@babel/plugin-proposal-class-properties"
|
|
||||||
],
|
|
||||||
"env": {
|
"env": {
|
||||||
"test": {
|
"test": {
|
||||||
"plugins": ["transform-es2015-modules-commonjs"]
|
"plugins": ["transform-es2015-modules-commonjs"]
|
||||||
@@ -359,9 +347,7 @@ dist/
|
|||||||
"jest": {
|
"jest": {
|
||||||
"verbose": false,
|
"verbose": false,
|
||||||
"testRegex": "(/tests/.*(test|spec))\\.js?$",
|
"testRegex": "(/tests/.*(test|spec))\\.js?$",
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": ["js"],
|
||||||
"js"
|
|
||||||
],
|
|
||||||
"transform": {
|
"transform": {
|
||||||
"^.+\\.[t|j]sx?$": "babel-jest"
|
"^.+\\.[t|j]sx?$": "babel-jest"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,7 @@ which cannot be considered either a tutorial, or reference documentation.
|
|||||||
- [Comparison with React/Vue](miscellaneous/comparison.md)
|
- [Comparison with React/Vue](miscellaneous/comparison.md)
|
||||||
- [Why did Odoo built Owl?](miscellaneous/why_owl.md)
|
- [Why did Odoo built Owl?](miscellaneous/why_owl.md)
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Found an issue in the documentation? A broken link? Some outdated information?
|
Found an issue in the documentation? A broken link? Some outdated information?
|
||||||
Please open an issue or submit a PR!
|
Please open an issue or submit a PR!
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -46,7 +46,7 @@ interface MountOptions {
|
|||||||
* useful to typecheck and describe the internal keys used by Owl to manage the
|
* useful to typecheck and describe the internal keys used by Owl to manage the
|
||||||
* component tree.
|
* component tree.
|
||||||
*/
|
*/
|
||||||
interface Internal<T extends Env, Props> {
|
interface Internal<T extends Env> {
|
||||||
// each component has a unique id, useful mostly to handle parent/child
|
// each component has a unique id, useful mostly to handle parent/child
|
||||||
// relationships
|
// relationships
|
||||||
readonly id: number;
|
readonly id: number;
|
||||||
@@ -58,8 +58,8 @@ interface Internal<T extends Env, Props> {
|
|||||||
|
|
||||||
// parent and children keys are obviously useful to setup the parent-children
|
// parent and children keys are obviously useful to setup the parent-children
|
||||||
// relationship.
|
// relationship.
|
||||||
parent: Component<T, any> | null;
|
parent: Component<any, T> | null;
|
||||||
children: { [key: number]: Component<T, any> };
|
children: { [key: number]: Component<any, T> };
|
||||||
// children mapping: from templateID to componentID. templateID identifies a
|
// children mapping: from templateID to componentID. templateID identifies a
|
||||||
// place in a template. The t-component directive needs it to be able to get
|
// place in a template. The t-component directive needs it to be able to get
|
||||||
// the component instance back whenever the template is rerendered.
|
// the component instance back whenever the template is rerendered.
|
||||||
@@ -85,7 +85,7 @@ interface Internal<T extends Env, Props> {
|
|||||||
willStartCB: Function | null;
|
willStartCB: Function | null;
|
||||||
willUpdatePropsCB: Function | null;
|
willUpdatePropsCB: Function | null;
|
||||||
classObj: { [key: string]: boolean } | null;
|
classObj: { [key: string]: boolean } | null;
|
||||||
refs: { [key: string]: Component<T, any> | HTMLElement | undefined } | null;
|
refs: { [key: string]: Component<any, T> | HTMLElement | undefined } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const portalSymbol = Symbol("portal"); // FIXME
|
export const portalSymbol = Symbol("portal"); // FIXME
|
||||||
@@ -95,11 +95,11 @@ export const portalSymbol = Symbol("portal"); // FIXME
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
let nextId = 1;
|
let nextId = 1;
|
||||||
|
|
||||||
export class Component<T extends Env, Props extends {}> {
|
export class Component<Props extends {} = any, T extends Env = Env> {
|
||||||
readonly __owl__: Internal<Env, Props>;
|
readonly __owl__: Internal<T>;
|
||||||
static template?: string | null = null;
|
static template?: string | null = null;
|
||||||
static _template?: string | null = null;
|
static _template?: string | null = null;
|
||||||
static current: Component<any, any> | null = null;
|
static current: Component | null = null;
|
||||||
static components = {};
|
static components = {};
|
||||||
static props?: any;
|
static props?: any;
|
||||||
static defaultProps?: any;
|
static defaultProps?: any;
|
||||||
@@ -130,7 +130,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
* hand. Other components should be created automatically by the framework (with
|
* hand. Other components should be created automatically by the framework (with
|
||||||
* the t-component directive in a template)
|
* the t-component directive in a template)
|
||||||
*/
|
*/
|
||||||
constructor(parent?: Component<T, any> | null, props?: Props) {
|
constructor(parent?: Component<any, T> | null, props?: Props) {
|
||||||
Component.current = this;
|
Component.current = this;
|
||||||
|
|
||||||
let constr = this.constructor as any;
|
let constr = this.constructor as any;
|
||||||
@@ -441,7 +441,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
* Note that it does not call the __callWillUnmount method to avoid visiting
|
* Note that it does not call the __callWillUnmount method to avoid visiting
|
||||||
* all children many times.
|
* all children many times.
|
||||||
*/
|
*/
|
||||||
__destroy(parent: Component<any, any> | null) {
|
__destroy(parent: Component | null) {
|
||||||
const __owl__ = this.__owl__;
|
const __owl__ = this.__owl__;
|
||||||
const isMounted = __owl__.isMounted;
|
const isMounted = __owl__.isMounted;
|
||||||
if (isMounted) {
|
if (isMounted) {
|
||||||
@@ -501,7 +501,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
* Private trigger method, allows to choose the component which triggered
|
* Private trigger method, allows to choose the component which triggered
|
||||||
* the event in the first place
|
* the event in the first place
|
||||||
*/
|
*/
|
||||||
__trigger(component: Component<any, any>, eventType: string, payload?: any) {
|
__trigger(component: Component, eventType: string, payload?: any) {
|
||||||
if (this.el) {
|
if (this.el) {
|
||||||
const ev = new OwlEvent(component, eventType, {
|
const ev = new OwlEvent(component, eventType, {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export class Fiber {
|
|||||||
|
|
||||||
scope: any;
|
scope: any;
|
||||||
|
|
||||||
component: Component<any, any>;
|
component: Component;
|
||||||
vnode: VNode | null = null;
|
vnode: VNode | null = null;
|
||||||
|
|
||||||
root: Fiber;
|
root: Fiber;
|
||||||
@@ -61,7 +61,7 @@ export class Fiber {
|
|||||||
|
|
||||||
error?: Error;
|
error?: Error;
|
||||||
|
|
||||||
constructor(parent: Fiber | null, component: Component<any, any>, force, inserter) {
|
constructor(parent: Fiber | null, component: Component, force: boolean, inserter) {
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.force = force;
|
this.force = force;
|
||||||
this.inserter = inserter;
|
this.inserter = inserter;
|
||||||
|
|||||||
+2
-2
@@ -100,11 +100,11 @@ export class Context extends EventBus {
|
|||||||
* to context state changes. The `useContext` method returns the context state
|
* to context state changes. The `useContext` method returns the context state
|
||||||
*/
|
*/
|
||||||
export function useContext(ctx: Context): any {
|
export function useContext(ctx: Context): any {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
return useContextWithCB(ctx, component, component.render.bind(component));
|
return useContextWithCB(ctx, component, component.render.bind(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useContextWithCB(ctx: Context, component: Component<any, any>, method): any {
|
export function useContextWithCB(ctx: Context, component: Component, method): any {
|
||||||
const __owl__ = component.__owl__;
|
const __owl__ = component.__owl__;
|
||||||
const id = __owl__.id;
|
const id = __owl__.id;
|
||||||
const mapping = ctx.mapping;
|
const mapping = ctx.mapping;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Component } from "../component/component";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export class OwlEvent<T> extends CustomEvent<T> {
|
export class OwlEvent<T> extends CustomEvent<T> {
|
||||||
originalComponent: Component<any, any>;
|
originalComponent: Component;
|
||||||
constructor(component, eventType, options) {
|
constructor(component, eventType, options) {
|
||||||
super(eventType, options);
|
super(eventType, options);
|
||||||
this.originalComponent = component;
|
this.originalComponent = component;
|
||||||
|
|||||||
+6
-6
@@ -22,7 +22,7 @@ import { Observer } from "./core/observer";
|
|||||||
* trigger a rerendering of the current component.
|
* trigger a rerendering of the current component.
|
||||||
*/
|
*/
|
||||||
export function useState<T>(state: T): T {
|
export function useState<T>(state: T): T {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
const __owl__ = component.__owl__;
|
const __owl__ = component.__owl__;
|
||||||
if (!__owl__.observer) {
|
if (!__owl__.observer) {
|
||||||
__owl__.observer = new Observer();
|
__owl__.observer = new Observer();
|
||||||
@@ -37,7 +37,7 @@ export function useState<T>(state: T): T {
|
|||||||
function makeLifecycleHook(method: string, reverse: boolean = false) {
|
function makeLifecycleHook(method: string, reverse: boolean = false) {
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
return function(cb) {
|
return function(cb) {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
if (component.__owl__[method]) {
|
if (component.__owl__[method]) {
|
||||||
const current = component.__owl__[method];
|
const current = component.__owl__[method];
|
||||||
component.__owl__[method] = function() {
|
component.__owl__[method] = function() {
|
||||||
@@ -50,7 +50,7 @@ function makeLifecycleHook(method: string, reverse: boolean = false) {
|
|||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return function(cb) {
|
return function(cb) {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
if (component.__owl__[method]) {
|
if (component.__owl__[method]) {
|
||||||
const current = component.__owl__[method];
|
const current = component.__owl__[method];
|
||||||
component.__owl__[method] = function() {
|
component.__owl__[method] = function() {
|
||||||
@@ -66,7 +66,7 @@ function makeLifecycleHook(method: string, reverse: boolean = false) {
|
|||||||
|
|
||||||
function makeAsyncHook(method: string) {
|
function makeAsyncHook(method: string) {
|
||||||
return function(cb) {
|
return function(cb) {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
if (component.__owl__[method]) {
|
if (component.__owl__[method]) {
|
||||||
const current = component.__owl__[method];
|
const current = component.__owl__[method];
|
||||||
component.__owl__[method] = function(...args) {
|
component.__owl__[method] = function(...args) {
|
||||||
@@ -96,7 +96,7 @@ export const onWillUpdateProps = makeAsyncHook("willUpdatePropsCB");
|
|||||||
*/
|
*/
|
||||||
interface Ref {
|
interface Ref {
|
||||||
el: HTMLElement | null;
|
el: HTMLElement | null;
|
||||||
comp: Component<any, any> | null;
|
comp: Component | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useRef(name: string): Ref {
|
export function useRef(name: string): Ref {
|
||||||
@@ -111,7 +111,7 @@ export function useRef(name: string): Ref {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
get comp(): Component<any, any> | null {
|
get comp(): Component | null {
|
||||||
const val = __owl__.refs && __owl__.refs[name];
|
const val = __owl__.refs && __owl__.refs[name];
|
||||||
return val instanceof Component ? val : null;
|
return val instanceof Component ? val : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { xml } from "../tags";
|
|||||||
* from this coordination. This is the goal of the AsyncRoot component.
|
* from this coordination. This is the goal of the AsyncRoot component.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class AsyncRoot extends Component<any, any> {
|
export class AsyncRoot extends Component {
|
||||||
static template = xml`<t t-slot="default"/>`;
|
static template = xml`<t t-slot="default"/>`;
|
||||||
|
|
||||||
async __updateProps(nextProps, parentFiber) {
|
async __updateProps(nextProps, parentFiber) {
|
||||||
|
|||||||
+7
-3
@@ -18,7 +18,11 @@ import { useSubEnv } from "../hooks";
|
|||||||
* are re-triggered on an empty <portal> node located in the parent's DOM.
|
* are re-triggered on an empty <portal> node located in the parent's DOM.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export class Portal extends Component<any, any> {
|
interface Props {
|
||||||
|
target: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Portal extends Component<Props> {
|
||||||
static template = xml`<portal><t t-slot="default"/></portal>`;
|
static template = xml`<portal><t t-slot="default"/></portal>`;
|
||||||
static props = {
|
static props = {
|
||||||
target: {
|
target: {
|
||||||
@@ -43,7 +47,7 @@ export class Portal extends Component<any, any> {
|
|||||||
// represents the element that is moved somewhere else
|
// represents the element that is moved somewhere else
|
||||||
portal: VNode | null = null;
|
portal: VNode | null = null;
|
||||||
// the target where we will move `portal`
|
// the target where we will move `portal`
|
||||||
target: HTMLElement | null = null;
|
target: Element | null = null;
|
||||||
|
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -158,7 +162,7 @@ export class Portal extends Component<any, any> {
|
|||||||
/**
|
/**
|
||||||
* Override to set the env
|
* Override to set the env
|
||||||
*/
|
*/
|
||||||
__trigger(component: Component<any, any>, eventType: string, payload?: any) {
|
__trigger(component: Component, eventType: string, payload?: any) {
|
||||||
const env = this.env;
|
const env = this.env;
|
||||||
this.env = this.parentEnv;
|
this.env = this.parentEnv;
|
||||||
super.__trigger(component, eventType, payload);
|
super.__trigger(component, eventType, payload);
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import { Destination, RouterEnv } from "./router";
|
|||||||
|
|
||||||
type Props = Destination;
|
type Props = Destination;
|
||||||
|
|
||||||
export class Link<Env extends RouterEnv> extends Component<Env, Props> {
|
export class Link<Env extends RouterEnv> extends Component<Props, Env> {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<a t-att-class="{'router-link-active': isActive }"
|
<a t-att-class="{'router-link-active': isActive }"
|
||||||
t-att-href="href"
|
t-att-href="href"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component } from "../component/component";
|
import { Component } from "../component/component";
|
||||||
import { xml } from "../tags";
|
import { xml } from "../tags";
|
||||||
|
|
||||||
export class RouteComponent extends Component<any, {}> {
|
export class RouteComponent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<t>
|
<t>
|
||||||
<t
|
<t
|
||||||
|
|||||||
+1
-1
@@ -83,7 +83,7 @@ interface SelectorOptions {
|
|||||||
const isStrictEqual = (a, b) => a === b;
|
const isStrictEqual = (a, b) => a === b;
|
||||||
|
|
||||||
export function useStore(selector, options: SelectorOptions = {}): any {
|
export function useStore(selector, options: SelectorOptions = {}): any {
|
||||||
const component: Component<any, any> = Component.current!;
|
const component: Component = Component.current!;
|
||||||
const componentId = component.__owl__.id;
|
const componentId = component.__owl__.id;
|
||||||
const store = options.store || (component.env.store as Store);
|
const store = options.store || (component.env.store as Store);
|
||||||
if (!(store instanceof Store)) {
|
if (!(store instanceof Store)) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ afterEach(() => {
|
|||||||
fixture.remove();
|
fixture.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
function children(w: Component<any, any>): Component<any, any>[] {
|
function children(w: Component): Component[] {
|
||||||
const childrenMap = w.__owl__.children;
|
const childrenMap = w.__owl__.children;
|
||||||
return Object.keys(childrenMap).map(id => childrenMap[id]);
|
return Object.keys(childrenMap).map(id => childrenMap[id]);
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ function children(w: Component<any, any>): Component<any, any>[] {
|
|||||||
describe("async rendering", () => {
|
describe("async rendering", () => {
|
||||||
test("destroying a widget before start is over", async () => {
|
test("destroying a widget before start is over", async () => {
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
class W extends Component<any, any> {
|
class W extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
willStart(): Promise<void> {
|
willStart(): Promise<void> {
|
||||||
return def;
|
return def;
|
||||||
@@ -53,7 +53,7 @@ describe("async rendering", () => {
|
|||||||
test("destroying/recreating a subwidget with different props (if start is not over)", async () => {
|
test("destroying/recreating a subwidget with different props (if start is not over)", async () => {
|
||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
let n = 0;
|
let n = 0;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span>child:<t t-esc="props.val"/></span>`;
|
static template = xml`<span>child:<t t-esc="props.val"/></span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -63,7 +63,7 @@ describe("async rendering", () => {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class W extends Component<any, any> {
|
class W extends Component {
|
||||||
static template = xml`<div><t t-if="state.val > 1"><Child val="state.val"/></t></div>`;
|
static template = xml`<div><t t-if="state.val > 1"><Child val="state.val"/></t></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ val: 1 });
|
state = useState({ val: 1 });
|
||||||
@@ -90,7 +90,7 @@ describe("async rendering", () => {
|
|||||||
let defB = makeDeferred();
|
let defB = makeDeferred();
|
||||||
let nbRenderings: number = 0;
|
let nbRenderings: number = 0;
|
||||||
|
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
static template = xml`<span><t t-esc="getValue()"/></span>`;
|
static template = xml`<span><t t-esc="getValue()"/></span>`;
|
||||||
willStart(): Promise<void> {
|
willStart(): Promise<void> {
|
||||||
return defA;
|
return defA;
|
||||||
@@ -101,13 +101,13 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChildB extends Component<any, any> {
|
class ChildB extends Component {
|
||||||
static template = xml`<span>b</span>`;
|
static template = xml`<span>b</span>`;
|
||||||
willStart(): Promise<void> {
|
willStart(): Promise<void> {
|
||||||
return defB;
|
return defB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.flagA"><ChildA /></t>
|
<t t-if="state.flagA"><ChildA /></t>
|
||||||
@@ -139,20 +139,20 @@ describe("async rendering", () => {
|
|||||||
let defA = makeDeferred();
|
let defA = makeDeferred();
|
||||||
let defB = makeDeferred();
|
let defB = makeDeferred();
|
||||||
|
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
static template = xml`<span>a<t t-esc="props.val"/></span>`;
|
static template = xml`<span>a<t t-esc="props.val"/></span>`;
|
||||||
willUpdateProps(): Promise<void> {
|
willUpdateProps(): Promise<void> {
|
||||||
return defA;
|
return defA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ChildB extends Component<any, any> {
|
class ChildB extends Component {
|
||||||
static template = xml`<span>b<t t-esc="props.val"/></span>`;
|
static template = xml`<span>b<t t-esc="props.val"/></span>`;
|
||||||
willStart(): Promise<void> {
|
willStart(): Promise<void> {
|
||||||
return defB;
|
return defB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<ChildA val="state.valA"/>
|
<ChildA val="state.valA"/>
|
||||||
@@ -182,20 +182,20 @@ describe("async rendering", () => {
|
|||||||
let defA = makeDeferred();
|
let defA = makeDeferred();
|
||||||
let defB = makeDeferred();
|
let defB = makeDeferred();
|
||||||
|
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
static template = xml`<span>a<t t-esc="props.val"/></span>`;
|
static template = xml`<span>a<t t-esc="props.val"/></span>`;
|
||||||
willUpdateProps(): Promise<void> {
|
willUpdateProps(): Promise<void> {
|
||||||
return defA;
|
return defA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ChildB extends Component<any, any> {
|
class ChildB extends Component {
|
||||||
static template = xml`<span>b<t t-esc="props.val"/></span>`;
|
static template = xml`<span>b<t t-esc="props.val"/></span>`;
|
||||||
willStart(): Promise<void> {
|
willStart(): Promise<void> {
|
||||||
return defB;
|
return defB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<ChildA val="state.valA"/>
|
<ChildA val="state.valA"/>
|
||||||
@@ -224,7 +224,7 @@ describe("async rendering", () => {
|
|||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
const defs = [makeDeferred(), makeDeferred()];
|
const defs = [makeDeferred(), makeDeferred()];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
willUpdateProps(): Promise<void> {
|
willUpdateProps(): Promise<void> {
|
||||||
return defs[index++];
|
return defs[index++];
|
||||||
@@ -234,7 +234,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><ChildA val="state.valA"/></div>`;
|
static template = xml`<div><ChildA val="state.valA"/></div>`;
|
||||||
static components = { ChildA };
|
static components = { ChildA };
|
||||||
state = useState({ valA: 1 });
|
state = useState({ valA: 1 });
|
||||||
@@ -258,7 +258,7 @@ describe("async rendering", () => {
|
|||||||
|
|
||||||
test("update a sub-component twice in the same frame, 2", async () => {
|
test("update a sub-component twice in the same frame, 2", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
static template = xml`<span><t t-esc="val()"/></span>`;
|
static template = xml`<span><t t-esc="val()"/></span>`;
|
||||||
patched() {
|
patched() {
|
||||||
steps.push("patched");
|
steps.push("patched");
|
||||||
@@ -269,7 +269,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><ChildA val="state.valA"/></div>`;
|
static template = xml`<div><ChildA val="state.valA"/></div>`;
|
||||||
static components = { ChildA };
|
static components = { ChildA };
|
||||||
state = useState({ valA: 1 });
|
state = useState({ valA: 1 });
|
||||||
@@ -302,9 +302,9 @@ describe("async rendering", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("components in a node in a t-foreach ", async () => {
|
test("components in a node in a t-foreach ", async () => {
|
||||||
class Child extends Component<any, any> {}
|
class Child extends Component {}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
|
|
||||||
get items() {
|
get items() {
|
||||||
@@ -335,7 +335,7 @@ describe("async rendering", () => {
|
|||||||
test("properly behave when destroyed/unmounted while rendering ", async () => {
|
test("properly behave when destroyed/unmounted while rendering ", async () => {
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
|
|
||||||
class SubChild extends Component<any, any> {
|
class SubChild extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
willPatch() {
|
willPatch() {
|
||||||
throw new Error("Should not happen!");
|
throw new Error("Should not happen!");
|
||||||
@@ -348,12 +348,12 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><SubChild /></div>`;
|
static template = xml`<div><SubChild /></div>`;
|
||||||
static components = { SubChild };
|
static components = { SubChild };
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><t t-if="state.flag"><Child val="state.val"/></t></div>`;
|
static template = xml`<div><t t-if="state.flag"><Child val="state.val"/></t></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ flag: true, val: "Framboise Lindemans" });
|
state = useState({ flag: true, val: "Framboise Lindemans" });
|
||||||
@@ -396,18 +396,18 @@ describe("async rendering", () => {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
let destroyCount = 0;
|
let destroyCount = 0;
|
||||||
class ChildA extends Component<any, any> {
|
class ChildA extends Component {
|
||||||
destroy() {
|
destroy() {
|
||||||
destroyCount++;
|
destroyCount++;
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ChildB extends Component<any, any> {
|
class ChildB extends Component {
|
||||||
willStart(): any {
|
willStart(): any {
|
||||||
return new Promise(function() {});
|
return new Promise(function() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { ChildA, ChildB };
|
static components = { ChildA, ChildB };
|
||||||
state = useState({ valA: 1, valB: 2, flag: false });
|
state = useState({ valA: 1, valB: 2, flag: false });
|
||||||
}
|
}
|
||||||
@@ -426,11 +426,11 @@ describe("async rendering", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("rendering component again in next microtick", async () => {
|
test("rendering component again in next microtick", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div t-name="Child">Child</div>`;
|
static template = xml`<div t-name="Child">Child</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="onClick">Click</button>
|
<button t-on-click="onClick">Click</button>
|
||||||
@@ -458,7 +458,7 @@ describe("async rendering", () => {
|
|||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let stateB;
|
let stateB;
|
||||||
|
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="someValue()"/></span>`;
|
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="someValue()"/></span>`;
|
||||||
someValue() {
|
someValue() {
|
||||||
return this.props.fromB;
|
return this.props.fromB;
|
||||||
@@ -469,7 +469,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentC.prototype.someValue = jest.fn(ComponentC.prototype.someValue);
|
ComponentC.prototype.someValue = jest.fn(ComponentC.prototype.someValue);
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
||||||
state = useState({ fromB: "b" });
|
state = useState({ fromB: "b" });
|
||||||
@@ -480,7 +480,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -514,14 +514,14 @@ describe("async rendering", () => {
|
|||||||
const defs = [makeDeferred(), makeDeferred()];
|
const defs = [makeDeferred(), makeDeferred()];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let stateB;
|
let stateB;
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromB"/></span>`;
|
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromB"/></span>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return defs[index++];
|
return defs[index++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
state = useState({ fromB: "b" });
|
state = useState({ fromB: "b" });
|
||||||
@@ -532,7 +532,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static template = xml`<div><t t-esc="state.fromA"/><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><t t-esc="state.fromA"/><ComponentB fromA="state.fromA"/></div>`;
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -564,14 +564,14 @@ describe("async rendering", () => {
|
|||||||
const defs = [makeDeferred(), makeDeferred()];
|
const defs = [makeDeferred(), makeDeferred()];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let stateB;
|
let stateB;
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromB"/></span>`;
|
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromB"/></span>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return defs[index++];
|
return defs[index++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
static template = xml`<p><ComponentC fromA="props.fromA" fromB="state.fromB" /></p>`;
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
state = useState({ fromB: "b" });
|
state = useState({ fromB: "b" });
|
||||||
@@ -582,7 +582,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -616,7 +616,7 @@ describe("async rendering", () => {
|
|||||||
let index = 0;
|
let index = 0;
|
||||||
let stateC;
|
let stateC;
|
||||||
|
|
||||||
class ComponentD extends Component<any, any> {
|
class ComponentD extends Component {
|
||||||
static template = xml`<i><t t-esc="props.fromA"/><t t-esc="someValue()"/></i>`;
|
static template = xml`<i><t t-esc="props.fromA"/><t t-esc="someValue()"/></i>`;
|
||||||
someValue() {
|
someValue() {
|
||||||
return this.props.fromC;
|
return this.props.fromC;
|
||||||
@@ -627,7 +627,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentD.prototype.someValue = jest.fn(ComponentD.prototype.someValue);
|
ComponentD.prototype.someValue = jest.fn(ComponentD.prototype.someValue);
|
||||||
|
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><ComponentD fromA="props.fromA" fromC="state.fromC" /></span>`;
|
static template = xml`<span><ComponentD fromA="props.fromA" fromC="state.fromC" /></span>`;
|
||||||
static components = { ComponentD };
|
static components = { ComponentD };
|
||||||
state = useState({ fromC: "c" });
|
state = useState({ fromC: "c" });
|
||||||
@@ -637,7 +637,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><ComponentC fromA="props.fromA" /></p>`;
|
static template = xml`<p><ComponentC fromA="props.fromA" /></p>`;
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -686,7 +686,7 @@ describe("async rendering", () => {
|
|||||||
let index = 0;
|
let index = 0;
|
||||||
let stateC;
|
let stateC;
|
||||||
|
|
||||||
class ComponentD extends Component<any, any> {
|
class ComponentD extends Component {
|
||||||
static template = xml`<i><t t-esc="props.fromA"/><t t-esc="someValue()"/></i>`;
|
static template = xml`<i><t t-esc="props.fromA"/><t t-esc="someValue()"/></i>`;
|
||||||
someValue() {
|
someValue() {
|
||||||
return this.props.fromC;
|
return this.props.fromC;
|
||||||
@@ -697,7 +697,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentD.prototype.someValue = jest.fn(ComponentD.prototype.someValue);
|
ComponentD.prototype.someValue = jest.fn(ComponentD.prototype.someValue);
|
||||||
|
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><ComponentD fromA="props.fromA" fromC="state.fromC" /></span>`;
|
static template = xml`<span><ComponentD fromA="props.fromA" fromC="state.fromC" /></span>`;
|
||||||
static components = { ComponentD };
|
static components = { ComponentD };
|
||||||
state = useState({ fromC: "c" });
|
state = useState({ fromC: "c" });
|
||||||
@@ -707,7 +707,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><ComponentC fromA="props.fromA" /></p>`;
|
static template = xml`<p><ComponentC fromA="props.fromA" /></p>`;
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
|
|
||||||
@@ -716,7 +716,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -754,7 +754,7 @@ describe("async rendering", () => {
|
|||||||
const defsB = [makeDeferred(), makeDeferred()];
|
const defsB = [makeDeferred(), makeDeferred()];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><t t-esc="someValue()" /></p>`;
|
static template = xml`<p><t t-esc="someValue()" /></p>`;
|
||||||
someValue() {
|
someValue() {
|
||||||
return this.props.fromA;
|
return this.props.fromA;
|
||||||
@@ -765,7 +765,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -799,7 +799,7 @@ describe("async rendering", () => {
|
|||||||
const defsB = [makeDeferred(), makeDeferred()];
|
const defsB = [makeDeferred(), makeDeferred()];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><t t-esc="someValue()" /></p>`;
|
static template = xml`<p><t t-esc="someValue()" /></p>`;
|
||||||
someValue() {
|
someValue() {
|
||||||
return this.props.fromA;
|
return this.props.fromA;
|
||||||
@@ -810,7 +810,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -841,7 +841,7 @@ describe("async rendering", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("concurrent renderings scenario 7", async () => {
|
test("concurrent renderings scenario 7", async () => {
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><t t-esc="props.fromA" /><t t-esc="someValue()" /></p>`;
|
static template = xml`<p><t t-esc="props.fromA" /><t t-esc="someValue()" /></p>`;
|
||||||
state = useState({ fromB: "b" });
|
state = useState({ fromB: "b" });
|
||||||
someValue() {
|
someValue() {
|
||||||
@@ -853,7 +853,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
ComponentB.prototype.someValue = jest.fn(ComponentB.prototype.someValue);
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -874,7 +874,7 @@ describe("async rendering", () => {
|
|||||||
test("concurrent renderings scenario 8", async () => {
|
test("concurrent renderings scenario 8", async () => {
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let stateB;
|
let stateB;
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><t t-esc="props.fromA" /><t t-esc="state.fromB" /></p>`;
|
static template = xml`<p><t t-esc="props.fromA" /><t t-esc="state.fromB" /></p>`;
|
||||||
state = useState({ fromB: "b" });
|
state = useState({ fromB: "b" });
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
@@ -886,7 +886,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
static template = xml`<div><ComponentB fromA="state.fromA"/></div>`;
|
||||||
state = useState({ fromA: 1 });
|
state = useState({ fromA: 1 });
|
||||||
@@ -925,10 +925,10 @@ describe("async rendering", () => {
|
|||||||
// re-rendering
|
// re-rendering
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let stateC;
|
let stateC;
|
||||||
class ComponentD extends Component<any, any> {
|
class ComponentD extends Component {
|
||||||
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromC"/></span>`;
|
static template = xml`<span><t t-esc="props.fromA"/><t t-esc="props.fromC"/></span>`;
|
||||||
}
|
}
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<p><ComponentD fromA="props.fromA" fromC="state.fromC" /></p>`;
|
static template = xml`<p><ComponentD fromA="props.fromA" fromC="state.fromC" /></p>`;
|
||||||
static components = { ComponentD };
|
static components = { ComponentD };
|
||||||
state = useState({ fromC: "b1" });
|
state = useState({ fromC: "b1" });
|
||||||
@@ -938,13 +938,13 @@ describe("async rendering", () => {
|
|||||||
stateC = this.state;
|
stateC = this.state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<b><t t-esc="props.fromA"/></b>`;
|
static template = xml`<b><t t-esc="props.fromA"/></b>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-esc="state.fromA"/>
|
<t t-esc="state.fromA"/>
|
||||||
@@ -991,14 +991,14 @@ describe("async rendering", () => {
|
|||||||
const defB = makeDeferred();
|
const defB = makeDeferred();
|
||||||
const defC = makeDeferred();
|
const defC = makeDeferred();
|
||||||
let stateB;
|
let stateB;
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><t t-esc="props.value"/></span>`;
|
static template = xml`<span><t t-esc="props.value"/></span>`;
|
||||||
willStart() {
|
willStart() {
|
||||||
return defC;
|
return defC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ComponentC.prototype.__render = jest.fn(ComponentC.prototype.__render);
|
ComponentC.prototype.__render = jest.fn(ComponentC.prototype.__render);
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static template = xml`<p><ComponentC t-if="state.hasChild" value="props.value"/></p>`;
|
static template = xml`<p><ComponentC t-if="state.hasChild" value="props.value"/></p>`;
|
||||||
state = useState({ hasChild: false });
|
state = useState({ hasChild: false });
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
@@ -1010,7 +1010,7 @@ describe("async rendering", () => {
|
|||||||
return defB;
|
return defB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static template = xml`<div><ComponentB value="state.value"/></div>`;
|
static template = xml`<div><ComponentB value="state.value"/></div>`;
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
@@ -1042,7 +1042,7 @@ describe("async rendering", () => {
|
|||||||
// remapped to the promise of the ambient rendering)
|
// remapped to the promise of the ambient rendering)
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let child;
|
let child;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/>|<t t-esc="val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/>|<t t-esc="val"/></span>`;
|
||||||
val = 3;
|
val = 3;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
@@ -1051,7 +1051,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child val="state.valA"/></div>`;
|
static template = xml`<div><Child val="state.valA"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ valA: 1 });
|
state = useState({ valA: 1 });
|
||||||
@@ -1079,14 +1079,14 @@ describe("async rendering", () => {
|
|||||||
// rendered but not completed yet)
|
// rendered but not completed yet)
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child val="state.val"/></div>`;
|
static template = xml`<div><Child val="state.val"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ val: 1 });
|
state = useState({ val: 1 });
|
||||||
@@ -1117,7 +1117,7 @@ describe("async rendering", () => {
|
|||||||
|
|
||||||
test("concurrent renderings scenario 13", async () => {
|
test("concurrent renderings scenario 13", async () => {
|
||||||
let lastChild;
|
let lastChild;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="state.val"/></span>`;
|
static template = xml`<span><t t-esc="state.val"/></span>`;
|
||||||
state = useState({ val: 0 });
|
state = useState({ val: 0 });
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -1129,7 +1129,7 @@ describe("async rendering", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<Child/>
|
<Child/>
|
||||||
@@ -1153,7 +1153,7 @@ describe("async rendering", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("change state and call manually render: no unnecessary rendering", async () => {
|
test("change state and call manually render: no unnecessary rendering", async () => {
|
||||||
class Widget extends Component<any, any> {
|
class Widget extends Component {
|
||||||
static template = xml`<div><t t-esc="state.val"/></div>`;
|
static template = xml`<div><t t-esc="state.val"/></div>`;
|
||||||
state = useState({ val: 1 });
|
state = useState({ val: 1 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe("class and style attributes with t-component", () => {
|
describe("class and style attributes with t-component", () => {
|
||||||
test("class is properly added on widget root el", async () => {
|
test("class is properly added on widget root el", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div class="c"/>`;
|
static template = xml`<div class="c"/>`;
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static template = xml`<div><Child class="a b"/></div>`;
|
static template = xml`<div><Child class="a b"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -41,10 +41,10 @@ describe("class and style attributes with t-component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("empty class attribute is not added on widget root el", async () => {
|
test("empty class attribute is not added on widget root el", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span/>`;
|
static template = xml`<span/>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child class=""/></div>`;
|
static template = xml`<div><Child class=""/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -54,10 +54,10 @@ describe("class and style attributes with t-component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("t-att-class is properly added/removed on widget root el", async () => {
|
test("t-att-class is properly added/removed on widget root el", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div class="c"/>`;
|
static template = xml`<div class="c"/>`;
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static template = xml`<div><Child t-att-class="{a:state.a, b:state.b}"/></div>`;
|
static template = xml`<div><Child t-att-class="{a:state.a, b:state.b}"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ a: true, b: false });
|
state = useState({ a: true, b: false });
|
||||||
@@ -80,8 +80,8 @@ describe("class and style attributes with t-component", () => {
|
|||||||
<Child class="a b c d"/>
|
<Child class="a b c d"/>
|
||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
class Child extends Component<any, any> {}
|
class Child extends Component {}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
env.qweb.addTemplate("Child", `<div/>`);
|
env.qweb.addTemplate("Child", `<div/>`);
|
||||||
@@ -99,10 +99,10 @@ describe("class and style attributes with t-component", () => {
|
|||||||
<span t-name="Child" class="c" t-att-class="{ d: state.d }"/>
|
<span t-name="Child" class="c" t-att-class="{ d: state.d }"/>
|
||||||
</templates>`);
|
</templates>`);
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
state = useState({ d: true });
|
state = useState({ d: true });
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ b: true });
|
state = useState({ b: true });
|
||||||
child = useRef("child");
|
child = useRef("child");
|
||||||
@@ -141,10 +141,10 @@ describe("class and style attributes with t-component", () => {
|
|||||||
<span t-name="Child" class="c" t-att-class="state.d ? 'd' : ''"/>
|
<span t-name="Child" class="c" t-att-class="state.d ? 'd' : ''"/>
|
||||||
</templates>`);
|
</templates>`);
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
state = useState({ d: true });
|
state = useState({ d: true });
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ b: true });
|
state = useState({ b: true });
|
||||||
child = useRef("child");
|
child = useRef("child");
|
||||||
@@ -180,7 +180,7 @@ describe("class and style attributes with t-component", () => {
|
|||||||
<div t-name="App" t-att-class="{ c: state.c }" />
|
<div t-name="App" t-att-class="{ c: state.c }" />
|
||||||
</templates>`);
|
</templates>`);
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
state = useState({ c: true });
|
state = useState({ c: true });
|
||||||
mounted() {
|
mounted() {
|
||||||
this.el!.classList.add("user");
|
this.el!.classList.add("user");
|
||||||
@@ -207,11 +207,11 @@ describe("class and style attributes with t-component", () => {
|
|||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
|
|
||||||
class SomeComponent extends Component<any, any> {
|
class SomeComponent extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { child: SomeComponent };
|
static components = { child: SomeComponent };
|
||||||
}
|
}
|
||||||
const widget = new ParentWidget();
|
const widget = new ParentWidget();
|
||||||
@@ -228,11 +228,11 @@ describe("class and style attributes with t-component", () => {
|
|||||||
</div>`
|
</div>`
|
||||||
);
|
);
|
||||||
|
|
||||||
class SomeComponent extends Component<any, any> {
|
class SomeComponent extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { child: SomeComponent };
|
static components = { child: SomeComponent };
|
||||||
state = useState({ style: "font-size: 20px" });
|
state = useState({ style: "font-size: 20px" });
|
||||||
}
|
}
|
||||||
@@ -250,10 +250,10 @@ describe("class and style attributes with t-component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("error in subcomponent with class", async () => {
|
test("error in subcomponent with class", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div t-esc="this.will.crash"/>`;
|
static template = xml`<div t-esc="this.will.crash"/>`;
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static template = xml`<div><Child class="a"/></div>`;
|
static template = xml`<div><Child class="a"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
|
|||||||
+254
-254
File diff suppressed because it is too large
Load Diff
@@ -41,10 +41,10 @@ describe("component error handling (catchError)", () => {
|
|||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
const handler = jest.fn();
|
const handler = jest.fn();
|
||||||
env.qweb.on("error", null, handler);
|
env.qweb.on("error", null, handler);
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div>hey<t t-esc="props.flag and state.this.will.crash"/></div>`;
|
static template = xml`<div>hey<t t-esc="props.flag and state.this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.error">Error handled</t>
|
<t t-if="state.error">Error handled</t>
|
||||||
@@ -56,7 +56,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<ErrorBoundary><ErrorComponent flag="state.flag"/></ErrorBoundary>
|
<ErrorBoundary><ErrorComponent flag="state.flag"/></ErrorBoundary>
|
||||||
@@ -83,11 +83,11 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
|
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div>hey<t t-esc="props.flag and state.this.will.crash"/></div>`;
|
static template = xml`<div>hey<t t-esc="props.flag and state.this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><ErrorComponent flag="state.flag"/></div>`;
|
static template = xml`<div><ErrorComponent flag="state.flag"/></div>`;
|
||||||
static components = { ErrorComponent };
|
static components = { ErrorComponent };
|
||||||
state = useState({ flag: false });
|
state = useState({ flag: false });
|
||||||
@@ -117,10 +117,10 @@ describe("component error handling (catchError)", () => {
|
|||||||
env.qweb.on("error", null, handler);
|
env.qweb.on("error", null, handler);
|
||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div>hey<t t-esc="state.this.will.crash"/></div>`;
|
static template = xml`<div>hey<t t-esc="state.this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.error">Error handled</t>
|
<t t-if="state.error">Error handled</t>
|
||||||
@@ -132,7 +132,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
||||||
@@ -153,10 +153,10 @@ describe("component error handling (catchError)", () => {
|
|||||||
env.qweb.on("error", null, handler);
|
env.qweb.on("error", null, handler);
|
||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div>hey<t t-esc="state.this.will.crash"/></div>`;
|
static template = xml`<div>hey<t t-esc="state.this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.error">Error handled</t>
|
<t t-if="state.error">Error handled</t>
|
||||||
@@ -168,7 +168,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<ErrorBoundary t-if="state.flag"><ErrorComponent /></ErrorBoundary>
|
<ErrorBoundary t-if="state.flag"><ErrorComponent /></ErrorBoundary>
|
||||||
@@ -203,20 +203,20 @@ describe("component error handling (catchError)", () => {
|
|||||||
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
</templates>`);
|
</templates>`);
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
constructor(parent) {
|
constructor(parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
throw new Error("NOOOOO");
|
throw new Error("NOOOOO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
state = useState({ error: false });
|
state = useState({ error: false });
|
||||||
|
|
||||||
catchError() {
|
catchError() {
|
||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { ErrorBoundary, ErrorComponent };
|
static components = { ErrorBoundary, ErrorComponent };
|
||||||
}
|
}
|
||||||
const app = new App();
|
const app = new App();
|
||||||
@@ -231,7 +231,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
test("can catch an error in the willStart call", async () => {
|
test("can catch an error in the willStart call", async () => {
|
||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div t-name="ErrorComponent">Some text</div>`;
|
static template = xml`<div t-name="ErrorComponent">Some text</div>`;
|
||||||
async willStart() {
|
async willStart() {
|
||||||
// we wait a little bit to be in a different stack frame
|
// we wait a little bit to be in a different stack frame
|
||||||
@@ -239,7 +239,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
throw new Error("NOOOOO");
|
throw new Error("NOOOOO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.error">Error handled</t>
|
<t t-if="state.error">Error handled</t>
|
||||||
@@ -251,7 +251,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><ErrorBoundary><ErrorComponent /></ErrorBoundary></div>`;
|
static template = xml`<div><ErrorBoundary><ErrorComponent /></ErrorBoundary></div>`;
|
||||||
static components = { ErrorBoundary, ErrorComponent };
|
static components = { ErrorBoundary, ErrorComponent };
|
||||||
}
|
}
|
||||||
@@ -277,19 +277,19 @@ describe("component error handling (catchError)", () => {
|
|||||||
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
<ErrorBoundary><ErrorComponent /></ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
</templates>`);
|
</templates>`);
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
mounted() {
|
mounted() {
|
||||||
throw new Error("NOOOOO");
|
throw new Error("NOOOOO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
state = useState({ error: false });
|
state = useState({ error: false });
|
||||||
|
|
||||||
catchError() {
|
catchError() {
|
||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { ErrorBoundary, ErrorComponent };
|
static components = { ErrorBoundary, ErrorComponent };
|
||||||
}
|
}
|
||||||
const app = new App();
|
const app = new App();
|
||||||
@@ -304,13 +304,13 @@ describe("component error handling (catchError)", () => {
|
|||||||
// we do not catch error in willPatch anymore
|
// we do not catch error in willPatch anymore
|
||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn();
|
console.error = jest.fn();
|
||||||
class ErrorComponent extends Component<any, any> {
|
class ErrorComponent extends Component {
|
||||||
static template = xml`<div><t t-esc="props.message"/></div>`;
|
static template = xml`<div><t t-esc="props.message"/></div>`;
|
||||||
willPatch() {
|
willPatch() {
|
||||||
throw new Error("NOOOOO");
|
throw new Error("NOOOOO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ErrorBoundary extends Component<any, any> {
|
class ErrorBoundary extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.error">Error handled</t>
|
<t t-if="state.error">Error handled</t>
|
||||||
@@ -322,7 +322,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
this.state.error = true;
|
this.state.error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span><t t-esc="state.message"/></span>
|
<span><t t-esc="state.message"/></span>
|
||||||
@@ -347,7 +347,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
// we do not catch error in willPatch anymore
|
// we do not catch error in willPatch anymore
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
|
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div>abc</div>`;
|
static template = xml`<div>abc</div>`;
|
||||||
mounted() {
|
mounted() {
|
||||||
throw new Error("boom");
|
throw new Error("boom");
|
||||||
@@ -395,7 +395,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="val"/></div>`;
|
static template = xml`<div><t t-esc="val"/></div>`;
|
||||||
val = 3;
|
val = 3;
|
||||||
willPatch() {
|
willPatch() {
|
||||||
@@ -424,7 +424,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="val"/></div>`;
|
static template = xml`<div><t t-esc="val"/></div>`;
|
||||||
val = 3;
|
val = 3;
|
||||||
patched() {
|
patched() {
|
||||||
@@ -453,10 +453,10 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
// we do not catch error in willPatch anymore
|
// we do not catch error in willPatch anymore
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
|
static template = xml`<div><t t-esc="this.will.crash"/></div>`;
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Child/></div>`;
|
static template = xml`<div><Child/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -479,7 +479,7 @@ describe("component error handling (catchError)", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
// we do not catch error in willPatch anymore
|
// we do not catch error in willPatch anymore
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-if="flag" t-esc="this.will.crash"/></div>`;
|
static template = xml`<div><t t-if="flag" t-esc="this.will.crash"/></div>`;
|
||||||
flag = false;
|
flag = false;
|
||||||
}
|
}
|
||||||
@@ -502,10 +502,10 @@ describe("component error handling (catchError)", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("a rendering error will reject the render promise (with sub components)", async () => {
|
test("a rendering error will reject the render promise (with sub components)", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span></span>`;
|
static template = xml`<span></span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child/><t t-esc="x.y"/></div>`;
|
static template = xml`<div><Child/><t t-esc="x.y"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ afterEach(() => {
|
|||||||
QWeb.dev = dev;
|
QWeb.dev = dev;
|
||||||
});
|
});
|
||||||
|
|
||||||
class Widget extends Component<any, any> {}
|
class Widget extends Component {}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Tests
|
// Tests
|
||||||
@@ -96,7 +96,7 @@ describe("props validation", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let props;
|
let props;
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
get p() {
|
get p() {
|
||||||
return props.p;
|
return props.p;
|
||||||
@@ -153,14 +153,14 @@ describe("props validation", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let props;
|
let props;
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
get p() {
|
get p() {
|
||||||
return props.p;
|
return props.p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let test of Tests) {
|
for (let test of Tests) {
|
||||||
let TestWidget = class extends Component<any, any> {
|
let TestWidget = class extends Component {
|
||||||
static props = { p: { type: test.type } };
|
static props = { p: { type: test.type } };
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
};
|
};
|
||||||
@@ -200,11 +200,11 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate a prop with multiple types", async () => {
|
test("can validate a prop with multiple types", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = { p: [String, Boolean] };
|
static props = { p: [String, Boolean] };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -244,11 +244,11 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate an optional props", async () => {
|
test("can validate an optional props", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = { p: { type: String, optional: true } };
|
static props = { p: { type: String, optional: true } };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -288,11 +288,11 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate an array with given primitive type", async () => {
|
test("can validate an array with given primitive type", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = { p: { type: Array, element: String } };
|
static props = { p: { type: Array, element: String } };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -340,11 +340,11 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate an array with multiple sub element types", async () => {
|
test("can validate an array with multiple sub element types", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = { p: { type: Array, element: [String, Boolean] } };
|
static props = { p: { type: Array, element: [String, Boolean] } };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -393,13 +393,13 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate an object with simple shape", async () => {
|
test("can validate an object with simple shape", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = {
|
static props = {
|
||||||
p: { type: Object, shape: { id: Number, url: String } }
|
p: { type: Object, shape: { id: Number, url: String } }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -451,7 +451,7 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate recursively complicated prop def", async () => {
|
test("can validate recursively complicated prop def", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
static props = {
|
static props = {
|
||||||
p: {
|
p: {
|
||||||
@@ -463,7 +463,7 @@ describe("props validation", () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="p"/></div>`;
|
static template = xml`<div><TestWidget p="p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
get p() {
|
get p() {
|
||||||
@@ -503,7 +503,7 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate optional attributes in nested sub props", () => {
|
test("can validate optional attributes in nested sub props", () => {
|
||||||
class TestComponent extends Component<any, any> {
|
class TestComponent extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
myprop: {
|
myprop: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -536,7 +536,7 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can validate with a custom validator", () => {
|
test("can validate with a custom validator", () => {
|
||||||
class TestComponent extends Component<any, any> {
|
class TestComponent extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
size: {
|
size: {
|
||||||
validate: e => ["small", "medium", "large"].includes(e)
|
validate: e => ["small", "medium", "large"].includes(e)
|
||||||
@@ -562,7 +562,7 @@ describe("props validation", () => {
|
|||||||
|
|
||||||
test("can validate with a custom validator, and a type", () => {
|
test("can validate with a custom validator, and a type", () => {
|
||||||
const validator = jest.fn(n => 0 <= n && n <= 10);
|
const validator = jest.fn(n => 0 <= n && n <= 10);
|
||||||
class TestComponent extends Component<any, any> {
|
class TestComponent extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
n: {
|
n: {
|
||||||
type: Number,
|
type: Number,
|
||||||
@@ -738,7 +738,7 @@ describe("props validation", () => {
|
|||||||
|
|
||||||
test("props are validated whenever component is updated", async () => {
|
test("props are validated whenever component is updated", async () => {
|
||||||
let error;
|
let error;
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static props = { p: { type: Number } };
|
static props = { p: { type: Number } };
|
||||||
static template = xml`<div><t t-esc="props.p"/></div>`;
|
static template = xml`<div><t t-esc="props.p"/></div>`;
|
||||||
|
|
||||||
@@ -750,7 +750,7 @@ describe("props validation", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="state.p"/></div>`;
|
static template = xml`<div><TestWidget p="state.p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
state: any = useState({ p: 1 });
|
state: any = useState({ p: 1 });
|
||||||
@@ -767,12 +767,12 @@ describe("props validation", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("default values are applied before validating props at update", async () => {
|
test("default values are applied before validating props at update", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static props = { p: { type: Number } };
|
static props = { p: { type: Number } };
|
||||||
static template = xml`<div><t t-esc="props.p"/></div>`;
|
static template = xml`<div><t t-esc="props.p"/></div>`;
|
||||||
static defaultProps = { p: 4 };
|
static defaultProps = { p: 4 };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget p="state.p"/></div>`;
|
static template = xml`<div><TestWidget p="state.p"/></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
state: any = useState({ p: 1 });
|
state: any = useState({ p: 1 });
|
||||||
@@ -790,11 +790,11 @@ describe("props validation", () => {
|
|||||||
|
|
||||||
describe("default props", () => {
|
describe("default props", () => {
|
||||||
test("can set default values", async () => {
|
test("can set default values", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static defaultProps = { p: 4 };
|
static defaultProps = { p: 4 };
|
||||||
static template = xml`<div><t t-esc="props.p"/></div>`;
|
static template = xml`<div><t t-esc="props.p"/></div>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><TestWidget /></div>`;
|
static template = xml`<div><TestWidget /></div>`;
|
||||||
static components = { TestWidget };
|
static components = { TestWidget };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ afterEach(() => {
|
|||||||
fixture.remove();
|
fixture.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
function children(w: Component<any, any>): Component<any, any>[] {
|
function children(w: Component): Component[] {
|
||||||
const childrenMap = w.__owl__.children;
|
const childrenMap = w.__owl__.children;
|
||||||
return Object.keys(childrenMap).map(id => childrenMap[id]);
|
return Object.keys(childrenMap).map(id => childrenMap[id]);
|
||||||
}
|
}
|
||||||
@@ -51,8 +51,8 @@ describe("t-slot directive", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -68,13 +68,13 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("named slots can define a default content", async () => {
|
test("named slots can define a default content", async () => {
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>
|
<span>
|
||||||
<t t-slot="header">default content</t>
|
<t t-slot="header">default content</t>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Dialog/></div>`;
|
static template = xml`<div><Dialog/></div>`;
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
@@ -86,13 +86,13 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("dafault slots can define a default content", async () => {
|
test("dafault slots can define a default content", async () => {
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>
|
<span>
|
||||||
<t t-slot="default">default content</t>
|
<t t-slot="default">default content</t>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Dialog/></div>`;
|
static template = xml`<div><Dialog/></div>`;
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
@@ -104,13 +104,13 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("default content is not rendered if slot is provided", async () => {
|
test("default content is not rendered if slot is provided", async () => {
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>
|
<span>
|
||||||
<t t-slot="default">default content</t>
|
<t t-slot="default">default content</t>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Dialog>hey</Dialog></div>`;
|
static template = xml`<div><Dialog>hey</Dialog></div>`;
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
@@ -121,13 +121,13 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("default content is not rendered if named slot is provided", async () => {
|
test("default content is not rendered if named slot is provided", async () => {
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>
|
<span>
|
||||||
<t t-slot="header">default content</t>
|
<t t-slot="header">default content</t>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Dialog><t t-set="header">hey</t></Dialog></div>`;
|
static template = xml`<div><Dialog><t t-set="header">hey</t></Dialog></div>`;
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
@@ -149,8 +149,8 @@ describe("t-slot directive", () => {
|
|||||||
<span t-name="Dialog"><t t-slot="footer"/></span>
|
<span t-name="Dialog"><t t-slot="footer"/></span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
state = useState({ val: 0 });
|
state = useState({ val: 0 });
|
||||||
doSomething() {
|
doSomething() {
|
||||||
@@ -186,9 +186,9 @@ describe("t-slot directive", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Link extends Component<any, any> {}
|
class Link extends Component {}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
state = useState({
|
state = useState({
|
||||||
users: [
|
users: [
|
||||||
{ id: 1, name: "Aaron" },
|
{ id: 1, name: "Aaron" },
|
||||||
@@ -230,9 +230,9 @@ describe("t-slot directive", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Link extends Component<any, any> {}
|
class Link extends Component {}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
state = useState({
|
state = useState({
|
||||||
users: [
|
users: [
|
||||||
{ id: 1, name: "Aaron" },
|
{ id: 1, name: "Aaron" },
|
||||||
@@ -272,9 +272,9 @@ describe("t-slot directive", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Link extends Component<any, any> {}
|
class Link extends Component {}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
state = useState({ user: { id: 1, name: "Aaron" } });
|
state = useState({ user: { id: 1, name: "Aaron" } });
|
||||||
static components = { Link };
|
static components = { Link };
|
||||||
}
|
}
|
||||||
@@ -294,10 +294,10 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("refs are properly bound in slots", async () => {
|
test("refs are properly bound in slots", async () => {
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`<span><t t-slot="footer"/></span>`;
|
static template = xml`<span><t t-slot="footer"/></span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span class="counter"><t t-esc="state.val"/></span>
|
<span class="counter"><t t-esc="state.val"/></span>
|
||||||
@@ -340,8 +340,8 @@ describe("t-slot directive", () => {
|
|||||||
<div t-name="Dialog"><t t-slot="default"/></div>
|
<div t-name="Dialog"><t t-slot="default"/></div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -360,8 +360,8 @@ describe("t-slot directive", () => {
|
|||||||
<div t-name="Dialog"><t t-slot="default"/></div>
|
<div t-name="Dialog"><t t-slot="default"/></div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -385,8 +385,8 @@ describe("t-slot directive", () => {
|
|||||||
<div t-name="Dialog"><t t-slot="content"/></div>
|
<div t-name="Dialog"><t t-slot="content"/></div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -408,8 +408,8 @@ describe("t-slot directive", () => {
|
|||||||
<div t-name="Dialog"><t t-slot="default"/></div>
|
<div t-name="Dialog"><t t-slot="default"/></div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -432,8 +432,8 @@ describe("t-slot directive", () => {
|
|||||||
</span>
|
</span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -456,8 +456,8 @@ describe("t-slot directive", () => {
|
|||||||
</span>
|
</span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Dialog extends Component<any, any> {}
|
class Dialog extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Dialog };
|
static components = { Dialog };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -478,9 +478,9 @@ describe("t-slot directive", () => {
|
|||||||
<div t-name="GrandChild">Grand Child</div>
|
<div t-name="GrandChild">Grand Child</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Child extends Component<any, any> {}
|
class Child extends Component {}
|
||||||
class GrandChild extends Component<any, any> {}
|
class GrandChild extends Component {}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child, GrandChild };
|
static components = { Child, GrandChild };
|
||||||
}
|
}
|
||||||
const parent = new Parent();
|
const parent = new Parent();
|
||||||
@@ -499,24 +499,24 @@ describe("t-slot directive", () => {
|
|||||||
|
|
||||||
test("nested slots: evaluation context and parented relationship", async () => {
|
test("nested slots: evaluation context and parented relationship", async () => {
|
||||||
let slot;
|
let slot;
|
||||||
class Slot extends Component<any, any> {
|
class Slot extends Component {
|
||||||
static template = xml`<span t-esc="props.val"/>`;
|
static template = xml`<span t-esc="props.val"/>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
slot = this;
|
slot = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class GrandChild extends Component<any, any> {
|
class GrandChild extends Component {
|
||||||
static template = xml`<div><t t-slot="default"/></div>`;
|
static template = xml`<div><t t-slot="default"/></div>`;
|
||||||
}
|
}
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static components = { GrandChild };
|
static components = { GrandChild };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<GrandChild>
|
<GrandChild>
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
</GrandChild>`;
|
</GrandChild>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child, Slot };
|
static components = { Child, Slot };
|
||||||
static template = xml`<Child><Slot val="state.val"/></Child>`;
|
static template = xml`<Child><Slot val="state.val"/></Child>`;
|
||||||
state = useState({ val: 3 });
|
state = useState({ val: 3 });
|
||||||
@@ -548,9 +548,9 @@ describe("t-slot directive", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class SomeComponent extends Component<any, any> {}
|
class SomeComponent extends Component {}
|
||||||
class GenericComponent extends Component<any, any> {}
|
class GenericComponent extends Component {}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { GenericComponent, SomeComponent };
|
static components = { GenericComponent, SomeComponent };
|
||||||
state = useState({ val: 4 });
|
state = useState({ val: 4 });
|
||||||
|
|
||||||
@@ -568,14 +568,14 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("slots and wrapper components", async () => {
|
test("slots and wrapper components", async () => {
|
||||||
class Link extends Component<any, any> {
|
class Link extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<a href="abc">
|
<a href="abc">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
</a>`;
|
</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class A extends Component<any, any> {
|
class A extends Component {
|
||||||
static template = xml`<Link>hey</Link>`;
|
static template = xml`<Link>hey</Link>`;
|
||||||
static components = { Link: Link };
|
static components = { Link: Link };
|
||||||
}
|
}
|
||||||
@@ -587,14 +587,14 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("template can just return a slot", async () => {
|
test("template can just return a slot", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.value"/></span>`;
|
static template = xml`<span><t t-esc="props.value"/></span>`;
|
||||||
}
|
}
|
||||||
class SlotComponent extends Component<any, any> {
|
class SlotComponent extends Component {
|
||||||
static template = xml`<t t-slot="default"/>`;
|
static template = xml`<t t-slot="default"/>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<SlotComponent><Child value="state.value"/></SlotComponent>
|
<SlotComponent><Child value="state.value"/></SlotComponent>
|
||||||
@@ -614,13 +614,13 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("multiple slots containing components", async () => {
|
test("multiple slots containing components", async () => {
|
||||||
class C extends Component<any, any> {
|
class C extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
}
|
}
|
||||||
class B extends Component<any, any> {
|
class B extends Component {
|
||||||
static template = xml`<div><t t-slot="s1"/><t t-slot="s2"/></div>`;
|
static template = xml`<div><t t-slot="s1"/><t t-slot="s2"/></div>`;
|
||||||
}
|
}
|
||||||
class A extends Component<any, any> {
|
class A extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<B>
|
<B>
|
||||||
<t t-set="s1"><C val="1"/></t>
|
<t t-set="s1"><C val="1"/></t>
|
||||||
@@ -636,14 +636,14 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("slots in t-foreach and re-rendering", async () => {
|
test("slots in t-foreach and re-rendering", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="state.val"/><t t-slot="default"/></span>`;
|
static template = xml`<span><t t-esc="state.val"/><t t-slot="default"/></span>`;
|
||||||
state = useState({ val: "A" });
|
state = useState({ val: "A" });
|
||||||
mounted() {
|
mounted() {
|
||||||
this.state.val = "B";
|
this.state.val = "B";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -661,7 +661,7 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("slots in t-foreach with t-set and re-rendering", async () => {
|
test("slots in t-foreach with t-set and re-rendering", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>
|
<span>
|
||||||
<t t-esc="state.val"/>
|
<t t-esc="state.val"/>
|
||||||
@@ -672,7 +672,7 @@ describe("t-slot directive", () => {
|
|||||||
this.state.val = "B";
|
this.state.val = "B";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -693,7 +693,7 @@ describe("t-slot directive", () => {
|
|||||||
|
|
||||||
test("nested slots in same template", async () => {
|
test("nested slots in same template", async () => {
|
||||||
let child, child2, child3;
|
let child, child2, child3;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c1">
|
<span id="c1">
|
||||||
<div>
|
<div>
|
||||||
@@ -705,7 +705,7 @@ describe("t-slot directive", () => {
|
|||||||
child = this;
|
child = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Child2 extends Component<any, any> {
|
class Child2 extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c2">
|
<span id="c2">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
@@ -715,7 +715,7 @@ describe("t-slot directive", () => {
|
|||||||
child2 = this;
|
child2 = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Child3 extends Component<any, any> {
|
class Child3 extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>Child 3</span>`;
|
<span>Child 3</span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
@@ -723,7 +723,7 @@ describe("t-slot directive", () => {
|
|||||||
child3 = this;
|
child3 = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child, Child2, Child3 };
|
static components = { Child, Child2, Child3 };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="parent">
|
<span id="parent">
|
||||||
@@ -748,7 +748,7 @@ describe("t-slot directive", () => {
|
|||||||
|
|
||||||
test("t-slot nested within another slot", async () => {
|
test("t-slot nested within another slot", async () => {
|
||||||
let portal, modal, child3;
|
let portal, modal, child3;
|
||||||
class Child3 extends Component<any, any> {
|
class Child3 extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>Child 3</span>`;
|
<span>Child 3</span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
@@ -756,7 +756,7 @@ describe("t-slot directive", () => {
|
|||||||
child3 = this;
|
child3 = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Modal extends Component<any, any> {
|
class Modal extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="modal">
|
<span id="modal">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
@@ -766,7 +766,7 @@ describe("t-slot directive", () => {
|
|||||||
modal = this;
|
modal = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Portal extends Component<any, any> {
|
class Portal extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="portal">
|
<span id="portal">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
@@ -776,7 +776,7 @@ describe("t-slot directive", () => {
|
|||||||
portal = this;
|
portal = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static components = { Modal, Portal };
|
static components = { Modal, Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c2">
|
<span id="c2">
|
||||||
@@ -787,7 +787,7 @@ describe("t-slot directive", () => {
|
|||||||
</Modal>
|
</Modal>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child3, Dialog };
|
static components = { Child3, Dialog };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c1">
|
<span id="c1">
|
||||||
@@ -809,7 +809,7 @@ describe("t-slot directive", () => {
|
|||||||
|
|
||||||
test("t-slot supports many instances", async () => {
|
test("t-slot supports many instances", async () => {
|
||||||
let child3;
|
let child3;
|
||||||
class Child3 extends Component<any, any> {
|
class Child3 extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span>Child 3</span>`;
|
<span>Child 3</span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
@@ -817,13 +817,13 @@ describe("t-slot directive", () => {
|
|||||||
child3 = this;
|
child3 = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Dialog extends Component<any, any> {
|
class Dialog extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c2">
|
<span id="c2">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
</span>`;
|
</span>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child3, Dialog };
|
static components = { Child3, Dialog };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span id="c1">
|
<span id="c1">
|
||||||
@@ -845,10 +845,10 @@ describe("t-slot directive", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("slots in slots, with vars", async () => {
|
test("slots in slots, with vars", async () => {
|
||||||
class B extends Component<any, any> {
|
class B extends Component {
|
||||||
static template = xml`<span><t t-slot="default"/></span>`;
|
static template = xml`<span><t t-slot="default"/></span>`;
|
||||||
}
|
}
|
||||||
class A extends Component<any, any> {
|
class A extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<B>
|
<B>
|
||||||
@@ -857,7 +857,7 @@ describe("t-slot directive", () => {
|
|||||||
</div>`;
|
</div>`;
|
||||||
static components = { B };
|
static components = { B };
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-set="test" t-value="state.name"/>
|
<t t-set="test" t-value="state.name"/>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe("styles and component", () => {
|
describe("styles and component", () => {
|
||||||
test("can define an inline stylesheet", async () => {
|
test("can define an inline stylesheet", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div class="app">text</div>`;
|
static template = xml`<div class="app">text</div>`;
|
||||||
static style = css`
|
static style = css`
|
||||||
.app {
|
.app {
|
||||||
@@ -54,7 +54,7 @@ describe("styles and component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("inherited components properly apply css", async () => {
|
test("inherited components properly apply css", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div class="app">text</div>`;
|
static template = xml`<div class="app">text</div>`;
|
||||||
static style = css`
|
static style = css`
|
||||||
.app {
|
.app {
|
||||||
@@ -86,7 +86,7 @@ describe("styles and component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("get a meaningful error message if css helper is missing", async () => {
|
test("get a meaningful error message if css helper is missing", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div class="app">text</div>`;
|
static template = xml`<div class="app">text</div>`;
|
||||||
static style = `.app {color: red;}`;
|
static style = `.app {color: red;}`;
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ describe("styles and component", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("inline stylesheets are processed", async () => {
|
test("inline stylesheets are processed", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div class="app">text</div>`;
|
static template = xml`<div class="app">text</div>`;
|
||||||
static style = css`
|
static style = css`
|
||||||
.app {
|
.app {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe("mount targets", () => {
|
describe("mount targets", () => {
|
||||||
test("can attach a component to an existing node (if same tagname)", async () => {
|
test("can attach a component to an existing node (if same tagname)", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div>app</div>`;
|
static template = xml`<div>app</div>`;
|
||||||
}
|
}
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
@@ -39,7 +39,7 @@ describe("mount targets", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("cannot attach a component to an existing node (if not same tagname)", async () => {
|
test("cannot attach a component to an existing node (if not same tagname)", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<span>app</span>`;
|
static template = xml`<span>app</span>`;
|
||||||
}
|
}
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
@@ -57,7 +57,7 @@ describe("mount targets", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can mount a component (with position='first-child')", async () => {
|
test("can mount a component (with position='first-child')", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div>app</div>`;
|
static template = xml`<div>app</div>`;
|
||||||
}
|
}
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
@@ -69,7 +69,7 @@ describe("mount targets", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can mount a component (with position='last-child')", async () => {
|
test("can mount a component (with position='last-child')", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div>app</div>`;
|
static template = xml`<div>app</div>`;
|
||||||
}
|
}
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
@@ -81,7 +81,7 @@ describe("mount targets", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("default mount option is 'last-child'", async () => {
|
test("default mount option is 'last-child'", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div>app</div>`;
|
static template = xml`<div>app</div>`;
|
||||||
}
|
}
|
||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
@@ -96,7 +96,7 @@ describe("mount targets", () => {
|
|||||||
describe("unmounting and remounting", () => {
|
describe("unmounting and remounting", () => {
|
||||||
test("widget can be unmounted and remounted", async () => {
|
test("widget can be unmounted and remounted", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class MyWidget extends Component<any, any> {
|
class MyWidget extends Component {
|
||||||
static template = xml`<div>Hey</div>`;
|
static template = xml`<div>Hey</div>`;
|
||||||
async willStart() {
|
async willStart() {
|
||||||
steps.push("willstart");
|
steps.push("willstart");
|
||||||
@@ -128,7 +128,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("widget can be mounted twice without ill effect", async () => {
|
test("widget can be mounted twice without ill effect", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class MyWidget extends Component<any, any> {
|
class MyWidget extends Component {
|
||||||
static template = xml`<div>Hey</div>`;
|
static template = xml`<div>Hey</div>`;
|
||||||
async willStart() {
|
async willStart() {
|
||||||
steps.push("willstart");
|
steps.push("willstart");
|
||||||
@@ -151,7 +151,7 @@ describe("unmounting and remounting", () => {
|
|||||||
test("state changes in willUnmount do not trigger rerender", async () => {
|
test("state changes in willUnmount do not trigger rerender", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span><t t-esc="props.val"/><t t-esc="state.n"/></span>
|
<span><t t-esc="props.val"/><t t-esc="state.n"/></span>
|
||||||
`;
|
`;
|
||||||
@@ -172,7 +172,7 @@ describe("unmounting and remounting", () => {
|
|||||||
this.state.n = 3;
|
this.state.n = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<Child t-if="state.flag" val="state.val"/>
|
<Child t-if="state.flag" val="state.val"/>
|
||||||
@@ -193,7 +193,7 @@ describe("unmounting and remounting", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("state changes in willUnmount will be applied on remount", async () => {
|
test("state changes in willUnmount will be applied on remount", async () => {
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div><t t-esc="state.val"/></div>
|
<div><t t-esc="state.val"/></div>
|
||||||
`;
|
`;
|
||||||
@@ -216,7 +216,7 @@ describe("unmounting and remounting", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("sub component is still active after being unmounted and remounted", async () => {
|
test("sub component is still active after being unmounted and remounted", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<p t-on-click="state.value++">
|
<p t-on-click="state.value++">
|
||||||
<t t-esc="state.value"/>
|
<t t-esc="state.value"/>
|
||||||
@@ -225,7 +225,7 @@ describe("unmounting and remounting", () => {
|
|||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
static template = xml`<div><Child/></div>`;
|
static template = xml`<div><Child/></div>`;
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("change state just before mounting component", async () => {
|
test("change state just before mounting component", async () => {
|
||||||
const steps: number[] = [];
|
const steps: number[] = [];
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div><t t-esc="state.val"/></div>
|
<div><t t-esc="state.val"/></div>
|
||||||
`;
|
`;
|
||||||
@@ -278,7 +278,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("change state while mounting component", async () => {
|
test("change state while mounting component", async () => {
|
||||||
const steps: number[] = [];
|
const steps: number[] = [];
|
||||||
class TestWidget extends Component<any, any> {
|
class TestWidget extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div><t t-esc="state.val"/></div>
|
<div><t t-esc="state.val"/></div>
|
||||||
`;
|
`;
|
||||||
@@ -312,7 +312,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("change state while component is unmounted", async () => {
|
test("change state while component is unmounted", async () => {
|
||||||
let child;
|
let child;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span t-esc="state.val"/>`;
|
static template = xml`<span t-esc="state.val"/>`;
|
||||||
state = useState({
|
state = useState({
|
||||||
val: "C1"
|
val: "C1"
|
||||||
@@ -323,7 +323,7 @@ describe("unmounting and remounting", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
static template = xml`<div><t t-esc="state.val"/><Child/></div>`;
|
static template = xml`<div><t t-esc="state.val"/><Child/></div>`;
|
||||||
state = useState({ val: "P1" });
|
state = useState({ val: "P1" });
|
||||||
@@ -345,7 +345,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("unmount component during a re-rendering", async () => {
|
test("unmount component during a re-rendering", async () => {
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return def;
|
return def;
|
||||||
@@ -353,7 +353,7 @@ describe("unmounting and remounting", () => {
|
|||||||
}
|
}
|
||||||
Child.prototype.__render = jest.fn(Child.prototype.__render);
|
Child.prototype.__render = jest.fn(Child.prototype.__render);
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child val="state.val"/></div>`;
|
static template = xml`<div><Child val="state.val"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ val: 1 });
|
state = useState({ val: 1 });
|
||||||
@@ -379,7 +379,7 @@ describe("unmounting and remounting", () => {
|
|||||||
|
|
||||||
test("widget can be mounted on different target", async () => {
|
test("widget can be mounted on different target", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class MyWidget extends Component<any, any> {
|
class MyWidget extends Component {
|
||||||
static template = xml`<div>Hey</div>`;
|
static template = xml`<div>Hey</div>`;
|
||||||
async willStart() {
|
async willStart() {
|
||||||
steps.push("willstart");
|
steps.push("willstart");
|
||||||
|
|||||||
+21
-21
@@ -32,7 +32,7 @@ describe("Context", () => {
|
|||||||
test("very simple use, with initial value", async () => {
|
test("very simple use, with initial value", async () => {
|
||||||
const testContext = new Context({ value: 123 });
|
const testContext = new Context({ value: 123 });
|
||||||
|
|
||||||
class Test extends Component<any, any> {
|
class Test extends Component {
|
||||||
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ describe("Context", () => {
|
|||||||
test("useContext hook is reactive, for one component", async () => {
|
test("useContext hook is reactive, for one component", async () => {
|
||||||
const testContext = new Context({ value: 123 });
|
const testContext = new Context({ value: 123 });
|
||||||
|
|
||||||
class Test extends Component<any, any> {
|
class Test extends Component {
|
||||||
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
static template = xml`<div><t t-esc="contextObj.value"/></div>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
}
|
}
|
||||||
@@ -59,11 +59,11 @@ describe("Context", () => {
|
|||||||
test("two components can subscribe to same context", async () => {
|
test("two components can subscribe to same context", async () => {
|
||||||
const testContext = new Context({ value: 123 });
|
const testContext = new Context({ value: 123 });
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj.value"/></span>`;
|
static template = xml`<span><t t-esc="contextObj.value"/></span>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /><Child /></div>`;
|
static template = xml`<div><Child /><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ describe("Context", () => {
|
|||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj.value"/></span>`;
|
static template = xml`<span><t t-esc="contextObj.value"/></span>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
async render() {
|
async render() {
|
||||||
@@ -90,7 +90,7 @@ describe("Context", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /><Child /></div>`;
|
static template = xml`<div><Child /><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -111,13 +111,13 @@ describe("Context", () => {
|
|||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class SlowComp extends Component<any, any> {
|
class SlowComp extends Component {
|
||||||
static template = xml`<p><t t-esc="props.value"/></p>`;
|
static template = xml`<p><t t-esc="props.value"/></p>`;
|
||||||
willUpdateProps() {
|
willUpdateProps() {
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><SlowComp value="contextObj.value"/></span>`;
|
static template = xml`<span><SlowComp value="contextObj.value"/></span>`;
|
||||||
static components = { SlowComp };
|
static components = { SlowComp };
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
@@ -128,12 +128,12 @@ describe("Context", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /><Child /></div>`;
|
static template = xml`<div><Child /><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Child /><Parent /></div>`;
|
static template = xml`<div><Child /><Parent /></div>`;
|
||||||
static components = { Child, Parent };
|
static components = { Child, Parent };
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,7 @@ describe("Context", () => {
|
|||||||
const testContext = new Context({ a: 1, b: 2 });
|
const testContext = new Context({ a: 1, b: 2 });
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj1.a"/><t t-esc="contextObj2.b"/></span>`;
|
static template = xml`<span><t t-esc="contextObj1.a"/><t t-esc="contextObj2.b"/></span>`;
|
||||||
contextObj1 = useContext(testContext);
|
contextObj1 = useContext(testContext);
|
||||||
contextObj2 = useContext(testContext);
|
contextObj2 = useContext(testContext);
|
||||||
@@ -175,7 +175,7 @@ describe("Context", () => {
|
|||||||
return super.__render(fiber);
|
return super.__render(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /></div>`;
|
static template = xml`<div><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ describe("Context", () => {
|
|||||||
const testContext = new Context({ a: 123, b: 321 });
|
const testContext = new Context({ a: 123, b: 321 });
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
__render(fiber) {
|
__render(fiber) {
|
||||||
@@ -201,7 +201,7 @@ describe("Context", () => {
|
|||||||
return super.__render(fiber);
|
return super.__render(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /><t t-esc="contextObj.b"/></div>`;
|
static template = xml`<div><Child /><t t-esc="contextObj.b"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
@@ -227,7 +227,7 @@ describe("Context", () => {
|
|||||||
const testContext = new Context({ a: 123 });
|
const testContext = new Context({ a: 123 });
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
__render(fiber) {
|
__render(fiber) {
|
||||||
@@ -235,7 +235,7 @@ describe("Context", () => {
|
|||||||
return super.__render(fiber);
|
return super.__render(fiber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
@@ -263,14 +263,14 @@ describe("Context", () => {
|
|||||||
test("destroyed component before being mounted is inactive", async () => {
|
test("destroyed component before being mounted is inactive", async () => {
|
||||||
const testContext = new Context({ a: 123 });
|
const testContext = new Context({ a: 123 });
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
static template = xml`<span><t t-esc="contextObj.a"/></span>`;
|
||||||
contextObj = useContext(testContext);
|
contextObj = useContext(testContext);
|
||||||
willStart() {
|
willStart() {
|
||||||
return makeDeferred();
|
return makeDeferred();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
@@ -293,7 +293,7 @@ describe("Context", () => {
|
|||||||
const testContext = new Context({ x: { n: 1 }, key: "x" });
|
const testContext = new Context({ x: { n: 1 }, key: "x" });
|
||||||
const def = makeDeferred();
|
const def = makeDeferred();
|
||||||
let stateC;
|
let stateC;
|
||||||
class ComponentC extends Component<any, any> {
|
class ComponentC extends Component {
|
||||||
static template = xml`<span><t t-esc="context[props.key].n"/><t t-esc="state.x"/></span>`;
|
static template = xml`<span><t t-esc="context[props.key].n"/><t t-esc="state.x"/></span>`;
|
||||||
context = useContext(testContext);
|
context = useContext(testContext);
|
||||||
state = useState({ x: "a" });
|
state = useState({ x: "a" });
|
||||||
@@ -303,7 +303,7 @@ describe("Context", () => {
|
|||||||
stateC = this.state;
|
stateC = this.state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ComponentB extends Component<any, any> {
|
class ComponentB extends Component {
|
||||||
static components = { ComponentC };
|
static components = { ComponentC };
|
||||||
static template = xml`<p><ComponentC key="props.key"/></p>`;
|
static template = xml`<p><ComponentC key="props.key"/></p>`;
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ describe("Context", () => {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ComponentA extends Component<any, any> {
|
class ComponentA extends Component {
|
||||||
static components = { ComponentB };
|
static components = { ComponentB };
|
||||||
static template = xml`<div><ComponentB key="context.key"/></div>`;
|
static template = xml`<div><ComponentB key="context.key"/></div>`;
|
||||||
context = useContext(testContext);
|
context = useContext(testContext);
|
||||||
|
|||||||
+28
-28
@@ -42,7 +42,7 @@ afterEach(() => {
|
|||||||
|
|
||||||
describe("hooks", () => {
|
describe("hooks", () => {
|
||||||
test("can use a state hook", async () => {
|
test("can use a state hook", async () => {
|
||||||
class Counter extends Component<any, any> {
|
class Counter extends Component {
|
||||||
static template = xml`<div><t t-esc="counter.value"/></div>`;
|
static template = xml`<div><t t-esc="counter.value"/></div>`;
|
||||||
counter = useState({ value: 42 });
|
counter = useState({ value: 42 });
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ describe("hooks", () => {
|
|||||||
steps.push("willunmount");
|
steps.push("willunmount");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -92,7 +92,7 @@ describe("hooks", () => {
|
|||||||
steps.push("willunmount");
|
steps.push("willunmount");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -100,7 +100,7 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
||||||
static components = { MyComponent };
|
static components = { MyComponent };
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
@@ -126,7 +126,7 @@ describe("hooks", () => {
|
|||||||
steps.push("hook:willunmount");
|
steps.push("hook:willunmount");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -157,7 +157,7 @@ describe("hooks", () => {
|
|||||||
steps.push("hook:willunmount");
|
steps.push("hook:willunmount");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -171,7 +171,7 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
||||||
static components = { MyComponent };
|
static components = { MyComponent };
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
@@ -197,7 +197,7 @@ describe("hooks", () => {
|
|||||||
steps.push("hook:willunmount" + i);
|
steps.push("hook:willunmount" + i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey</div>`;
|
static template = xml`<div>hey</div>`;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -219,7 +219,7 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("useRef hook", async () => {
|
test("useRef hook", async () => {
|
||||||
class Counter extends Component<any, any> {
|
class Counter extends Component {
|
||||||
static template = xml`<div><button t-ref="button"><t t-esc="value"/></button></div>`;
|
static template = xml`<div><button t-ref="button"><t t-esc="value"/></button></div>`;
|
||||||
button = useRef("button");
|
button = useRef("button");
|
||||||
value = 0;
|
value = 0;
|
||||||
@@ -241,7 +241,7 @@ describe("hooks", () => {
|
|||||||
|
|
||||||
test("useRef hook is null if ref is removed ", async () => {
|
test("useRef hook is null if ref is removed ", async () => {
|
||||||
expect.assertions(4);
|
expect.assertions(4);
|
||||||
class TestRef extends Component<any, any> {
|
class TestRef extends Component {
|
||||||
static template = xml`<div><span t-if="state.flag" t-ref="span">owl</span></div>`;
|
static template = xml`<div><span t-if="state.flag" t-ref="span">owl</span></div>`;
|
||||||
spanRef = useRef("span");
|
spanRef = useRef("span");
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
@@ -261,10 +261,10 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("t-refs on widget are components", async () => {
|
test("t-refs on widget are components", async () => {
|
||||||
class WidgetB extends Component<any, any> {
|
class WidgetB extends Component {
|
||||||
static template = xml`<div>b</div>`;
|
static template = xml`<div>b</div>`;
|
||||||
}
|
}
|
||||||
class WidgetC extends Component<any, any> {
|
class WidgetC extends Component {
|
||||||
static template = xml`<div class="outer-div">Hello<WidgetB t-ref="mywidgetb" /></div>`;
|
static template = xml`<div class="outer-div">Hello<WidgetB t-ref="mywidgetb" /></div>`;
|
||||||
static components = { WidgetB };
|
static components = { WidgetB };
|
||||||
ref = useRef("mywidgetb");
|
ref = useRef("mywidgetb");
|
||||||
@@ -280,11 +280,11 @@ describe("hooks", () => {
|
|||||||
|
|
||||||
test("t-refs are bound at proper timing", async () => {
|
test("t-refs are bound at proper timing", async () => {
|
||||||
expect.assertions(2);
|
expect.assertions(2);
|
||||||
class Widget extends Component<any, any> {
|
class Widget extends Component {
|
||||||
static template = xml`<div>widget</div>`;
|
static template = xml`<div>widget</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-foreach="state.list" t-as="elem" t-ref="child" t-key="elem" t-component="Widget"/>
|
<t t-foreach="state.list" t-as="elem" t-ref="child" t-key="elem" t-component="Widget"/>
|
||||||
@@ -309,10 +309,10 @@ describe("hooks", () => {
|
|||||||
|
|
||||||
test("t-refs are bound at proper timing (2)", async () => {
|
test("t-refs are bound at proper timing (2)", async () => {
|
||||||
expect.assertions(10);
|
expect.assertions(10);
|
||||||
class Widget extends Component<any, any> {
|
class Widget extends Component {
|
||||||
static template = xml`<div>widget</div>`;
|
static template = xml`<div>widget</div>`;
|
||||||
}
|
}
|
||||||
class ParentWidget extends Component<any, any> {
|
class ParentWidget extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<t t-if="state.child1" t-ref="child1" t-component="Widget"/>
|
<t t-if="state.child1" t-ref="child1" t-component="Widget"/>
|
||||||
@@ -369,7 +369,7 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
|
|
||||||
@@ -403,7 +403,7 @@ describe("hooks", () => {
|
|||||||
steps.push("hook:willPatch");
|
steps.push("hook:willPatch");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
static template = xml`<div><t t-if="state.flag">hey</t></div>`;
|
||||||
state = useState({ flag: true });
|
state = useState({ flag: true });
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ describe("hooks", () => {
|
|||||||
steps.push("hook:willPatch" + i);
|
steps.push("hook:willPatch" + i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<div>hey<t t-esc="state.value"/></div>`;
|
static template = xml`<div>hey<t t-esc="state.value"/></div>`;
|
||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -473,7 +473,7 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test("simple input", async () => {
|
test("simple input", async () => {
|
||||||
class SomeComponent extends Component<any, any> {
|
class SomeComponent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<input t-ref="input1"/>
|
<input t-ref="input1"/>
|
||||||
@@ -494,7 +494,7 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("input in a t-if", async () => {
|
test("input in a t-if", async () => {
|
||||||
class SomeComponent extends Component<any, any> {
|
class SomeComponent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<input t-ref="input1"/>
|
<input t-ref="input1"/>
|
||||||
@@ -521,7 +521,7 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("can use sub env", async () => {
|
test("can use sub env", async () => {
|
||||||
class TestComponent extends Component<any, any> {
|
class TestComponent extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -536,7 +536,7 @@ describe("hooks", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("parent and child env", async () => {
|
test("parent and child env", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/></div>`;
|
static template = xml`<div><t t-esc="env.val"/></div>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -544,7 +544,7 @@ describe("hooks", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
static template = xml`<div><t t-esc="env.val"/><Child/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -568,14 +568,14 @@ describe("hooks", () => {
|
|||||||
steps.push("onWillUpdateProps");
|
steps.push("onWillUpdateProps");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<span><t t-esc="props.value"/></span>`;
|
static template = xml`<span><t t-esc="props.value"/></span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
useMyHook();
|
useMyHook();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><MyComponent value="state.value"/></div>`;
|
static template = xml`<div><MyComponent value="state.value"/></div>`;
|
||||||
static components = { MyComponent };
|
static components = { MyComponent };
|
||||||
state = useState({ value: 1 });
|
state = useState({ value: 1 });
|
||||||
@@ -597,7 +597,7 @@ describe("hooks", () => {
|
|||||||
test("useExternalListener", async () => {
|
test("useExternalListener", async () => {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
|
|
||||||
class MyComponent extends Component<any, any> {
|
class MyComponent extends Component {
|
||||||
static template = xml`<span><t t-esc="props.value"/></span>`;
|
static template = xml`<span><t t-esc="props.value"/></span>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
@@ -607,7 +607,7 @@ describe("hooks", () => {
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
static template = xml`<div><MyComponent t-if="state.flag"/></div>`;
|
||||||
static components = { MyComponent };
|
static components = { MyComponent };
|
||||||
state = useState({ flag: false });
|
state = useState({ flag: false });
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ afterEach(() => {
|
|||||||
describe("Asyncroot", () => {
|
describe("Asyncroot", () => {
|
||||||
test("delayed component with AsyncRoot component", async () => {
|
test("delayed component with AsyncRoot component", async () => {
|
||||||
let def;
|
let def;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
}
|
}
|
||||||
class AsyncChild extends Child {
|
class AsyncChild extends Child {
|
||||||
@@ -35,7 +35,7 @@ describe("Asyncroot", () => {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
@@ -74,7 +74,7 @@ describe("Asyncroot", () => {
|
|||||||
|
|
||||||
test("fast component with AsyncRoot", async () => {
|
test("fast component with AsyncRoot", async () => {
|
||||||
let def;
|
let def;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
}
|
}
|
||||||
class AsyncChild extends Child {
|
class AsyncChild extends Child {
|
||||||
@@ -83,7 +83,7 @@ describe("Asyncroot", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
@@ -122,7 +122,7 @@ describe("Asyncroot", () => {
|
|||||||
|
|
||||||
test("asyncroot component: mixed re-renderings", async () => {
|
test("asyncroot component: mixed re-renderings", async () => {
|
||||||
let def;
|
let def;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span t-on-click="increment">
|
<span t-on-click="increment">
|
||||||
<t t-esc="state.val"/>/<t t-esc="props.val"/>
|
<t t-esc="state.val"/>/<t t-esc="props.val"/>
|
||||||
@@ -138,7 +138,7 @@ describe("Asyncroot", () => {
|
|||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="updateApp">Update App State</button>
|
<button t-on-click="updateApp">Update App State</button>
|
||||||
|
|||||||
+45
-45
@@ -36,7 +36,7 @@ describe("Portal: Props validation", () => {
|
|||||||
test("target is mandatory", async () => {
|
test("target is mandatory", async () => {
|
||||||
const dev = QWeb.dev;
|
const dev = QWeb.dev;
|
||||||
QWeb.dev = true;
|
QWeb.dev = true;
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -61,7 +61,7 @@ describe("Portal: Props validation", () => {
|
|||||||
test("target is not list", async () => {
|
test("target is not list", async () => {
|
||||||
const dev = QWeb.dev;
|
const dev = QWeb.dev;
|
||||||
QWeb.dev = true;
|
QWeb.dev = true;
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -88,7 +88,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
test("basic use of portal", async () => {
|
test("basic use of portal", async () => {
|
||||||
const dev = QWeb.dev;
|
const dev = QWeb.dev;
|
||||||
QWeb.dev = true;
|
QWeb.dev = true;
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -113,7 +113,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("conditional use of Portal", async () => {
|
test("conditional use of Portal", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -148,10 +148,10 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("conditional use of Portal (with sub Component)", async () => {
|
test("conditional use of Portal (with sub Component)", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="props.val"/></div>`;
|
static template = xml`<div><t t-esc="props.val"/></div>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -190,7 +190,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("with target in template (before portal)", async () => {
|
test("with target in template (before portal)", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -210,7 +210,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("with target in template (after portal)", async () => {
|
test("with target in template (after portal)", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -233,7 +233,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -260,7 +260,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
|
|
||||||
test("portal with child and props", async () => {
|
test("portal with child and props", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.val"/></span>`;
|
static template = xml`<span><t t-esc="props.val"/></span>`;
|
||||||
mounted() {
|
mounted() {
|
||||||
steps.push("mounted");
|
steps.push("mounted");
|
||||||
@@ -271,7 +271,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
expect(outside.innerHTML).toBe("<span>2</span>");
|
expect(outside.innerHTML).toBe("<span>2</span>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -298,7 +298,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -326,7 +326,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -354,7 +354,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -379,7 +379,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("portal with dynamic body", async () => {
|
test("portal with dynamic body", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -405,7 +405,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
const consoleError = console.error;
|
const consoleError = console.error;
|
||||||
console.error = jest.fn(() => {});
|
console.error = jest.fn(() => {});
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -439,7 +439,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
test("lifecycle hooks of portal sub component are properly called", async () => {
|
test("lifecycle hooks of portal sub component are properly called", async () => {
|
||||||
const steps: any[] = [];
|
const steps: any[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span t-esc="props.val"/>`;
|
static template = xml`<span t-esc="props.val"/>`;
|
||||||
mounted() {
|
mounted() {
|
||||||
steps.push("child:mounted");
|
steps.push("child:mounted");
|
||||||
@@ -454,7 +454,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
steps.push("child:willUnmount");
|
steps.push("child:willUnmount");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -520,11 +520,11 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("portal destroys on crash", async () => {
|
test("portal destroys on crash", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span t-esc="props.error and this.will.crash" />`;
|
static template = xml`<span t-esc="props.error and this.will.crash" />`;
|
||||||
state = {};
|
state = {};
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -550,7 +550,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("portal manual unmount", async () => {
|
test("portal manual unmount", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -577,7 +577,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
|
|
||||||
test("portal manual unmount with subcomponent", async () => {
|
test("portal manual unmount with subcomponent", async () => {
|
||||||
expect.assertions(9);
|
expect.assertions(9);
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span>gloria</span>`;
|
static template = xml`<span>gloria</span>`;
|
||||||
mounted() {
|
mounted() {
|
||||||
expect(outside.contains(this.el)).toBeTruthy();
|
expect(outside.contains(this.el)).toBeTruthy();
|
||||||
@@ -586,7 +586,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
expect(outside.contains(this.el)).toBeTruthy();
|
expect(outside.contains(this.el)).toBeTruthy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -614,7 +614,7 @@ describe("Portal: Basic use and DOM placement", () => {
|
|||||||
|
|
||||||
describe("Portal: Events handling", () => {
|
describe("Portal: Events handling", () => {
|
||||||
test("events triggered on movable pure node are handled", async () => {
|
test("events triggered on movable pure node are handled", async () => {
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal };
|
static components = { Portal };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -638,8 +638,8 @@ describe("Portal: Events handling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("events triggered on movable owl components are redirected", async () => {
|
test("events triggered on movable owl components are redirected", async () => {
|
||||||
let childInst: Component<any, any> | null = null;
|
let childInst: Component | null = null;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span t-on-custom="_onCustom" t-esc="props.val"/>`;
|
<span t-on-custom="_onCustom" t-esc="props.val"/>`;
|
||||||
|
|
||||||
@@ -652,7 +652,7 @@ describe("Portal: Events handling", () => {
|
|||||||
this.trigger("custom-portal");
|
this.trigger("custom-portal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-on-custom-portal="_onCustomPortal">
|
<div t-on-custom-portal="_onCustomPortal">
|
||||||
@@ -677,8 +677,8 @@ describe("Portal: Events handling", () => {
|
|||||||
|
|
||||||
test("events triggered on contained movable owl components are redirected", async () => {
|
test("events triggered on contained movable owl components are redirected", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
let childInst: Component<any, any> | null = null;
|
let childInst: Component | null = null;
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<span t-on-custom="_onCustom"/>`;
|
<span t-on-custom="_onCustom"/>`;
|
||||||
|
|
||||||
@@ -691,7 +691,7 @@ describe("Portal: Events handling", () => {
|
|||||||
this.trigger("custom-portal");
|
this.trigger("custom-portal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-on-custom="_handled" t-on-custom-portal="_handled">
|
<div t-on-custom="_handled" t-on-custom-portal="_handled">
|
||||||
@@ -717,9 +717,9 @@ describe("Portal: Events handling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("Dom events are not mapped", async () => {
|
test("Dom events are not mapped", async () => {
|
||||||
let childInst: Component<any, any> | null = null;
|
let childInst: Component | null = null;
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<button>child</button>`;
|
<button>child</button>`;
|
||||||
|
|
||||||
@@ -728,7 +728,7 @@ describe("Portal: Events handling", () => {
|
|||||||
childInst = this;
|
childInst = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-on-click="_handled">
|
<div t-on-click="_handled">
|
||||||
@@ -760,22 +760,22 @@ describe("Portal: Events handling", () => {
|
|||||||
fixture.appendChild(outside2);
|
fixture.appendChild(outside2);
|
||||||
|
|
||||||
const steps: Array<string> = [];
|
const steps: Array<string> = [];
|
||||||
let childInst: Component<any, any> | null = null;
|
let childInst: Component | null = null;
|
||||||
class Child2 extends Component<any, any> {
|
class Child2 extends Component {
|
||||||
static template = xml`<div>child2</div>`;
|
static template = xml`<div>child2</div>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
childInst = this;
|
childInst = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static components = { Portal, Child2 };
|
static components = { Portal, Child2 };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<Portal target="'#outside2'">
|
<Portal target="'#outside2'">
|
||||||
<Child2 />
|
<Child2 />
|
||||||
</Portal>`;
|
</Portal>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-on-custom='_handled'>
|
<div t-on-custom='_handled'>
|
||||||
@@ -797,11 +797,11 @@ describe("Portal: Events handling", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("portal's parent's env is not polluted", async () => {
|
test("portal's parent's env is not polluted", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<button>child</button>`;
|
<button>child</button>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -818,22 +818,22 @@ describe("Portal: Events handling", () => {
|
|||||||
|
|
||||||
test("Portal composed with t-slot", async () => {
|
test("Portal composed with t-slot", async () => {
|
||||||
const steps: Array<string> = [];
|
const steps: Array<string> = [];
|
||||||
let childInst: Component<any, any> | null = null;
|
let childInst: Component | null = null;
|
||||||
class Child2 extends Component<any, any> {
|
class Child2 extends Component {
|
||||||
static template = xml`<div>child2</div>`;
|
static template = xml`<div>child2</div>`;
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
childInst = this;
|
childInst = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static components = { Portal, Child2 };
|
static components = { Portal, Child2 };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<Portal target="'#outside'">
|
<Portal target="'#outside'">
|
||||||
<t t-slot="default"/>
|
<t t-slot="default"/>
|
||||||
</Portal>`;
|
</Portal>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Child, Child2 };
|
static components = { Child, Child2 };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-on-custom='_handled'>
|
<div t-on-custom='_handled'>
|
||||||
@@ -857,11 +857,11 @@ describe("Portal: Events handling", () => {
|
|||||||
|
|
||||||
describe("Portal: UI/UX", () => {
|
describe("Portal: UI/UX", () => {
|
||||||
test("focus is kept across re-renders", async () => {
|
test("focus is kept across re-renders", async () => {
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<input id="target-me" t-att-placeholder="props.val"/>`;
|
<input id="target-me" t-att-placeholder="props.val"/>`;
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static components = { Portal, Child };
|
static components = { Portal, Child };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ describe("Link component", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { Link: Link };
|
static components = { Link: Link };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ describe("Link component", () => {
|
|||||||
</div>
|
</div>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { Link: Link };
|
static components = { Link: Link };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ describe("RouteComponent", () => {
|
|||||||
<span t-name="Users">Users</span>
|
<span t-name="Users">Users</span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class About extends Component<any, any> {}
|
class About extends Component {}
|
||||||
class Users extends Component<any, any> {}
|
class Users extends Component {}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { RouteComponent };
|
static components = { RouteComponent };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +65,8 @@ describe("RouteComponent", () => {
|
|||||||
<span t-name="Book">Book <t t-esc="props.title"/></span>
|
<span t-name="Book">Book <t t-esc="props.title"/></span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Book extends Component<any, any> {}
|
class Book extends Component {}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { RouteComponent };
|
static components = { RouteComponent };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +87,12 @@ describe("RouteComponent", () => {
|
|||||||
<span t-name="Book">Book <t t-esc="props.title"/>|<t t-esc="incVal"/></span>
|
<span t-name="Book">Book <t t-esc="props.title"/>|<t t-esc="incVal"/></span>
|
||||||
</templates>
|
</templates>
|
||||||
`);
|
`);
|
||||||
class Book extends Component<any, any> {
|
class Book extends Component {
|
||||||
get incVal() {
|
get incVal() {
|
||||||
return this.props.val + 1;
|
return this.props.val + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static components = { RouteComponent };
|
static components = { RouteComponent };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+44
-44
@@ -29,7 +29,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
||||||
@@ -60,7 +60,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-if="isBoolean">ok</span>
|
<span t-if="isBoolean">ok</span>
|
||||||
@@ -102,7 +102,7 @@ describe("connecting a component to store", () => {
|
|||||||
const state = { smallerArray: [1], biggerArray: [2, 3], useSmallArray: true };
|
const state = { smallerArray: [1], biggerArray: [2, 3], useSmallArray: true };
|
||||||
const store = new Store({ state });
|
const store = new Store({ state });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div t-esc="mapAdd"/>`;
|
static template = xml`<div t-esc="mapAdd"/>`;
|
||||||
storeProps = {
|
storeProps = {
|
||||||
array: useStore(state => {
|
array: useStore(state => {
|
||||||
@@ -131,7 +131,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("throw error if no store is found", async () => {
|
test("throw error if no store is found", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div></div>`;
|
static template = xml`<div></div>`;
|
||||||
todos = useStore(state => state.todos);
|
todos = useStore(state => state.todos);
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ describe("connecting a component to store", () => {
|
|||||||
const actions = {};
|
const actions = {};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div/>`;
|
static template = xml`<div/>`;
|
||||||
storeState = useStore(state => state.a);
|
storeState = useStore(state => state.a);
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-esc="a.value"/>
|
<span t-esc="a.value"/>
|
||||||
@@ -208,7 +208,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
||||||
@@ -245,7 +245,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="nbrTodos.value"/></div>`;
|
static template = xml`<div><t t-esc="nbrTodos.value"/></div>`;
|
||||||
nbrTodos = useStore(state => ({ value: state.todos.length }));
|
nbrTodos = useStore(state => ({ value: state.todos.length }));
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="nbrTodos.value"/></div>`;
|
static template = xml`<div><t t-esc="nbrTodos.value"/></div>`;
|
||||||
nbrTodos = useStore(state => ({ value: state.todos.length }), { isEqual: shallowEqual });
|
nbrTodos = useStore(state => ({ value: state.todos.length }), { isEqual: shallowEqual });
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
<span t-foreach="todos" t-key="todo.id" t-as="todo"><t t-esc="todo.msg"/></span>
|
||||||
@@ -336,7 +336,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
(<any>env).store = store;
|
(<any>env).store = store;
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="dispatch('inc')">Inc</button>
|
<button t-on-click="dispatch('inc')">Inc</button>
|
||||||
@@ -365,14 +365,14 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions: {} });
|
const store = new Store({ state, actions: {} });
|
||||||
|
|
||||||
class TodoItem extends Component<any, any> {
|
class TodoItem extends Component {
|
||||||
static template = xml`<span><t t-esc="todo.text"/></span>`;
|
static template = xml`<span><t t-esc="todo.text"/></span>`;
|
||||||
todo = useStore((state, props) => {
|
todo = useStore((state, props) => {
|
||||||
return state.todos.find(t => t.id === props.todoId);
|
return state.todos.find(t => t.id === props.todoId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><TodoItem todoId="state.currentId"/></div>`;
|
static template = xml`<div><TodoItem todoId="state.currentId"/></div>`;
|
||||||
static components = { TodoItem };
|
static components = { TodoItem };
|
||||||
state = useState({ currentId: 1 });
|
state = useState({ currentId: 1 });
|
||||||
@@ -399,14 +399,14 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, actions });
|
const store = new Store({ state, actions });
|
||||||
|
|
||||||
class TodoItem extends Component<any, any> {
|
class TodoItem extends Component {
|
||||||
static template = xml`<span><t t-esc="todo.text"/></span>`;
|
static template = xml`<span><t t-esc="todo.text"/></span>`;
|
||||||
todo = useStore((state, props) => {
|
todo = useStore((state, props) => {
|
||||||
return state.todos.find(t => t.id === props.id);
|
return state.todos.find(t => t.id === props.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TodoList extends Component<any, any> {
|
class TodoList extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<TodoItem t-foreach="todos" t-as="todo" id="todo.id" t-key="todo.id"/>
|
<TodoItem t-foreach="todos" t-as="todo" id="todo.id" t-key="todo.id"/>
|
||||||
@@ -444,7 +444,7 @@ describe("connecting a component to store", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ state, getters });
|
const store = new Store({ state, getters });
|
||||||
|
|
||||||
class TodoItem extends Component<any, any> {
|
class TodoItem extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span><t t-esc="storeProps.activeTodoText"/></span>
|
<span><t t-esc="storeProps.activeTodoText"/></span>
|
||||||
@@ -460,7 +460,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TodoList extends Component<any, any> {
|
class TodoList extends Component {
|
||||||
static components = { TodoItem };
|
static components = { TodoItem };
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
@@ -481,12 +481,12 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("connected component is updated when props are updated", async () => {
|
test("connected component is updated when props are updated", async () => {
|
||||||
class Beer extends Component<any, any> {
|
class Beer extends Component {
|
||||||
static template = xml`<span><t t-esc="beer.name"/></span>`;
|
static template = xml`<span><t t-esc="beer.name"/></span>`;
|
||||||
beer = useStore((state, props) => state.beers[props.id]);
|
beer = useStore((state, props) => state.beers[props.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
||||||
static components = { Beer };
|
static components = { Beer };
|
||||||
state = useState({ beerId: 1 });
|
state = useState({ beerId: 1 });
|
||||||
@@ -506,7 +506,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("connected component is updated when store is changed", async () => {
|
test("connected component is updated when store is changed", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span t-foreach="data.beers" t-as="beer" t-key="beer.name"><t t-esc="beer.name"/></span>
|
<span t-foreach="data.beers" t-as="beer" t-key="beer.name"><t t-esc="beer.name"/></span>
|
||||||
@@ -539,7 +539,7 @@ describe("connecting a component to store", () => {
|
|||||||
test("connected component is updated when mixing store and props changes", async () => {
|
test("connected component is updated when mixing store and props changes", async () => {
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
|
||||||
class Beer extends Component<any, any> {
|
class Beer extends Component {
|
||||||
static template = xml`<span><t t-esc="beer.name"/></span>`;
|
static template = xml`<span><t t-esc="beer.name"/></span>`;
|
||||||
beer = useStore((state, props) => state.beers[props.id], {
|
beer = useStore((state, props) => state.beers[props.id], {
|
||||||
onUpdate: result => {
|
onUpdate: result => {
|
||||||
@@ -548,7 +548,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
||||||
static components = { Beer };
|
static components = { Beer };
|
||||||
state = useState({ beerId: 1 });
|
state = useState({ beerId: 1 });
|
||||||
@@ -580,7 +580,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("connected component is properly cleaned up on destroy", async () => {
|
test("connected component is properly cleaned up on destroy", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div></div>`;
|
static template = xml`<div></div>`;
|
||||||
state = useStore((state, props) => state);
|
state = useStore((state, props) => state);
|
||||||
}
|
}
|
||||||
@@ -599,7 +599,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("connected component with undefined, null and string props", async () => {
|
test("connected component with undefined, null and string props", async () => {
|
||||||
class Beer extends Component<any, any> {
|
class Beer extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div t-name="Beer">
|
<div t-name="Beer">
|
||||||
<span>taster:<t t-esc="data.taster"/></span>
|
<span>taster:<t t-esc="data.taster"/></span>
|
||||||
@@ -613,7 +613,7 @@ describe("connecting a component to store", () => {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
||||||
static components = { Beer };
|
static components = { Beer };
|
||||||
state = useState({ beerId: 0 });
|
state = useState({ beerId: 0 });
|
||||||
@@ -658,7 +658,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("connected component deeply reactive with undefined, null and string props", async () => {
|
test("connected component deeply reactive with undefined, null and string props", async () => {
|
||||||
class Beer extends Component<any, any> {
|
class Beer extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span>taster:<t t-esc="info.taster"/></span>
|
<span>taster:<t t-esc="info.taster"/></span>
|
||||||
@@ -674,7 +674,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
static template = xml`<div><Beer id="state.beerId"/></div>`;
|
||||||
static components = { Beer };
|
static components = { Beer };
|
||||||
state = useState({ beerId: 0 });
|
state = useState({ beerId: 0 });
|
||||||
@@ -749,7 +749,7 @@ describe("connecting a component to store", () => {
|
|||||||
state.x.val = val;
|
state.x.val = val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><t t-esc="x.val"/></div>`;
|
static template = xml`<div><t t-esc="x.val"/></div>`;
|
||||||
x = useStore(state => {
|
x = useStore(state => {
|
||||||
return Object.assign({}, state.x);
|
return Object.assign({}, state.x);
|
||||||
@@ -770,7 +770,7 @@ describe("connecting a component to store", () => {
|
|||||||
test("correct update order when parent/children are connected", async () => {
|
test("correct update order when parent/children are connected", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="state.msg"/></span>`;
|
static template = xml`<span><t t-esc="state.msg"/></span>`;
|
||||||
|
|
||||||
state = useStore((state, props) => {
|
state = useStore((state, props) => {
|
||||||
@@ -778,7 +778,7 @@ describe("connecting a component to store", () => {
|
|||||||
return { msg: state.msg[props.key] };
|
return { msg: state.msg[props.key] };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child key="state.current"/></div>`;
|
static template = xml`<div><Child key="state.current"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
|
|
||||||
@@ -817,7 +817,7 @@ describe("connecting a component to store", () => {
|
|||||||
let def = makeDeferred();
|
let def = makeDeferred();
|
||||||
def.resolve();
|
def.resolve();
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="state.msg"/></span>`;
|
static template = xml`<span><t t-esc="state.msg"/></span>`;
|
||||||
state = useStore((s, props) => {
|
state = useStore((s, props) => {
|
||||||
steps.push("child");
|
steps.push("child");
|
||||||
@@ -825,7 +825,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<Child t-if="state.flag" someId="state.someId"/>
|
<Child t-if="state.flag" someId="state.someId"/>
|
||||||
@@ -885,7 +885,7 @@ describe("connecting a component to store", () => {
|
|||||||
actions
|
actions
|
||||||
});
|
});
|
||||||
|
|
||||||
class TodoItem extends Component<any, any> {
|
class TodoItem extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div class="todo">
|
<div class="todo">
|
||||||
<t t-esc="state.todo.title"/>
|
<t t-esc="state.todo.title"/>
|
||||||
@@ -906,7 +906,7 @@ describe("connecting a component to store", () => {
|
|||||||
return super.__render(f);
|
return super.__render(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class TodoApp extends Component<any, any> {
|
class TodoApp extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div class="todoapp">
|
<div class="todoapp">
|
||||||
<t t-foreach="Object.values(state.todos)" t-as="todo">
|
<t t-foreach="Object.values(state.todos)" t-as="todo">
|
||||||
@@ -958,7 +958,7 @@ describe("connecting a component to store", () => {
|
|||||||
actions
|
actions
|
||||||
});
|
});
|
||||||
|
|
||||||
class TodoItem extends Component<any, any> {
|
class TodoItem extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div class="todo">
|
<div class="todo">
|
||||||
<t t-esc="state.todo.title"/>
|
<t t-esc="state.todo.title"/>
|
||||||
@@ -980,7 +980,7 @@ describe("connecting a component to store", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TodoApp extends Component<any, any> {
|
class TodoApp extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div class="todoapp">
|
<div class="todoapp">
|
||||||
<t t-foreach="Object.values(state.todos)" t-as="todo">
|
<t t-foreach="Object.values(state.todos)" t-as="todo">
|
||||||
@@ -1024,7 +1024,7 @@ describe("connecting a component to store", () => {
|
|||||||
test("connected component willpatch/patch hooks are called on store updates", async () => {
|
test("connected component willpatch/patch hooks are called on store updates", async () => {
|
||||||
const steps: string[] = [];
|
const steps: string[] = [];
|
||||||
|
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="store.msg"/></div>`;
|
static template = xml`<div><t t-esc="store.msg"/></div>`;
|
||||||
store = useStore(s => ({ msg: s.msg }));
|
store = useStore(s => ({ msg: s.msg }));
|
||||||
|
|
||||||
@@ -1059,12 +1059,12 @@ describe("connecting a component to store", () => {
|
|||||||
test("connected child components stop listening to store when destroyed", async () => {
|
test("connected child components stop listening to store when destroyed", async () => {
|
||||||
let steps: any = [];
|
let steps: any = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="store.val"/></div>`;
|
static template = xml`<div><t t-esc="store.val"/></div>`;
|
||||||
store = useStore(s => s);
|
store = useStore(s => s);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child t-if="state.child" /></div>`;
|
static template = xml`<div><Child t-if="state.child" /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ child: true });
|
state = useState({ child: true });
|
||||||
@@ -1097,14 +1097,14 @@ describe("connecting a component to store", () => {
|
|||||||
test("connected child component destroyed by dispatched action", async () => {
|
test("connected child component destroyed by dispatched action", async () => {
|
||||||
let steps: any = [];
|
let steps: any = [];
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div><t t-esc="store.val"/></div>`;
|
static template = xml`<div><t t-esc="store.val"/></div>`;
|
||||||
store = useStore(s => {
|
store = useStore(s => {
|
||||||
steps.push("child selector");
|
steps.push("child selector");
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child t-if="store.child" /></div>`;
|
static template = xml`<div><Child t-if="store.child" /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
store = useStore(s => {
|
store = useStore(s => {
|
||||||
@@ -1135,7 +1135,7 @@ describe("connecting a component to store", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("dispatch an action", async () => {
|
test("dispatch an action", async () => {
|
||||||
class App extends Component<any, any> {
|
class App extends Component {
|
||||||
static template = xml`<div><t t-esc="store.counter"/></div>`;
|
static template = xml`<div><t t-esc="store.counter"/></div>`;
|
||||||
store = useStore(state => state);
|
store = useStore(state => state);
|
||||||
dispatch = useDispatch();
|
dispatch = useDispatch();
|
||||||
@@ -1203,7 +1203,7 @@ describe("various scenarios", () => {
|
|||||||
};
|
};
|
||||||
const store = new Store({ actions, state });
|
const store = new Store({ actions, state });
|
||||||
|
|
||||||
class Attachment extends Component<any, any> {
|
class Attachment extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<span>Attachment <t t-esc="props.id"/></span>
|
<span>Attachment <t t-esc="props.id"/></span>
|
||||||
@@ -1213,7 +1213,7 @@ describe("various scenarios", () => {
|
|||||||
attachment = useStore((state, props) => ({ name: state.attachments[props.id].name }));
|
attachment = useStore((state, props) => ({ name: state.attachments[props.id].name }));
|
||||||
}
|
}
|
||||||
|
|
||||||
class Message extends Component<any, any> {
|
class Message extends Component {
|
||||||
static template = xml`
|
static template = xml`
|
||||||
<div>
|
<div>
|
||||||
<button t-on-click="doStuff">Do stuff</button>
|
<button t-on-click="doStuff">Do stuff</button>
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ test("can log full lifecycle", async () => {
|
|||||||
const log = console.log;
|
const log = console.log;
|
||||||
console.log = arg => steps.push(arg);
|
console.log = arg => steps.push(arg);
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div>child</div>`;
|
static template = xml`<div>child</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
static template = xml`<div><Child t-if="state.flag"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
state = useState({ flag: false });
|
state = useState({ flag: false });
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ test("can log scheduler start and stop", async () => {
|
|||||||
const log = console.log;
|
const log = console.log;
|
||||||
console.log = arg => steps.push(arg);
|
console.log = arg => steps.push(arg);
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<div>child</div>`;
|
static template = xml`<div>child</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child /></div>`;
|
static template = xml`<div><Child /></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ test("log a specific message for render method calls if component is not mounted
|
|||||||
const log = console.log;
|
const log = console.log;
|
||||||
console.log = arg => steps.push(arg);
|
console.log = arg => steps.push(arg);
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><t t-esc="state.value"/></div>`;
|
static template = xml`<div><t t-esc="state.value"/></div>`;
|
||||||
state = owl.hooks.useState({ value: 1 });
|
state = owl.hooks.useState({ value: 1 });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,14 @@ test("log a sub component with non stringifiable props", async () => {
|
|||||||
const log = console.log;
|
const log = console.log;
|
||||||
console.log = arg => steps.push(arg);
|
console.log = arg => steps.push(arg);
|
||||||
|
|
||||||
class Child extends Component<any, any> {
|
class Child extends Component {
|
||||||
static template = xml`<span><t t-esc="props.obj.val"/></span>`;
|
static template = xml`<span><t t-esc="props.obj.val"/></span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const circularObject: any = { val: 1 };
|
const circularObject: any = { val: 1 };
|
||||||
circularObject.circularObject = circularObject;
|
circularObject.circularObject = circularObject;
|
||||||
|
|
||||||
class Parent extends Component<any, any> {
|
class Parent extends Component {
|
||||||
static template = xml`<div><Child obj="obj"/></div>`;
|
static template = xml`<div><Child obj="obj"/></div>`;
|
||||||
static components = { Child };
|
static components = { Child };
|
||||||
obj = circularObject;
|
obj = circularObject;
|
||||||
|
|||||||
Reference in New Issue
Block a user