[FIX] component: reorganize fiber update algorithm

Closes #473
Closes #484
Closes #489
Closes #492
Closes #512

Co-authored-by: Aaron Bohy <aab@odoo.com>
This commit is contained in:
Géry Debongnie
2019-11-21 11:23:05 +01:00
parent 7f6782d009
commit 8c17bb0411
15 changed files with 458 additions and 163 deletions
+72 -23
View File
@@ -1,13 +1,15 @@
import { Component, Env } from "../src/component/component";
import { QWeb } from "../src/qweb/index";
import { useState, useRef } from "../src/hooks";
import { xml } from "../src/tags";
import {
makeDeferred,
makeTestFixture,
makeTestEnv,
patchNextFrame,
renderToDOM,
unpatchNextFrame
unpatchNextFrame,
nextTick
} from "./helpers";
//------------------------------------------------------------------------------
@@ -321,30 +323,23 @@ describe("animations", () => {
});
test("t-transition combined with t-component, remove and re-add before transitionend", async () => {
expect.assertions(11);
expect.assertions(12);
env.qweb.addTemplates(
`<templates>
<div t-name="Parent">
<button t-on-click="toggle">Toggle</button>
<t t-if="state.flag" t-component="Child" t-transition="chimay"/>
</div>
<span t-name="Child">blue</span>
</templates>`
);
class Child extends Widget {}
class Child extends Widget {
static template = xml`<span>blue</span>`;
}
class Parent extends Widget {
static template = xml`
<div t-name="Parent">
<t t-if="state.flag" t-component="Child" t-transition="chimay"/>
</div>`;
static components = { Child };
state = useState({ flag: false });
toggle() {
this.state.flag = !this.state.flag;
}
}
const widget = new Parent();
await widget.mount(fixture);
let button = widget.el!.querySelector("button");
expect(env.qweb.templates[Parent.template].fn.toString()).toMatchSnapshot();
let def = makeDeferred();
let phase = "enter";
@@ -357,24 +352,78 @@ describe("animations", () => {
def.resolve();
});
// click display the span
button!.click();
// display the span
widget.state.flag = true;
await def; // wait for the mocked repaint to be done
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend")); // mock end of css transition
expect(fixture.innerHTML).toBe('<div><button>Toggle</button><span class="">blue</span></div>');
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
// click to remove the span, and click again to re-add it before transitionend
def = makeDeferred();
phase = "leave";
button!.click();
widget.state.flag = false;
await def; // wait for the mocked repaint to be done
def = makeDeferred();
phase = "enter";
button!.click();
widget.state.flag = true;
await def; // wait for the mocked repaint to be done
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend")); // mock end of css transition
expect(fixture.innerHTML).toBe('<div><button>Toggle</button><span class="">blue</span></div>');
expect(fixture.innerHTML).toBe('<div><span class="" data-owl-key="__5__">blue</span></div>');
});
test("transitionInsert is called the correct amount of times", async () => {
const oldTransitionInsert = QWeb.utils.transitionInsert;
QWeb.utils.transitionInsert = jest.fn(oldTransitionInsert);
class Child extends Widget {
static template = xml`<span>blue</span>`;
}
class Parent extends Widget {
static template = xml`
<div t-name="Parent">
<Child t-if="state.flag" t-transition="chimay"/>
</div>`;
static components = { Child };
state = useState({ flag: false });
}
patchNextFrame(cb => cb());
const widget = new Parent();
await widget.mount(fixture);
widget.state.flag = true;
await nextTick();
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend"));
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
expect(QWeb.utils.transitionInsert).toBeCalledTimes(1);
widget.state.flag = false;
await nextTick();
expect(fixture.innerHTML).toBe(
'<div><span class="chimay-leave-active chimay-leave-to" data-owl-key="__5__">blue</span></div>'
);
expect(QWeb.utils.transitionInsert).toBeCalledTimes(1);
widget.state.flag = true;
await nextTick();
expect(fixture.innerHTML).toBe(
'<div><span class="chimay-enter-active chimay-enter-to" data-owl-key="__5__">blue</span></div>'
);
expect(QWeb.utils.transitionInsert).toBeCalledTimes(2);
widget.state.flag = false;
await nextTick();
widget.state.flag = true;
await nextTick();
expect(QWeb.utils.transitionInsert).toBeCalledTimes(3);
widget.el!.querySelector("span")!.dispatchEvent(new Event("transitionend"));
expect(fixture.innerHTML).toBe('<div><span class="" data-owl-key="__5__">blue</span></div>');
QWeb.utils.transitionInsert = oldTransitionInsert;
});
});