[IMP] web: patch/unpatch: allow to re-apply a patch
In tests, we might want to disable a specific patch for a specific test (e.g. to remove a monkey patch done when another addon is installed, to test the behavior of the current addon). Before this commit, it was possible to unpatch at the beginning of the test, but we couldn't re-patch when the test was over. Feature required by task~2392303
This commit is contained in:
@@ -897,6 +897,7 @@ var utils = {
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {string} patchName
|
||||
* @returns {Object} the removed patch
|
||||
*/
|
||||
unpatch: function (obj, patchName) {
|
||||
const objDesc = patchMap.get(obj);
|
||||
@@ -915,11 +916,16 @@ var utils = {
|
||||
}
|
||||
|
||||
// Re-apply the patches except the one to remove.
|
||||
let removedPatch;
|
||||
for (const patchDesc of objDesc.patches) {
|
||||
if (patchDesc.name !== patchName) {
|
||||
utils.patch(obj, patchDesc.name, patchDesc.patch);
|
||||
} else {
|
||||
removedPatch = patchDesc.patch;
|
||||
}
|
||||
}
|
||||
|
||||
return removedPatch;
|
||||
},
|
||||
/**
|
||||
* @param {any} node
|
||||
|
||||
@@ -290,6 +290,52 @@ QUnit.module('core', {}, function () {
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('unpatch and re-patch', async function (assert) {
|
||||
assert.expect(13);
|
||||
|
||||
const BaseClass = makeBaseClass(assert);
|
||||
|
||||
patch(BaseClass.prototype, 'patch', {
|
||||
setup() {
|
||||
this._super();
|
||||
assert.step('patch.setup');
|
||||
},
|
||||
fn() {
|
||||
this._super();
|
||||
assert.step('patch.fn');
|
||||
},
|
||||
});
|
||||
|
||||
(new BaseClass()).fn();
|
||||
|
||||
assert.verifySteps([
|
||||
'base.setup',
|
||||
'patch.setup',
|
||||
'base.fn',
|
||||
'patch.fn',
|
||||
]);
|
||||
|
||||
const p = unpatch(BaseClass.prototype, 'patch');
|
||||
|
||||
(new BaseClass()).fn();
|
||||
|
||||
assert.verifySteps([
|
||||
'base.setup',
|
||||
'base.fn',
|
||||
]);
|
||||
|
||||
patch(BaseClass.prototype, 'patch', p);
|
||||
|
||||
(new BaseClass()).fn();
|
||||
|
||||
assert.verifySteps([
|
||||
'base.setup',
|
||||
'patch.setup',
|
||||
'base.fn',
|
||||
'patch.fn',
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test('patch for specialization', async function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
|
||||
@@ -2811,10 +2811,14 @@ Therefore, patching a component constructor is always possible:
|
||||
Removing a patch
|
||||
-----------------
|
||||
|
||||
We can also remove the patch by calling the ``unpatch`` function. This is really
|
||||
only useful for tests.
|
||||
In tests, it is sometimes useful to remove a patch for a specific test, for instance,
|
||||
to remove a patch applied when another addon is installed, which overrides the behavior
|
||||
implemented in the addon where the test is defined. The function ``unpatch`` exists for
|
||||
that purpose. It returns the removed patch, such that it can be re-applied at the end
|
||||
of the test.
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
unpatch(object, "patch name");
|
||||
|
||||
const p = unpatch(object, "patch name");
|
||||
// test stuff here
|
||||
patch(object, "patch name", p);
|
||||
|
||||
Reference in New Issue
Block a user