Skip to content

Commit

Permalink
Copy over acessor properties to target object sinonjs#2387
Browse files Browse the repository at this point in the history
  • Loading branch information
sauravazad committed Jul 17, 2021
1 parent 57c6c63 commit 258caee
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 5 deletions.
27 changes: 22 additions & 5 deletions lib/sinon/util/core/extend.js
Expand Up @@ -102,13 +102,30 @@ module.exports = function extend(target, ...sources) {
if (prop === "name" && !destOwnPropertyDescriptor.writable) {
return;
}

Object.defineProperty(dest, prop, {
const descriptors = {
configurable: sourceOwnPropertyDescriptor.configurable,
enumerable: sourceOwnPropertyDescriptor.enumerable,
writable: sourceOwnPropertyDescriptor.writable,
value: sourceOwnPropertyDescriptor.value,
});
};
/*
if the sorce has an Accessor property copy over the accessor functions (get and set)
data properties has writable attribute where as acessor property don't
REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#properties
*/

if (hasOwnProperty(sourceOwnPropertyDescriptor, "writable")) {
descriptors.writable = sourceOwnPropertyDescriptor.writable;
descriptors.value = sourceOwnPropertyDescriptor.value;
} else {
if (sourceOwnPropertyDescriptor.get) {
descriptors.get =
sourceOwnPropertyDescriptor.get.bind(dest);
}
if (sourceOwnPropertyDescriptor.set) {
descriptors.set =
sourceOwnPropertyDescriptor.set.bind(dest);
}
}
Object.defineProperty(dest, prop, descriptors);
}
);
};
Expand Down
52 changes: 52 additions & 0 deletions test/extend-test.js
Expand Up @@ -78,6 +78,58 @@ describe("extend", function () {
assert.equals(result, expected);
});

it("copies acessor properties into the target", function () {
var target = {
hello: "hello",
};
const obj = {
private: 1,
};
Object.defineProperty(obj, "lexical", {
configurable: true,
enumerable: true,
get: () => this.private,
set: (value) => {
this.private = value;
},
});
Object.defineProperty(obj, "instance", {
configurable: true,
enumerable: true,
get: () => obj.private,
set: (value) => {
obj.private = value;
},
});
Object.defineProperty(obj, "bound", {
configurable: true,
enumerable: true,
get: function () {
return this.private;
},
set: function (value) {
this.private = value;
},
});
extend(target, obj);
assert.equals(target.hello, "hello");
assert.equals(target.lexical === undefined, true);
assert.equals(target.instance, 1);
assert.equals(target.bound, 1);
target.lexical = 2;
assert.equals(target.lexical, 2);
assert.equals(target.instance, 1);
assert.equals(target.bound, 1);
target.instance = 3;
assert.equals(target.lexical, 2);
assert.equals(target.instance, 3);
assert.equals(target.bound, 1);
target.bound = 4;
assert.equals(target.lexical, 2);
assert.equals(target.instance, 3);
assert.equals(target.bound, 4);
});

context("when 'name' property is not writable", function () {
it("does not attempt to write to the property", function () {
var object1 = { prop1: null };
Expand Down

0 comments on commit 258caee

Please sign in to comment.