From 8b6f8a8c34c82b3535de7d230c55a722ebb735a7 Mon Sep 17 00:00:00 2001 From: Piotr Jamroz Date: Mon, 21 May 2018 11:50:16 +0200 Subject: [PATCH 1/4] Revert spied fakeTimers to original state When sandbox.useFakeTimers() is called, the original setTimeout and other methods are replaced with fake methods. When such fake method is spied it's replaced again with another fake. To make sure that sandbox.restore() reverts setTimeout and other methods to the original state these fakes should be restored in reverse order to make sure each fake is restored to its predecessor when calling fake.restore(). --- lib/sinon/sandbox.js | 2 +- test/sandbox-test.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index 9d63c084d..199cccf0a 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -132,7 +132,7 @@ function Sandbox() { throw new Error("sandbox.restore() does not take any parameters. Perhaps you meant stub.restore()"); } - applyOnEach(collection, "restore"); + applyOnEach(collection.reverse(), "restore"); collection = []; forEach.call(fakeRestorers, function (restorer) { diff --git a/test/sandbox-test.js b/test/sandbox-test.js index cd07744a1..fef2ca4b2 100644 --- a/test/sandbox-test.js +++ b/test/sandbox-test.js @@ -933,6 +933,17 @@ describe("Sandbox", function () { assert.same(setTimeout, originalSetTimeout, "fakeTimers restored"); }); + + it("restores spied fake timers when then sanddox is restored", function () { + var originalSetTimeout = setTimeout; + + this.sandbox.useFakeTimers(); + this.sandbox.spy(global, "setTimeout"); + + this.sandbox.restore(); + + assert.same(originalSetTimeout, global.setTimeout, "fakeTimers restored"); + }); }); describe(".usingPromise", function () { From 6799e1ca99b6da7ef83004dbd8c80de1180a9458 Mon Sep 17 00:00:00 2001 From: Piotr Jamroz Date: Mon, 21 May 2018 11:51:48 +0200 Subject: [PATCH 2/4] Use fakeTimers in the default sandbox This is to allow restoring spied fakeTimers in default sandbox. --- lib/sinon.js | 3 --- test/issues/issues-test.js | 13 +++++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/sinon.js b/lib/sinon.js index a0b171d05..e05fc7a1c 100644 --- a/lib/sinon.js +++ b/lib/sinon.js @@ -24,11 +24,8 @@ var apiMethods = { setFormatter: format.setFormatter, // fake timers - useFakeTimers: fakeTimers.useFakeTimers, - clock: fakeTimers.clock, timers: fakeTimers.timers, - // fake XHR xhr: nise.fakeXhr.xhr, FakeXMLHttpRequest: nise.fakeXhr.FakeXMLHttpRequest, diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index 0c3d84433..ccea369d1 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -466,4 +466,17 @@ describe("issues", function () { // TypeError: Attempted to wrap someMethod which is already wrapped }); }); + + describe("sinon.restore spied fakeTimers", function () { + it("should restore spied fake timers", function () { + var originalSetTimeout = setTimeout; + + sinon.useFakeTimers(); + sinon.spy(global, "setTimeout"); + + sinon.restore(); + + assert.same(originalSetTimeout, global.setTimeout, "fakeTimers restored"); + }); + }); }); From d19a4c0ee69d73f6cb0c0923f3bf5d1ad4afa335 Mon Sep 17 00:00:00 2001 From: Piotr Jamroz Date: Mon, 21 May 2018 12:00:14 +0200 Subject: [PATCH 3/4] Add issue number --- test/issues/issues-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index ccea369d1..613efcec1 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -467,7 +467,7 @@ describe("issues", function () { }); }); - describe("sinon.restore spied fakeTimers", function () { + describe("#1801 - sinon.restore spied fakeTimers", function () { it("should restore spied fake timers", function () { var originalSetTimeout = setTimeout; From 087bc1c0699b1fd2efd83e8461923e6f28f4b7c2 Mon Sep 17 00:00:00 2001 From: Piotr Jamroz Date: Mon, 21 May 2018 15:06:37 +0200 Subject: [PATCH 4/4] Cache reverse function --- lib/sinon/sandbox.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index 199cccf0a..a33f95b13 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -17,6 +17,7 @@ var fakeXhr = require("nise").fakeXhr; var usePromiseLibrary = require("./util/core/use-promise-library"); // cache original versions, to prevent issues when they are stubbed in user space +var reverse = Array.prototype.reverse; var push = Array.prototype.push; var filter = Array.prototype.filter; var forEach = Array.prototype.filter; @@ -132,7 +133,8 @@ function Sandbox() { throw new Error("sandbox.restore() does not take any parameters. Perhaps you meant stub.restore()"); } - applyOnEach(collection.reverse(), "restore"); + reverse.call(collection); + applyOnEach(collection, "restore"); collection = []; forEach.call(fakeRestorers, function (restorer) {