mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REF] move animations tests into their own file
This commit is contained in:
@@ -0,0 +1,115 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`animations t-transition combined with t-widget 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
|
let owner = context;
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('div', p1, c1);
|
||||||
|
//WIDGET
|
||||||
|
let _2_index = c1.length;
|
||||||
|
c1.push(null);
|
||||||
|
let def3;
|
||||||
|
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
||||||
|
let props4 = {};
|
||||||
|
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
||||||
|
w4.destroy();
|
||||||
|
w4 = false
|
||||||
|
}
|
||||||
|
if (!w4) {
|
||||||
|
let W4 = context.widgets['Child'];
|
||||||
|
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
||||||
|
w4 = new W4(owner, props4);
|
||||||
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
|
def3 = w4._prepare();
|
||||||
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
||||||
|
w4.destroy();
|
||||||
|
};
|
||||||
|
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
|
} else {
|
||||||
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
}
|
||||||
|
extra.promises.push(def3);
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`animations t-transition combined with t-widget and t-if 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
let utils = this.utils;
|
||||||
|
let owner = context;
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('div', p1, c1);
|
||||||
|
if (context['state'].display) {
|
||||||
|
//WIDGET
|
||||||
|
let _2_index = c1.length;
|
||||||
|
c1.push(null);
|
||||||
|
let def3;
|
||||||
|
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
||||||
|
let props4 = {};
|
||||||
|
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
||||||
|
w4.destroy();
|
||||||
|
w4 = false
|
||||||
|
}
|
||||||
|
if (!w4) {
|
||||||
|
let W4 = context.widgets['Child'];
|
||||||
|
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
||||||
|
w4 = new W4(owner, props4);
|
||||||
|
context.__owl__.cmap[4] = w4.__owl__.id;
|
||||||
|
def3 = w4._prepare();
|
||||||
|
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
||||||
|
w4.destroy();
|
||||||
|
};
|
||||||
|
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
||||||
|
} else {
|
||||||
|
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
||||||
|
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
||||||
|
}
|
||||||
|
extra.promises.push(def3);
|
||||||
|
}
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`animations t-transition with no delay/duration 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('span', p1, c1);
|
||||||
|
p1.hook = {
|
||||||
|
insert: vn => {
|
||||||
|
this.utils.transitionInsert(vn.elm, 'jupiler');
|
||||||
|
},
|
||||||
|
remove: (vn, rm) => {
|
||||||
|
this.utils.transitionRemove(vn.elm, 'jupiler', rm);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
c1.push({text: \`blue\`});
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`animations t-transition, on a simple node (insert) 1`] = `
|
||||||
|
"function anonymous(context,extra
|
||||||
|
) {
|
||||||
|
var h = this.utils.h;
|
||||||
|
let c1 = [], p1 = {key:1};
|
||||||
|
var vn1 = h('span', p1, c1);
|
||||||
|
p1.hook = {
|
||||||
|
insert: vn => {
|
||||||
|
this.utils.transitionInsert(vn.elm, 'chimay');
|
||||||
|
},
|
||||||
|
remove: (vn, rm) => {
|
||||||
|
this.utils.transitionRemove(vn.elm, 'chimay', rm);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
c1.push({text: \`blue\`});
|
||||||
|
return vn1;
|
||||||
|
}"
|
||||||
|
`;
|
||||||
@@ -1,81 +1,5 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`animations t-transition combined with t-widget 1`] = `
|
|
||||||
"function anonymous(context,extra
|
|
||||||
) {
|
|
||||||
let utils = this.utils;
|
|
||||||
let owner = context;
|
|
||||||
var h = this.utils.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
var vn1 = h('div', p1, c1);
|
|
||||||
//WIDGET
|
|
||||||
let _2_index = c1.length;
|
|
||||||
c1.push(null);
|
|
||||||
let def3;
|
|
||||||
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
|
||||||
let props4 = {};
|
|
||||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
|
||||||
w4.destroy();
|
|
||||||
w4 = false
|
|
||||||
}
|
|
||||||
if (!w4) {
|
|
||||||
let W4 = context.widgets['Child'];
|
|
||||||
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
|
||||||
w4 = new W4(owner, props4);
|
|
||||||
context.__owl__.cmap[4] = w4.__owl__.id;
|
|
||||||
def3 = w4._prepare();
|
|
||||||
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
|
||||||
w4.destroy();
|
|
||||||
};
|
|
||||||
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
|
||||||
} else {
|
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
|
||||||
}
|
|
||||||
extra.promises.push(def3);
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`animations t-transition combined with t-widget and t-if 1`] = `
|
|
||||||
"function anonymous(context,extra
|
|
||||||
) {
|
|
||||||
let utils = this.utils;
|
|
||||||
let owner = context;
|
|
||||||
var h = this.utils.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
var vn1 = h('div', p1, c1);
|
|
||||||
if (context['state'].display) {
|
|
||||||
//WIDGET
|
|
||||||
let _2_index = c1.length;
|
|
||||||
c1.push(null);
|
|
||||||
let def3;
|
|
||||||
let w4 = 4 in context.__owl__.cmap ? context.__owl__.children[context.__owl__.cmap[4]] : false;
|
|
||||||
let props4 = {};
|
|
||||||
if (w4 && w4.__owl__.renderPromise && !w4.__owl__.vnode && props4 !== w4.__owl__.renderProps) {
|
|
||||||
w4.destroy();
|
|
||||||
w4 = false
|
|
||||||
}
|
|
||||||
if (!w4) {
|
|
||||||
let W4 = context.widgets['Child'];
|
|
||||||
if (!W4) {throw new Error(\`Cannot find the definition of widget \\"Child\\"\`)}
|
|
||||||
w4 = new W4(owner, props4);
|
|
||||||
context.__owl__.cmap[4] = w4.__owl__.id;
|
|
||||||
def3 = w4._prepare();
|
|
||||||
def3 = def3.then(vnode=>{let pvnode=h(vnode.sel, {key: 4, hook: {insert(vn) {let nvn=w4._mount(vnode, pvnode.elm);pvnode.elm=nvn.elm;utils.transitionInsert(vn.elm, 'chimay');},remove() {},destroy(vn) {let finalize = () => {
|
|
||||||
w4.destroy();
|
|
||||||
};
|
|
||||||
utils.transitionRemove(vn.elm, 'chimay', finalize);}}});c1[_2_index]=pvnode;w4.__owl__.pvnode = pvnode;});
|
|
||||||
} else {
|
|
||||||
def3 = w4._updateProps(props4, extra.forceUpdate, extra.patchQueue);
|
|
||||||
def3 = def3.then(()=>{if (w4.__owl__.isDestroyed) {return};let pvnode=w4.__owl__.pvnode;c1[_2_index]=pvnode;});
|
|
||||||
}
|
|
||||||
extra.promises.push(def3);
|
|
||||||
}
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`class and style attributes with t-widget dynamic t-att-style is properly added and updated on widget root el 1`] = `
|
exports[`class and style attributes with t-widget dynamic t-att-style is properly added and updated on widget root el 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,43 +1,5 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`animations t-transition with no delay/duration 1`] = `
|
|
||||||
"function anonymous(context,extra
|
|
||||||
) {
|
|
||||||
var h = this.utils.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
var vn1 = h('span', p1, c1);
|
|
||||||
p1.hook = {
|
|
||||||
insert: vn => {
|
|
||||||
this.utils.transitionInsert(vn.elm, 'jupiler');
|
|
||||||
},
|
|
||||||
remove: (vn, rm) => {
|
|
||||||
this.utils.transitionRemove(vn.elm, 'jupiler', rm);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
c1.push({text: \`blue\`});
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`animations t-transition, on a simple node (insert) 1`] = `
|
|
||||||
"function anonymous(context,extra
|
|
||||||
) {
|
|
||||||
var h = this.utils.h;
|
|
||||||
let c1 = [], p1 = {key:1};
|
|
||||||
var vn1 = h('span', p1, c1);
|
|
||||||
p1.hook = {
|
|
||||||
insert: vn => {
|
|
||||||
this.utils.transitionInsert(vn.elm, 'chimay');
|
|
||||||
},
|
|
||||||
remove: (vn, rm) => {
|
|
||||||
this.utils.transitionRemove(vn.elm, 'chimay', rm);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
c1.push({text: \`blue\`});
|
|
||||||
return vn1;
|
|
||||||
}"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`attributes dynamic attribute falsy variable 1`] = `
|
exports[`attributes dynamic attribute falsy variable 1`] = `
|
||||||
"function anonymous(context,extra
|
"function anonymous(context,extra
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -0,0 +1,290 @@
|
|||||||
|
import { Component, Env } from "../src/component";
|
||||||
|
import { QWeb } from "../src/qweb_core";
|
||||||
|
import {
|
||||||
|
makeDeferred,
|
||||||
|
makeTestFixture,
|
||||||
|
makeTestEnv,
|
||||||
|
nextTick,
|
||||||
|
patchNextFrame,
|
||||||
|
renderToDOM,
|
||||||
|
unpatchNextFrame
|
||||||
|
} from "./helpers";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Setup and helpers
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// We create before each test:
|
||||||
|
// - fixture: a div, appended to the DOM, intended to be the target of dom
|
||||||
|
// manipulations. Note that it is removed after each test.
|
||||||
|
// - qweb: a new QWeb instance
|
||||||
|
// - env: a WEnv, necessary to create new widgets
|
||||||
|
// - cssEl: a stylesheet injected into the dom
|
||||||
|
|
||||||
|
let fixture: HTMLElement;
|
||||||
|
let qweb: QWeb;
|
||||||
|
let env: Env;
|
||||||
|
let cssEl: HTMLElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = makeTestFixture();
|
||||||
|
env = makeTestEnv();
|
||||||
|
qweb = new QWeb();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
class Widget extends Component<any, any, any> {}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
describe("animations", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cssEl = document.createElement("style");
|
||||||
|
let css = `
|
||||||
|
.chimay-enter-active, .chimay-leave-active {
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-duration: 0.1s;
|
||||||
|
}
|
||||||
|
.chimay-enter, .chimay-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
cssEl.textContent = css.trim();
|
||||||
|
document.head.appendChild(cssEl);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.head.removeChild(cssEl);
|
||||||
|
unpatchNextFrame();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition, on a simple node (insert)", async () => {
|
||||||
|
expect.assertions(5);
|
||||||
|
qweb.addTemplate("test", `<span t-transition="chimay">blue</span>`);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(node.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
cb();
|
||||||
|
expect(node.className).toBe("chimay-enter-active chimay-enter-to");
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
|
||||||
|
|
||||||
|
expect(node.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
node.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(node.className).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition with no delay/duration", async () => {
|
||||||
|
expect.assertions(4);
|
||||||
|
qweb.addTemplate("test", `<span t-transition="jupiler">blue</span>`);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(node.className).toBe("jupiler-enter jupiler-enter-active");
|
||||||
|
cb();
|
||||||
|
expect(node.className).toBe("");
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
|
||||||
|
expect(node.className).toBe("jupiler-enter jupiler-enter-active");
|
||||||
|
await def;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition on a conditional node", async () => {
|
||||||
|
expect.assertions(7);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"TestWidget",
|
||||||
|
`<div><span t-if="!state.hide" t-transition="chimay">blue</span></div>`
|
||||||
|
);
|
||||||
|
class TestWidget extends Widget {
|
||||||
|
state = { hide: false };
|
||||||
|
}
|
||||||
|
const widget = new TestWidget(env);
|
||||||
|
|
||||||
|
// insert widget into the DOM
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
cb();
|
||||||
|
expect(spanNode.className).toBe("chimay-enter-active chimay-enter-to");
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(spanNode.className).toBe("");
|
||||||
|
|
||||||
|
// remove span from the DOM
|
||||||
|
def = makeDeferred();
|
||||||
|
widget.state.hide = true;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(spanNode.className).toBe("chimay-leave chimay-leave-active");
|
||||||
|
cb();
|
||||||
|
expect(spanNode.className).toBe("chimay-leave-active chimay-leave-to");
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(spanNode.className).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-ref", async () => {
|
||||||
|
expect.assertions(5);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"TestWidget",
|
||||||
|
`<div><span t-ref="'span'" t-transition="chimay">blue</span></div>`
|
||||||
|
);
|
||||||
|
class TestWidget extends Widget {
|
||||||
|
state = { hide: false };
|
||||||
|
}
|
||||||
|
const widget = new TestWidget(env);
|
||||||
|
|
||||||
|
// insert widget into the DOM
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
cb();
|
||||||
|
expect(spanNode.className).toBe("chimay-enter-active chimay-enter-to");
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
expect(widget.refs.span).toBe(spanNode);
|
||||||
|
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(spanNode.className).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-widget", async () => {
|
||||||
|
expect.assertions(5);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"Parent",
|
||||||
|
`<div><t t-widget="Child" t-transition="chimay"/></div>`
|
||||||
|
);
|
||||||
|
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||||
|
class Parent extends Widget {
|
||||||
|
widgets = { Child: Child };
|
||||||
|
}
|
||||||
|
class Child extends Widget {}
|
||||||
|
const widget = new Parent(env);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
|
||||||
|
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-widget and t-if", async () => {
|
||||||
|
expect.assertions(8);
|
||||||
|
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"Parent",
|
||||||
|
`<div><t t-if="state.display" t-widget="Child" t-transition="chimay"/></div>`
|
||||||
|
);
|
||||||
|
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
||||||
|
class Parent extends Widget {
|
||||||
|
widgets = { Child: Child };
|
||||||
|
state = { display: true };
|
||||||
|
}
|
||||||
|
class Child extends Widget {}
|
||||||
|
const widget = new Parent(env);
|
||||||
|
|
||||||
|
let def = makeDeferred();
|
||||||
|
var spanNode;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await widget.mount(fixture);
|
||||||
|
spanNode = widget.el!.children[0];
|
||||||
|
|
||||||
|
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
||||||
|
|
||||||
|
// remove span from the DOM
|
||||||
|
def = makeDeferred();
|
||||||
|
widget.state.display = false;
|
||||||
|
patchNextFrame(cb => {
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-leave chimay-leave-active">blue</span></div>'
|
||||||
|
);
|
||||||
|
cb();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
'<div><span class="chimay-leave-active chimay-leave-to">blue</span></div>'
|
||||||
|
);
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
await def; // wait for the mocked repaint to be done
|
||||||
|
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
||||||
|
expect(fixture.innerHTML).toBe("<div></div>");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("t-transition combined with t-mounted", async () => {
|
||||||
|
env.qweb.addTemplate(
|
||||||
|
"TestWidget",
|
||||||
|
`<div><span t-if="state.flag" t-mounted="f" t-transition="chimay">blue</span></div>`
|
||||||
|
);
|
||||||
|
class TestWidget extends Widget {
|
||||||
|
state = { flag: false };
|
||||||
|
f() {}
|
||||||
|
}
|
||||||
|
const widget = new TestWidget(env);
|
||||||
|
widget.f = jest.fn();
|
||||||
|
await widget.mount(fixture);
|
||||||
|
|
||||||
|
patchNextFrame(cb => cb());
|
||||||
|
expect(widget.f).toHaveBeenCalledTimes(0);
|
||||||
|
|
||||||
|
widget.state.flag = true;
|
||||||
|
await nextTick();
|
||||||
|
expect(widget.f).toHaveBeenCalledTimes(1);
|
||||||
|
unpatchNextFrame();
|
||||||
|
});
|
||||||
|
});
|
||||||
+1
-215
@@ -5,9 +5,7 @@ import {
|
|||||||
makeTestEnv,
|
makeTestEnv,
|
||||||
nextMicroTick,
|
nextMicroTick,
|
||||||
nextTick,
|
nextTick,
|
||||||
normalize,
|
normalize
|
||||||
patchNextFrame,
|
|
||||||
unpatchNextFrame
|
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -21,7 +19,6 @@ import {
|
|||||||
|
|
||||||
let fixture: HTMLElement;
|
let fixture: HTMLElement;
|
||||||
let env: Env;
|
let env: Env;
|
||||||
let cssEl: HTMLElement;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = makeTestFixture();
|
fixture = makeTestFixture();
|
||||||
@@ -2266,27 +2263,6 @@ describe("t-mounted directive", () => {
|
|||||||
expect(widget.refs.input).toBeDefined();
|
expect(widget.refs.input).toBeDefined();
|
||||||
expect(widget.f).toHaveBeenCalledTimes(1);
|
expect(widget.f).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("combined with a t-transition", async () => {
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"TestWidget",
|
|
||||||
`<div><span t-if="state.flag" t-mounted="f" t-transition="chimay">blue</span></div>`
|
|
||||||
);
|
|
||||||
class TestWidget extends Widget {
|
|
||||||
state = { flag: false };
|
|
||||||
f() {}
|
|
||||||
}
|
|
||||||
const widget = new TestWidget(env);
|
|
||||||
widget.f = jest.fn();
|
|
||||||
await widget.mount(fixture);
|
|
||||||
|
|
||||||
patchNextFrame(cb => cb());
|
|
||||||
expect(widget.f).toHaveBeenCalledTimes(0);
|
|
||||||
|
|
||||||
widget.state.flag = true;
|
|
||||||
await nextTick();
|
|
||||||
expect(widget.f).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("can deduce template from name", () => {
|
describe("can deduce template from name", () => {
|
||||||
@@ -2332,193 +2308,3 @@ describe("can deduce template from name", () => {
|
|||||||
expect(fixture.innerHTML).toBe("<span>Rochefort 10</span>");
|
expect(fixture.innerHTML).toBe("<span>Rochefort 10</span>");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("animations", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cssEl = document.createElement("style");
|
|
||||||
let css = `
|
|
||||||
.chimay-enter-active, .chimay-leave-active {
|
|
||||||
transition-property: opacity;
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
.chimay-enter, .chimay-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
cssEl.textContent = css.trim();
|
|
||||||
document.head.appendChild(cssEl);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
document.head.removeChild(cssEl);
|
|
||||||
unpatchNextFrame();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition on a conditional node", async () => {
|
|
||||||
expect.assertions(7);
|
|
||||||
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"TestWidget",
|
|
||||||
`<div><span t-if="!state.hide" t-transition="chimay">blue</span></div>`
|
|
||||||
);
|
|
||||||
class TestWidget extends Widget {
|
|
||||||
state = { hide: false };
|
|
||||||
}
|
|
||||||
const widget = new TestWidget(env);
|
|
||||||
|
|
||||||
// insert widget into the DOM
|
|
||||||
let def = makeDeferred();
|
|
||||||
var spanNode;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
cb();
|
|
||||||
expect(spanNode.className).toBe("chimay-enter-active chimay-enter-to");
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await widget.mount(fixture);
|
|
||||||
spanNode = widget.el!.children[0];
|
|
||||||
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(spanNode.className).toBe("");
|
|
||||||
|
|
||||||
// remove span from the DOM
|
|
||||||
def = makeDeferred();
|
|
||||||
widget.state.hide = true;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(spanNode.className).toBe("chimay-leave chimay-leave-active");
|
|
||||||
cb();
|
|
||||||
expect(spanNode.className).toBe("chimay-leave-active chimay-leave-to");
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(spanNode.className).toBe("");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition combined with t-ref", async () => {
|
|
||||||
expect.assertions(5);
|
|
||||||
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"TestWidget",
|
|
||||||
`<div><span t-ref="'span'" t-transition="chimay">blue</span></div>`
|
|
||||||
);
|
|
||||||
class TestWidget extends Widget {
|
|
||||||
state = { hide: false };
|
|
||||||
}
|
|
||||||
const widget = new TestWidget(env);
|
|
||||||
|
|
||||||
// insert widget into the DOM
|
|
||||||
let def = makeDeferred();
|
|
||||||
var spanNode;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
cb();
|
|
||||||
expect(spanNode.className).toBe("chimay-enter-active chimay-enter-to");
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await widget.mount(fixture);
|
|
||||||
spanNode = widget.el!.children[0];
|
|
||||||
expect(widget.refs.span).toBe(spanNode);
|
|
||||||
expect(spanNode.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(spanNode.className).toBe("");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition combined with t-widget", async () => {
|
|
||||||
expect.assertions(5);
|
|
||||||
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"Parent",
|
|
||||||
`<div><t t-widget="Child" t-transition="chimay"/></div>`
|
|
||||||
);
|
|
||||||
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
|
||||||
class Parent extends Widget {
|
|
||||||
widgets = { Child: Child };
|
|
||||||
}
|
|
||||||
class Child extends Widget {}
|
|
||||||
const widget = new Parent(env);
|
|
||||||
|
|
||||||
let def = makeDeferred();
|
|
||||||
var spanNode;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
|
||||||
);
|
|
||||||
cb(performance.now());
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
|
||||||
);
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await widget.mount(fixture);
|
|
||||||
spanNode = widget.el!.children[0];
|
|
||||||
|
|
||||||
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition combined with t-widget and t-if", async () => {
|
|
||||||
expect.assertions(8);
|
|
||||||
|
|
||||||
env.qweb.addTemplate(
|
|
||||||
"Parent",
|
|
||||||
`<div><t t-if="state.display" t-widget="Child" t-transition="chimay"/></div>`
|
|
||||||
);
|
|
||||||
env.qweb.addTemplate("Child", `<span>blue</span>`);
|
|
||||||
class Parent extends Widget {
|
|
||||||
widgets = { Child: Child };
|
|
||||||
state = { display: true };
|
|
||||||
}
|
|
||||||
class Child extends Widget {}
|
|
||||||
const widget = new Parent(env);
|
|
||||||
|
|
||||||
let def = makeDeferred();
|
|
||||||
var spanNode;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
|
||||||
);
|
|
||||||
cb(performance.now());
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter-active chimay-enter-to">blue</span></div>'
|
|
||||||
);
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await widget.mount(fixture);
|
|
||||||
spanNode = widget.el!.children[0];
|
|
||||||
|
|
||||||
expect(env.qweb.templates.Parent.fn.toString()).toMatchSnapshot();
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-enter chimay-enter-active">blue</span></div>'
|
|
||||||
);
|
|
||||||
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(fixture.innerHTML).toBe('<div><span class="">blue</span></div>');
|
|
||||||
|
|
||||||
// remove span from the DOM
|
|
||||||
def = makeDeferred();
|
|
||||||
widget.state.display = false;
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-leave chimay-leave-active">blue</span></div>'
|
|
||||||
);
|
|
||||||
cb(performance.now());
|
|
||||||
expect(fixture.innerHTML).toBe(
|
|
||||||
'<div><span class="chimay-leave-active chimay-leave-to">blue</span></div>'
|
|
||||||
);
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
spanNode.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(fixture.innerHTML).toBe("<div></div>");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
+41
-3
@@ -1,5 +1,6 @@
|
|||||||
import { Env } from "../src/component";
|
import { Env } from "../src/component";
|
||||||
import { QWeb, UTILS } from "../src/qweb_core";
|
import { EvalContext, QWeb, UTILS } from "../src/qweb_core";
|
||||||
|
import { patch } from "../src/vdom";
|
||||||
import "../src/qweb_directives";
|
import "../src/qweb_directives";
|
||||||
import "../src/qweb_extensions";
|
import "../src/qweb_extensions";
|
||||||
|
|
||||||
@@ -43,13 +44,50 @@ export function makeTestEnv(): Env {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function trim(str: string): string {
|
||||||
|
return str.replace(/\s/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderToDOM(
|
||||||
|
qweb: QWeb,
|
||||||
|
template: string,
|
||||||
|
context: EvalContext = {},
|
||||||
|
extra?: any
|
||||||
|
): HTMLElement | Text {
|
||||||
|
const vnode = qweb.render(template, context, extra);
|
||||||
|
|
||||||
|
// we snapshot here the compiled code. This is useful to prevent unwanted code
|
||||||
|
// change.
|
||||||
|
expect(qweb.templates[template].fn.toString()).toMatchSnapshot();
|
||||||
|
|
||||||
|
if (vnode.sel === undefined) {
|
||||||
|
return document.createTextNode(vnode.text!);
|
||||||
|
}
|
||||||
|
const node = document.createElement(vnode.sel!);
|
||||||
|
const result = patch(node, vnode);
|
||||||
|
return result.elm as HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function renderToString(
|
||||||
|
qweb: QWeb,
|
||||||
|
t: string,
|
||||||
|
context: EvalContext = {}
|
||||||
|
): string {
|
||||||
|
const node = renderToDOM(qweb, t, context);
|
||||||
|
return node instanceof Text ? node.textContent! : node.outerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hereafter, we define two helpers to patch/unpatch the nextFrame utils. This
|
||||||
|
// is useful for animations tests, as we hook before repaints to trigger
|
||||||
|
// animations (thanks to requestAnimationFrame). Patching nextFrame allows to
|
||||||
|
// simulate calls to this hook. One must not forget to unpatch afterwards.
|
||||||
let nextFrame = UTILS.nextFrame;
|
let nextFrame = UTILS.nextFrame;
|
||||||
export function patchNextFrame(f: Function): void {
|
export function patchNextFrame(f: Function) {
|
||||||
UTILS.nextFrame = (cb: () => void) => {
|
UTILS.nextFrame = (cb: () => void) => {
|
||||||
setTimeout(() => f(cb));
|
setTimeout(() => f(cb));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unpatchNextFrame(): void {
|
export function unpatchNextFrame() {
|
||||||
UTILS.nextFrame = nextFrame;
|
UTILS.nextFrame = nextFrame;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-96
@@ -1,10 +1,9 @@
|
|||||||
import { EvalContext, QWeb } from "../src/qweb_core";
|
import { QWeb } from "../src/qweb_core";
|
||||||
import { patch } from "../src/vdom";
|
|
||||||
import {
|
import {
|
||||||
makeDeferred,
|
|
||||||
normalize,
|
normalize,
|
||||||
patchNextFrame,
|
renderToDOM,
|
||||||
unpatchNextFrame
|
renderToString,
|
||||||
|
trim
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -15,45 +14,11 @@ import {
|
|||||||
// - qweb: a new QWeb instance
|
// - qweb: a new QWeb instance
|
||||||
|
|
||||||
let qweb: QWeb;
|
let qweb: QWeb;
|
||||||
let cssEl: HTMLElement;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
qweb = new QWeb();
|
qweb = new QWeb();
|
||||||
});
|
});
|
||||||
|
|
||||||
function trim(str: string): string {
|
|
||||||
return str.replace(/\s/g, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderToDOM(
|
|
||||||
qweb: QWeb,
|
|
||||||
template: string,
|
|
||||||
context: EvalContext = {},
|
|
||||||
extra?: any
|
|
||||||
): HTMLElement | Text {
|
|
||||||
const vnode = qweb.render(template, context, extra);
|
|
||||||
|
|
||||||
// we snapshot here the compiled code. This is useful to prevent unwanted code
|
|
||||||
// change.
|
|
||||||
expect(qweb.templates[template].fn.toString()).toMatchSnapshot();
|
|
||||||
|
|
||||||
if (vnode.sel === undefined) {
|
|
||||||
return document.createTextNode(vnode.text!);
|
|
||||||
}
|
|
||||||
const node = document.createElement(vnode.sel!);
|
|
||||||
const result = patch(node, vnode);
|
|
||||||
return result.elm as HTMLElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderToString(
|
|
||||||
qweb: QWeb,
|
|
||||||
t: string,
|
|
||||||
context: EvalContext = {}
|
|
||||||
): string {
|
|
||||||
const node = renderToDOM(qweb, t, context);
|
|
||||||
return node instanceof Text ? node.textContent! : node.outerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Tests
|
// Tests
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -1285,60 +1250,3 @@ describe("debugging", () => {
|
|||||||
console.log = consoleLog;
|
console.log = consoleLog;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("animations", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cssEl = document.createElement("style");
|
|
||||||
let css = `
|
|
||||||
.chimay-enter-active, .chimay-leave-active {
|
|
||||||
transition-property: opacity;
|
|
||||||
transition-duration: 0.1s;
|
|
||||||
}
|
|
||||||
.chimay-enter, .chimay-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
cssEl.textContent = css.trim();
|
|
||||||
document.head.appendChild(cssEl);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
document.head.removeChild(cssEl);
|
|
||||||
unpatchNextFrame();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition, on a simple node (insert)", async () => {
|
|
||||||
expect.assertions(5);
|
|
||||||
qweb.addTemplate("test", `<span t-transition="chimay">blue</span>`);
|
|
||||||
|
|
||||||
let def = makeDeferred();
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(node.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
cb();
|
|
||||||
expect(node.className).toBe("chimay-enter-active chimay-enter-to");
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
|
|
||||||
expect(node.className).toBe("chimay-enter chimay-enter-active");
|
|
||||||
await def; // wait for the mocked repaint to be done
|
|
||||||
node.dispatchEvent(new Event("transitionend")); // mock end of css transition
|
|
||||||
expect(node.className).toBe("");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("t-transition with no delay/duration", async () => {
|
|
||||||
expect.assertions(4);
|
|
||||||
qweb.addTemplate("test", `<span t-transition="jupiler">blue</span>`);
|
|
||||||
|
|
||||||
let def = makeDeferred();
|
|
||||||
patchNextFrame(cb => {
|
|
||||||
expect(node.className).toBe("jupiler-enter jupiler-enter-active");
|
|
||||||
cb();
|
|
||||||
expect(node.className).toBe("");
|
|
||||||
def.resolve();
|
|
||||||
});
|
|
||||||
let node: HTMLElement = <HTMLElement>renderToDOM(qweb, "test");
|
|
||||||
expect(node.className).toBe("jupiler-enter jupiler-enter-active");
|
|
||||||
await def;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user