diff --git a/doc/learning/how_to_test.md b/doc/learning/how_to_test.md index ca1fd70c..47696e15 100644 --- a/doc/learning/how_to_test.md +++ b/doc/learning/how_to_test.md @@ -30,27 +30,21 @@ To help with this, it is useful to have a `helper.js` file that contains some common utility functions: ```js +let lastFixture = null; + export function makeTestFixture() { let fixture = document.createElement("div"); document.body.appendChild(fixture); + if (lastFixture) { + lastFixture.remove(); + } + lastFixture = fixture; return fixture; } -export function nextTick() { - let requestAnimationFrame = owl.Component.scheduler.requestAnimationFrame; - return new Promise(function(resolve) { - setTimeout(() => requestAnimationFrame(() => resolve())); - }); -} - -export function makeTestEnv() { - // application specific. It needs a way to load actual templates - const templates = ...; - - return { - qweb: new QWeb(templates), - ..., // each service can be mocked here - }; +export async function nextTick() { + await new Promise((resolve) => setTimeout(resolve)); + await new Promise((resolve) => requestAnimationFrame(resolve)); } ``` @@ -59,7 +53,7 @@ With such a file, a typical test suite for Jest will look like this: ```js // in SomeComponent.test.js import { SomeComponent } from "../../src/ui/SomeComponent"; -import { nextTick, makeTestFixture, makeTestEnv} from '../helpers'; +import { nextTick, makeTestFixture } from '../helpers'; //------------------------------------------------------------------------------ @@ -70,9 +64,6 @@ let env: Env; beforeEach(() => { fixture = makeTestFixture(); - env = makeTestEnv(); - // we set here the default environment for each component created in the test - Component.env = env; }); afterEach(() => { @@ -85,7 +76,7 @@ afterEach(() => { describe("SomeComponent", () => { test("component behaves as expected", async () => { const props = {...}; // depends on the component - const comp = await mount(SomeComponent, { target: fixture, props }); + const comp = await mount(SomeComponent, fixture, { props }); // do some assertions expect(...).toBe(...); @@ -102,29 +93,3 @@ describe("SomeComponent", () => { Note that Owl does wait for the next animation frame to actually update the DOM. This is why it is necessary to wait with the `nextTick` (or other methods) to make sure that the DOM is up-to-date. - -It is sometimes useful to wait until Owl is completely done updating components -(in particular, if we have a highly concurrent user interface). This next -helper simply polls every 20ms the internal Owl task queue and returns a promise -which resolves when it is empty: - -```js -function afterUpdates() { - return new Promise((resolve, reject) => { - let timer = setTimeout(poll, 20); - let counter = 0; - function poll() { - counter++; - if (owl.Component.scheduler.tasks.length) { - if (counter > 10) { - reject(new Error("timeout")); - } else { - timer = setTimeout(poll); - } - } else { - resolve(); - } - } - }); -} -``` diff --git a/doc/learning/quick_start.md b/doc/learning/quick_start.md index 48deae64..05d46572 100644 --- a/doc/learning/quick_start.md +++ b/doc/learning/quick_start.md @@ -36,6 +36,8 @@ hello_owl/ 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). It is a single javascript file which export all Owl into the global `owl` object. +Note that there are multiple files, and in this case, we need one of the two +files suffixed with `.iife`: they are built to be directly used in a browser. Now, `index.html` should contain the following: @@ -45,30 +47,24 @@ Now, `index.html` should contain the following: Hello Owl - - + + + ``` And `app.js` should look like this: ```js -const { Component, mount } = owl; -const { xml } = owl.tags; -const { whenReady } = owl.utils; +const { Component, mount, xml } = owl; // Owl Components -class App extends Component { +class Root extends Component { static template = xml`
Hello Owl
`; } -// Setup code -function setup() { - mount(App, target: { document.body }) -} - -whenReady(setup); +mount(Root, document.body); ``` Now, simply loading this html file in a browser should display a welcome message. @@ -93,14 +89,16 @@ Let us start a new project with the following file structure: ``` hello_owl/ src/ - app.js index.html main.js owl.js + root.js ``` 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). +Note that there are multiple files, and in this case, we need one of the two +files suffixed with `.iife`: they are built to be directly used in a browser. Now, `index.html` should contain the following: @@ -110,37 +108,33 @@ Now, `index.html` should contain the following: Hello Owl - - + + + ``` Not that the `main.js` script tag has the `type="module"` attribute. This means that the browser will parse the script as a module, and load all its dependencies. -Here is the content of `app.js` and `main.js`: +Here is the content of `root.js` and `main.js`: ```js -// app.js ---------------------------------------------------------------------- -const { Component, mount } = owl; -const { xml } = owl.tags; +// root.js ---------------------------------------------------------------------- +const { Component, mount, xml } = owl; -export class App extends Component { +export class Root extends Component { static template = xml`
Hello Owl
`; } // main.js --------------------------------------------------------------------- -import { App } from "./app.js"; +import { Root } from "./root.js"; -function setup() { - mount(App, { target: document.body }); -} - -owl.utils.whenReady(setup); +mount(Root, document.body); ``` -The `main.js` file import the `app.js` file. Note that the import statement has +The `main.js` file imports the `root.js` file. Note that the import statement has a `.js` suffix, which is important. Most text editor can understand this syntax and will provide autocompletion. @@ -193,11 +187,11 @@ hello_owl/ index.html src/ components/ - App.js + Root.js main.js tests/ components/ - App.test.js + Root.test.js helpers.js .gitignore package.json @@ -224,13 +218,15 @@ Note that there are no `