Skip to content

Commit

Permalink
Move replacement using accessor into own function
Browse files Browse the repository at this point in the history
  • Loading branch information
fatso83 committed Oct 3, 2023
1 parent fb7db2b commit e71b0c9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
42 changes: 26 additions & 16 deletions lib/sinon/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,13 @@ function Sandbox() {
sandbox.injectedKeys.length = 0;
};

function getFakeRestorer(object, property, forceAssignment) {
/**
* Creates a restorer function for the property
* @param {object|Function} object
* @param {string} property
* @param {boolean} forceAssignment
*/
function getFakeRestorer(object, property, forceAssignment = false) {
const descriptor = getPropertyDescriptor(object, property);
const value = object[property];

Expand Down Expand Up @@ -229,11 +235,9 @@ function Sandbox() {
* @param {object|Function} object
* @param {string} property
* @param {*} replacement a fake, stub, spy or any other value
* @param {object} [options]
* @param {boolean} options.forceAssignment allows you to force use of assignment in the presence of a setter
* @returns {*}
*/
sandbox.replace = function replace(object, property, replacement, options) {
sandbox.replace = function replace(object, property, replacement) {
const descriptor = getPropertyDescriptor(object, property);

if (typeof descriptor === "undefined") {
Expand All @@ -248,18 +252,12 @@ function Sandbox() {
throw new TypeError("Expected replacement argument to be defined");
}

if (!options?.forceAssignment) {
if (typeof descriptor.get === "function") {
throw new Error(
"Use sandbox.replaceGetter for replacing getters"
);
}
if (typeof descriptor.get === "function") {
throw new Error("Use sandbox.replaceGetter for replacing getters");
}

if (typeof descriptor.set === "function") {
throw new Error(
"Use sandbox.replaceSetter for replacing setters"
);
}
if (typeof descriptor.set === "function") {
throw new Error("Use sandbox.replaceSetter for replacing setters");
}

if (typeof object[property] !== typeof replacement) {
Expand All @@ -275,14 +273,26 @@ function Sandbox() {
// store a function for restoring the replaced property
push(
fakeRestorers,
getFakeRestorer(object, property, options?.forceAssignment)
getFakeRestorer(object, property)
);

object[property] = replacement;

return replacement;
};

sandbox.replace.usingAccessor = function replaceUsingAccessor(object, property, replacement) {
// store a function for restoring the replaced property
push(
fakeRestorers,
getFakeRestorer(object, property, true)
);

object[property] = replacement;

return replacement;
}

sandbox.define = function define(object, property, value) {
const descriptor = getPropertyDescriptor(object, property);

Expand Down
6 changes: 2 additions & 4 deletions test/sandbox-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ describe("Sandbox", function () {
);
});

it("should allow forcing assignment", function () {
it("should allow using assignment when replacing a value", function () {
const sandbox = this.sandbox;
let hiddenFoo = () => "original";
const object = {
Expand All @@ -1129,9 +1129,7 @@ describe("Sandbox", function () {
};

assert.equals(object.foo(), "original");
sandbox.replace(object, "foo", sinonFake.returns("fake"), {
forceAssignment: true,
});
sandbox.replace.usingAccessor(object, "foo", sinonFake.returns("fake"));
assert.equals(object.foo(), "fake");
sandbox.restore();
assert.equals(object.foo(), "original");
Expand Down

0 comments on commit e71b0c9

Please sign in to comment.