From 01cbe618db2a9cc4b3d58080159a8c0c4bd5999b Mon Sep 17 00:00:00 2001 From: Morgan Roderick Date: Fri, 27 Apr 2018 11:30:09 +0100 Subject: [PATCH] Allow replacing non-own object properties (#1705) --- lib/sinon/sandbox.js | 6 +++--- test/sandbox-test.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index dcc3fa9f1..507c99e0e 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -165,7 +165,7 @@ function Sandbox() { } sandbox.replace = function replace(object, property, replacement) { - var descriptor = Object.getOwnPropertyDescriptor(object, property); + var descriptor = getPropertyDescriptor(object, property); if (typeof descriptor === "undefined") { throw new TypeError("Cannot replace non-existent own property " + valueToString(property)); @@ -196,7 +196,7 @@ function Sandbox() { }; sandbox.replaceGetter = function replaceGetter(object, property, replacement) { - var descriptor = Object.getOwnPropertyDescriptor(object, property); + var descriptor = getPropertyDescriptor(object, property); if (typeof descriptor === "undefined") { throw new TypeError("Cannot replace non-existent own property " + valueToString(property)); @@ -222,7 +222,7 @@ function Sandbox() { }; sandbox.replaceSetter = function replaceSetter(object, property, replacement) { - var descriptor = Object.getOwnPropertyDescriptor(object, property); + var descriptor = getPropertyDescriptor(object, property); if (typeof descriptor === "undefined") { throw new TypeError("Cannot replace non-existent own property " + valueToString(property)); diff --git a/test/sandbox-test.js b/test/sandbox-test.js index 158758a3a..fd51ea004 100644 --- a/test/sandbox-test.js +++ b/test/sandbox-test.js @@ -581,6 +581,25 @@ describe("Sandbox", function () { assert.equals(actual, replacement); }); + it("should replace an inherited property", function () { + var expected = "baz"; + var replacement = fake.returns(expected); + var existing = "existing"; + var object = Object.create({ + get foo() { + return existing; + } + }); + + this.sandbox.replaceGetter(object, "foo", replacement); + + assert.equals(object.foo, expected); + + this.sandbox.restore(); + + assert.equals(object.foo, existing); + }); + describe("when called with a non-function replacement argument", function () { it("should throw a TypeError", function () { var sandbox = this.sandbox; @@ -652,6 +671,27 @@ describe("Sandbox", function () { assert.equals(actual, replacement); }); + it("should replace an inherited property", function () { + // eslint-disable-next-line accessor-pairs + var object = Object.create({ + set foo(value) { + this.prop = value; + }, + prop: "bar" + }); + var replacement = function (value) { + this.prop = value + "blabla"; + }; + + this.sandbox.replaceSetter(object, "foo", replacement); + object.foo = "doodle"; + assert.equals(object.prop, "doodleblabla"); + + this.sandbox.restore(); + object.foo = "doodle"; + assert.equals(object.prop, "doodle"); + }); + describe("when called with a non-function replacement argument", function () { it("should throw a TypeError", function () { var sandbox = this.sandbox;