From 531f8723e5e1ceee403e431dfc553e15cf4cd43f Mon Sep 17 00:00:00 2001 From: Carl-Erik Kopseng Date: Thu, 10 Aug 2017 08:38:19 +0200 Subject: [PATCH 1/3] Cache reference to filter in stubbing calls closes #1521 --- lib/sinon/spy.js | 7 +++++-- test/issues/issues-test.js | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/sinon/spy.js b/lib/sinon/spy.js index 497dc3068..87ff6fcf5 100644 --- a/lib/sinon/spy.js +++ b/lib/sinon/spy.js @@ -12,11 +12,14 @@ var wrapMethod = require("./util/core/wrap-method"); var sinonFormat = require("./util/core/format"); var valueToString = require("./util/core/value-to-string"); +/* cache references to library methods so that they also can be stubbed without problems */ var push = Array.prototype.push; var slice = Array.prototype.slice; -var callId = 0; +var filter = Array.prototype.filter; var ErrorConstructor = Error.prototype.constructor; +var callId = 0; + function spy(object, property, types) { var descriptor, methodDesc; @@ -340,7 +343,7 @@ var spyApi = { }, matchingFakes: function (args, strict) { - return (this.fakes || []).filter(function (fake) { + return filter.call(this.fakes || [], function (fake) { return fake.matches(args, strict); }); }, diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index 90bf205ad..0227a1010 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -321,7 +321,7 @@ describe("issues", function () { }); }); - describe("#1512", function () { + describe("#1512 - sandbox.stub(obj,protoMethod)", function () { var sandbox; beforeEach(function () { @@ -341,4 +341,24 @@ describe("issues", function () { assert(stub.called); }); }); + + describe("#1521 - stubbing Array.prototype.filter", function () { + var orgFilter; + + before(function () { + orgFilter = Array.prototype.filter; + }); + + afterEach(function () { + /* eslint-disable no-extend-native */ + Array.prototype.filter = orgFilter; + }); + + it("should be possible stub filter", function () { + var stub = sinon.stub(Array.prototype, "filter"); + [1, 2, 3].filter(function () { return false; }); + assert(stub.calledOnce); + }); + + }); }); From 56ca580764e381e092473ec50b7c0ea2482725d1 Mon Sep 17 00:00:00 2001 From: Carl-Erik Kopseng Date: Thu, 10 Aug 2017 12:18:15 +0200 Subject: [PATCH 2/3] Cache other references to Array.prototype.filter --- lib/sinon/call.js | 5 +++-- lib/sinon/collection.js | 5 +++-- lib/sinon/mock.js | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/sinon/call.js b/lib/sinon/call.js index a9484ca54..9d698e56b 100644 --- a/lib/sinon/call.js +++ b/lib/sinon/call.js @@ -6,6 +6,7 @@ var functionName = require("./util/core/function-name"); var sinonFormat = require("./util/core/format"); var valueToString = require("./util/core/value-to-string"); var slice = Array.prototype.slice; +var filter = Array.prototype.filter; function throwYieldError(proxy, text, args) { var msg = functionName(proxy) + text; @@ -131,7 +132,7 @@ var callProto = { yieldOn: function (thisValue) { var args = slice.call(this.args); - var yieldFn = args.filter(function (arg) { + var yieldFn = filter.call(args, function (arg) { return typeof arg === "function"; })[0]; @@ -148,7 +149,7 @@ var callProto = { yieldToOn: function (prop, thisValue) { var args = slice.call(this.args); - var yieldArg = args.filter(function (arg) { + var yieldArg = filter.call(args, function (arg) { return arg && typeof arg[prop] === "function"; })[0]; var yieldFn = yieldArg && yieldArg[prop]; diff --git a/lib/sinon/collection.js b/lib/sinon/collection.js index 0f369db3f..7a487a20c 100644 --- a/lib/sinon/collection.js +++ b/lib/sinon/collection.js @@ -6,7 +6,8 @@ var sinonMock = require("./mock"); var collectOwnMethods = require("./collect-own-methods"); var valueToString = require("./util/core/value-to-string"); -var push = [].push; +var push = Array.prototype.push; +var filter = Array.prototype.filter; function getFakes(fakeCollection) { if (!fakeCollection.fakes) { @@ -18,7 +19,7 @@ function getFakes(fakeCollection) { function each(fakeCollection, method) { var fakes = getFakes(fakeCollection); - var matchingFakes = fakes.filter(function (fake) { + var matchingFakes = filter.call(fakes, function (fake) { return typeof fake[method] === "function"; }); diff --git a/lib/sinon/mock.js b/lib/sinon/mock.js index 3b4f37318..54084d8d0 100644 --- a/lib/sinon/mock.js +++ b/lib/sinon/mock.js @@ -8,6 +8,7 @@ var deepEqual = require("./util/core/deep-equal").use(match); var wrapMethod = require("./util/core/wrap-method"); var push = Array.prototype.push; +var filter = Array.prototype.filter; function mock(object) { if (!object || typeof object === "string") { @@ -118,13 +119,13 @@ extend(mock, { var currentArgs = args || []; var available; - var expectationsWithMatchingArgs = expectations.filter(function (expectation) { + var expectationsWithMatchingArgs = filter.call(expectations, function (expectation) { var expectedArgs = expectation.expectedArguments || []; return arrayEquals(expectedArgs, currentArgs, expectation.expectsExactArgCount); }); - var expectationsToApply = expectationsWithMatchingArgs.filter(function (expectation) { + var expectationsToApply = filter.call(expectationsWithMatchingArgs, function (expectation) { return !expectation.met() && expectation.allowsCall(thisValue, args); }); From 052a2d0b26aa7ccff1193c16b5828ed7c7293d5d Mon Sep 17 00:00:00 2001 From: Carl-Erik Kopseng Date: Thu, 10 Aug 2017 12:30:35 +0200 Subject: [PATCH 3/3] Add requirements to pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 8e5216400..ebcc6c048 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,11 +13,16 @@ #### Solution - optional > When contributing code (and not just fixing typos, documentation and configuration), please describe why/how your solution works. This helps reviewers spot any mistakes in the implementation. > -> Example: +> Example: > "This solution works by adding a `paintBlue()` method" > Then your reviewer might spot a mistake in the implementation, if `paintBlue()` uses the colour red. #### How to verify - mandatory -1. Check out this branch (see github instructions below) +1. Check out this branch 2. `npm install` 3. + +#### Checklist for author + +- [ ] `npm run lint` passes +- [ ] References to standard library functions are [cached](https://github.com/sinonjs/sinon/pull/1523).