[FIX] web: patch: can call a not bound patched function

Before this commit, it wasn't possible to patch some functions
(e.g. setTimeout) on window, because of the way we call them.
Indeed, we typically do `setTimeout(...)`, because this function
doesn't need to be bound to the window object.

X-original-commit: 476dbf75bb88dc2ddfdd47c1f229ce53cf7fadb7
Part-of: odoo/odoo#78698
This commit is contained in:
Aaron Bohy
2021-10-20 15:15:22 +00:00
parent 60d62a1d9d
commit f9594fba3f
2 changed files with 32 additions and 3 deletions
+8 -3
View File
@@ -77,10 +77,15 @@ export function patch(obj, patchName, patchValue, options = {}) {
} else {
newDesc[key] = {
[patchedFnName](...args) {
const prevSuper = this._super;
this._super = _superFn.bind(this);
let prevSuper;
if (this) {
prevSuper = this._super;
this._super = _superFn.bind(this);
}
const result = patchFn.call(this, ...args);
this._super = prevSuper;
if (this) {
this._super = prevSuper;
}
return result;
},
}[patchedFnName];
@@ -1084,6 +1084,30 @@ QUnit.module("utils", () => {
assert.verifySteps(["obj"]);
});
QUnit.test("can call a non bound patched method", async function (assert) {
// use case: patching a function on window (e.g. setTimeout)
assert.expect(3);
const obj = {
fn() {
assert.step("original");
},
};
const originalFn = obj.fn;
patch(obj, "patch", {
fn() {
assert.step("patched");
originalFn();
},
});
const fn = obj.fn; // purposely not bound
fn();
assert.verifySteps(["patched", "original"]);
});
QUnit.module("patch 'pure' option");
QUnit.test("function objects are preserved with 'pure' patch", async function (assert) {