From 431e802e31a77bfd42a9f9035409d88a8441c819 Mon Sep 17 00:00:00 2001 From: Samuel Degueldre Date: Thu, 25 Nov 2021 10:37:21 +0000 Subject: [PATCH] [FIX] web: allow patching descriptors with getter/setter with value Previously, it was impossible to patch a property that was defined with a getter or a setter with a simple value property. This commit fixes that. X-original-commit: cd7514e35b458143a948c7b8e73b05760df0a482 Part-of: odoo/odoo#80543 --- addons/web/static/src/core/utils/patch.js | 2 +- .../static/tests/core/utils/patch_tests.js | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/core/utils/patch.js b/addons/web/static/src/core/utils/patch.js index 84929850799..8d27121625a 100644 --- a/addons/web/static/src/core/utils/patch.js +++ b/addons/web/static/src/core/utils/patch.js @@ -50,7 +50,7 @@ export function patch(obj, patchName, patchValue, options = {}) { if (prevDesc.value && typeof newDesc.value === "function") { makeIntermediateFunction("value", prevDesc, newDesc, patchedFnName); } - if (prevDesc.get || prevDesc.set) { + if ((newDesc.get || newDesc.set) && (prevDesc.get || prevDesc.set)) { // get and set are defined together. If they are both defined // in the previous descriptor but only one in the new descriptor // then the other will be undefined so we need to apply the diff --git a/addons/web/static/tests/core/utils/patch_tests.js b/addons/web/static/tests/core/utils/patch_tests.js index a675a7ff9a9..20e8213af42 100644 --- a/addons/web/static/tests/core/utils/patch_tests.js +++ b/addons/web/static/tests/core/utils/patch_tests.js @@ -441,6 +441,39 @@ QUnit.module("utils", () => { assert.strictEqual(instance.dynamic, "base"); }); + QUnit.test("patch getter/setter with value", async function (assert) { + assert.expect(4); + + const BaseClass = makeBaseClass(assert, false); + + const originalDescriptor = Object.getOwnPropertyDescriptor( + BaseClass.prototype, + "dynamic" + ); + patch(BaseClass.prototype, "patch", { + dynamic: "patched", + }); + + const instance = new BaseClass(); + + assert.deepEqual(Object.getOwnPropertyDescriptor(BaseClass.prototype, "dynamic"), { + value: "patched", + writable: true, + configurable: true, + enumerable: true, + }); + assert.equal(instance.dynamic, "patched"); + + unpatch(BaseClass.prototype, "patch"); + + instance.dynamic = "base"; + assert.deepEqual( + Object.getOwnPropertyDescriptor(BaseClass.prototype, "dynamic"), + originalDescriptor + ); + assert.strictEqual(instance.dynamic, "base"); + }); + QUnit.test("async function", async function (assert) { assert.expect(3);