mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] *: re-add a bunch of tests
This commit is contained in:
committed by
Aaron Bohy
parent
b6eb4d009e
commit
ced5d0f69f
+70
-276
@@ -379,283 +379,35 @@ describe("Portal", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
// test.skip("portal destroys on crash", async () => {
|
||||
// class Child extends Component {
|
||||
// static template = xml`<span t-esc="props.error and this.will.crash" />`;
|
||||
// state = {};
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div>
|
||||
// <Portal target="'#outside'" >
|
||||
// <Child error="state.error"/>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
// state = { error: false };
|
||||
// }
|
||||
test("portal destroys on crash", async () => {
|
||||
class Child extends Component {
|
||||
static template = xml`<span t-esc="props.error and this.will.crash" />`;
|
||||
state = {};
|
||||
}
|
||||
class Parent extends Component {
|
||||
static components = { Portal, Child };
|
||||
static template = xml`
|
||||
<div>
|
||||
<Portal target="'#outside'" >
|
||||
<Child error="state.error"/>
|
||||
</Portal>
|
||||
</div>`;
|
||||
state = { error: false };
|
||||
}
|
||||
addOutsideDiv(fixture);
|
||||
const parent = await mount(Parent, fixture);
|
||||
parent.state.error = true;
|
||||
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
// parent.state.error = true;
|
||||
|
||||
// let error;
|
||||
// try {
|
||||
// await parent.render();
|
||||
// } catch (e) {
|
||||
// error = e;
|
||||
// }
|
||||
// expect(error).toBeDefined();
|
||||
// const regexp = /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g
|
||||
// expect(error.message).toMatch(regexp);
|
||||
// });
|
||||
|
||||
// test.skip("portal manual unmount", async () => {
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal };
|
||||
// static template = xml`
|
||||
// <div>
|
||||
// <Portal target="'#outside'">
|
||||
// <span>gloria</span>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
// }
|
||||
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// expect(outside.innerHTML).toBe("<span>gloria</span>");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal></portal>");
|
||||
|
||||
// parent.unmount();
|
||||
// expect(outside.innerHTML).toBe("");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal><span>gloria</span></portal>");
|
||||
|
||||
// await parent.mount(fixture);
|
||||
// expect(outside.innerHTML).toBe("<span>gloria</span>");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal></portal>");
|
||||
// });
|
||||
|
||||
// test.skip("portal manual unmount with subcomponent", async () => {
|
||||
// expect.assertions(9);
|
||||
// class Child extends Component {
|
||||
// static template = xml`<span>gloria</span>`;
|
||||
// mounted() {
|
||||
// expect(outside.contains(this.el)).toBeTruthy();
|
||||
// }
|
||||
// willUnmount() {
|
||||
// expect(outside.contains(this.el)).toBeTruthy();
|
||||
// }
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div>
|
||||
// <Portal target="'#outside'">
|
||||
// <Child />
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
// }
|
||||
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// expect(outside.innerHTML).toBe("<span>gloria</span>");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal></portal>");
|
||||
|
||||
// parent.unmount();
|
||||
// expect(outside.innerHTML).toBe("");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal><span>gloria</span></portal>");
|
||||
|
||||
// await parent.mount(fixture);
|
||||
// expect(outside.innerHTML).toBe("<span>gloria</span>");
|
||||
// expect(parent.el!.innerHTML).toBe("<portal></portal>");
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe("Portal: Events handling", () => {
|
||||
// test.skip("events triggered on movable pure node are handled", async () => {
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal };
|
||||
// static template = xml`
|
||||
// <div>
|
||||
// <Portal target="'#outside'">
|
||||
// <span id="trigger-me" t-on-custom="_onCustom" t-esc="state.val"/>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
// state = useState({ val: "ab" });
|
||||
|
||||
// _onCustom() {
|
||||
// this.state.val = "triggered";
|
||||
// }
|
||||
// }
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// expect(outside.innerHTML).toBe(`<span id="trigger-me">ab</span>`);
|
||||
// outside.querySelector("#trigger-me")!.dispatchEvent(new Event("custom"));
|
||||
// await nextTick();
|
||||
// expect(outside.innerHTML).toBe(`<span id="trigger-me">triggered</span>`);
|
||||
// });
|
||||
|
||||
// test.skip("events triggered on movable owl components are redirected", async () => {
|
||||
// let childInst: Component | null = null;
|
||||
// class Child extends Component {
|
||||
// static template = xml`
|
||||
// <span t-on-custom="_onCustom" t-esc="props.val"/>`;
|
||||
|
||||
// constructor(parent, props) {
|
||||
// super(parent, props);
|
||||
// childInst = this;
|
||||
// }
|
||||
|
||||
// _onCustom() {
|
||||
// this.trigger("custom-portal");
|
||||
// }
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div t-on-custom-portal="_onCustomPortal">
|
||||
// <Portal target="'#outside'">
|
||||
// <Child val="state.val"/>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
// state = useState({ val: "ab" });
|
||||
|
||||
// _onCustomPortal() {
|
||||
// this.state.val = "triggered";
|
||||
// }
|
||||
// }
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// expect(outside.innerHTML).toBe(`<span>ab</span>`);
|
||||
// childInst!.trigger("custom");
|
||||
// await nextTick();
|
||||
// expect(outside.innerHTML).toBe(`<span>triggered</span>`);
|
||||
// });
|
||||
|
||||
// test.skip("events triggered on contained movable owl components are redirected", async () => {
|
||||
// const steps: string[] = [];
|
||||
// let childInst: Component | null = null;
|
||||
// class Child extends Component {
|
||||
// static template = xml`
|
||||
// <span t-on-custom="_onCustom"/>`;
|
||||
|
||||
// constructor(parent, props) {
|
||||
// super(parent, props);
|
||||
// childInst = this;
|
||||
// }
|
||||
|
||||
// _onCustom() {
|
||||
// this.trigger("custom-portal");
|
||||
// }
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div t-on-custom="_handled" t-on-custom-portal="_handled">
|
||||
// <Portal target="'#outside'">
|
||||
// <div>
|
||||
// <Child/>
|
||||
// </div>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
|
||||
// _handled(ev) {
|
||||
// steps.push(ev.type);
|
||||
// }
|
||||
// }
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// childInst!.trigger("custom");
|
||||
// await nextTick();
|
||||
|
||||
// // This is expected because trigger is synchronous
|
||||
// expect(steps).toMatchObject(["custom-portal", "custom"]);
|
||||
// });
|
||||
|
||||
// test.skip("Dom events are not mapped", async () => {
|
||||
// let childInst: Component | null = null;
|
||||
// const steps: string[] = [];
|
||||
// class Child extends Component {
|
||||
// static template = xml`
|
||||
// <button>child</button>`;
|
||||
|
||||
// constructor(parent, props) {
|
||||
// super(parent, props);
|
||||
// childInst = this;
|
||||
// }
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div t-on-click="_handled">
|
||||
// <Portal target="'#outside'">
|
||||
// <Child />
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
|
||||
// _handled(ev) {
|
||||
// steps.push(ev.type as string);
|
||||
// }
|
||||
// }
|
||||
// const bodyListener = (ev) => {
|
||||
// steps.push(`body: ${ev.type}`);
|
||||
// };
|
||||
// document.body.addEventListener("click", bodyListener);
|
||||
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
// childInst!.el!.click();
|
||||
|
||||
// expect(steps).toEqual(["body: click"]);
|
||||
// document.body.removeEventListener("click", bodyListener);
|
||||
// });
|
||||
|
||||
// test.skip("Nested portals event propagation", async () => {
|
||||
// const outside2 = document.createElement("div");
|
||||
// outside2.setAttribute("id", "outside2");
|
||||
// fixture.appendChild(outside2);
|
||||
|
||||
// const steps: Array<string> = [];
|
||||
// let childInst: Component | null = null;
|
||||
// class Child2 extends Component {
|
||||
// static template = xml`<div>child2</div>`;
|
||||
// constructor(parent, props) {
|
||||
// super(parent, props);
|
||||
// childInst = this;
|
||||
// }
|
||||
// }
|
||||
// class Child extends Component {
|
||||
// static components = { Portal, Child2 };
|
||||
// static template = xml`
|
||||
// <Portal target="'#outside2'">
|
||||
// <Child2 />
|
||||
// </Portal>`;
|
||||
// }
|
||||
// class Parent extends Component {
|
||||
// static components = { Portal, Child };
|
||||
// static template = xml`
|
||||
// <div t-on-custom='_handled'>
|
||||
// <Portal target="'#outside'">
|
||||
// <Child/>
|
||||
// </Portal>
|
||||
// </div>`;
|
||||
|
||||
// _handled(ev) {
|
||||
// steps.push(`${ev.type} from ${ev.originalComponent.constructor.name}`);
|
||||
// }
|
||||
// }
|
||||
|
||||
// const parent = new Parent();
|
||||
// await parent.mount(fixture);
|
||||
|
||||
// childInst!.trigger("custom");
|
||||
// expect(steps).toEqual(["custom from Child2"]);
|
||||
// });
|
||||
let error;
|
||||
try {
|
||||
await parent.render();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeDefined();
|
||||
const regexp = /Cannot read properties of undefined \(reading 'crash'\)|Cannot read property 'crash' of undefined/g
|
||||
expect(error.message).toMatch(regexp);
|
||||
});
|
||||
|
||||
test("portal's parent's env is not polluted", async () => {
|
||||
class Child extends Component {
|
||||
@@ -750,3 +502,45 @@ describe("Portal: UI/UX", () => {
|
||||
expect(document.activeElement === inputReRendered).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Portal: Props validation", () => {
|
||||
test.skip("target is mandatory", async () => {
|
||||
class Parent extends Component {
|
||||
static components = { Portal };
|
||||
static template = xml`
|
||||
<div>
|
||||
<Portal>
|
||||
<div>2</div>
|
||||
</Portal>
|
||||
</div>`;
|
||||
}
|
||||
let error;
|
||||
try {
|
||||
await mount(Parent, fixture);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBe(`Missing props 'target' (component 'Portal')`);
|
||||
});
|
||||
|
||||
test.skip("target is not list", async () => {
|
||||
class Parent extends Component {
|
||||
static components = { Portal };
|
||||
static template = xml`
|
||||
<div>
|
||||
<Portal target="['body']">
|
||||
<div>2</div>
|
||||
</Portal>
|
||||
</div>`;
|
||||
}
|
||||
let error;
|
||||
try {
|
||||
await mount(Parent, fixture);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
expect(error).toBeDefined();
|
||||
expect(error.message).toBe(`Invalid Prop 'target' in component 'Portal'`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user