Skip to content

Commit

Permalink
Retain spy function names and fix spy.named(name) (#1987)
Browse files Browse the repository at this point in the history
  • Loading branch information
mantoni committed Mar 4, 2019
1 parent 3275d18 commit 19b3fc7
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
13 changes: 13 additions & 0 deletions lib/sinon/spy.js
Expand Up @@ -152,6 +152,12 @@ function createProxy(func, proxyLength) {
return p.invoke(func, this, slice(arguments));
};
}
var nameDescriptor = Object.getOwnPropertyDescriptor(func, "name");
if (nameDescriptor && nameDescriptor.configurable) {
// IE 11 functions don't have a name.
// Safari 9 has names that are not configurable.
Object.defineProperty(p, "name", nameDescriptor);
}
extend.nonEnum(p, {
isSinonProxy: true,

Expand Down Expand Up @@ -332,6 +338,13 @@ var spyApi = {

named: function named(name) {
this.displayName = name;
var nameDescriptor = Object.getOwnPropertyDescriptor(this, "name");
if (nameDescriptor && nameDescriptor.configurable) {
// IE 11 functions don't have a name.
// Safari 9 has names that are not configurable.
nameDescriptor.value = name;
Object.defineProperty(this, "name", nameDescriptor);
}
return this;
},

Expand Down
3 changes: 2 additions & 1 deletion test/issues/issues-test.js
Expand Up @@ -111,7 +111,8 @@ describe("issues", function() {
// IE 11 does not support the function name property
if (bob.name) {
it("should not rename spies", function() {
var expectedName = "proxy";
var nameDescriptor = Object.getOwnPropertyDescriptor(bob, "name");
var expectedName = nameDescriptor && nameDescriptor.configurable ? "bob" : "proxy";
var spy = sinon.spy(bob);

assert.equals(spy.name, expectedName);
Expand Down
24 changes: 23 additions & 1 deletion test/spy-test.js
Expand Up @@ -207,6 +207,16 @@ function spyNeverCalledTests(method) {
};
}

function verifyFunctionName(func, expectedName) {
var descriptor = Object.getOwnPropertyDescriptor(func, "name");
if (descriptor && descriptor.configurable) {
// IE 11 functions don't have a name.
// Safari 9 has names that are not configurable.
assert.equals(descriptor.value, expectedName);
assert.equals(func.name, expectedName);
}
}

describe("spy", function() {
it("does not throw if called without function", function() {
refute.exception(function() {
Expand Down Expand Up @@ -423,10 +433,11 @@ describe("spy", function() {
});

describe(".named", function() {
it("sets displayName", function() {
it("sets name and displayName", function() {
var spy = createSpy();
var retval = spy.named("beep");
assert.equals(spy.displayName, "beep");
verifyFunctionName(spy, "beep");
assert.same(spy, retval);
});
});
Expand Down Expand Up @@ -506,6 +517,17 @@ describe("spy", function() {
assert.exception(spy, err);
});

it("retains function name", function() {
function test() {
return;
}

var spy = createSpy.create(test);

assert.equals(spy.displayName, "test");
verifyFunctionName(spy, "test");
});

it("retains function length 0", function() {
var spy = createSpy.create(function() {
return;
Expand Down

0 comments on commit 19b3fc7

Please sign in to comment.