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 64fad59
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 6 deletions.
23 changes: 17 additions & 6 deletions lib/sinon/util/core/extend.js
Expand Up @@ -102,13 +102,24 @@ 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,
});
enumerable: sourceOwnPropertyDescriptor.enumerable
}
/*
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
50 changes: 50 additions & 0 deletions test/extend-test.js
Expand Up @@ -78,6 +78,56 @@ 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 64fad59

Please sign in to comment.