restore fake timers tests
// Employs 'mini-mocha' to emulate running in the Mocha test runner (mochajs.org)
require("@fatso83/mini-mocha").install();
const sinon = require("sinon");
const {assert} = require('@sinonjs/referee');
describe("original sinon", function() {
it("should clear all timers when doing sandbox is restored", function() {
const sandbox = sinon.createSandbox();
const clock = sandbox.useFakeTimers();
const intervalTaskStub = sandbox.stub().callsFake(() => console.log('...executing task...'));
setInterval(intervalTaskStub, 1000);
console.log('\nabout to tick 5s');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 5);
console.log('\nabout to tick 5s');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 10);
sandbox.restore();
console.log('\nabout to tick 5s (after clearInterval)');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 10); // FAIL - Actual: 15; Expectation: should remain 10
// the IntervalTimer should stop running after restore, so ticking another 5s shouldn't have made the task be executed 5 more times.
});
});
describe("clearable sinon", function() {
let clearableSinon;
beforeEach(() => {
clearableSinon = new ClearableSinon();
});
it("should clear all timers when doing sandbox is restored", function() {
const sandbox = clearableSinon.sandbox;
const clock = clearableSinon.activateFakeTimer();
const intervalTaskStub = sandbox.stub().callsFake(() => console.log('...executing task...'));
setInterval(intervalTaskStub, 1000);
console.log('\nabout to tick 5s');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 5);
console.log('\nabout to tick 5s');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 10);
clearableSinon.restore();
console.log('\nabout to tick 5s (after clearInterval)');
clock.tick(5000);
sinon.assert.callCount(intervalTaskStub, 10); // PASS
});
});
class ClearableSinon {
constructor() {
this._sandbox = sinon.createSandbox();
this._originalSetIntervalSpy = this._sandbox.spy(global, 'setInterval');
this._originalSetTimeoutSpy = this._sandbox.spy(global, 'setTimeout');
// TODO: setImmediate
this._sandbox;
}
get sandbox() {
return this._sandbox;
}
restore() {
this._clearFakeTimers(); // clear all fake timers before restoring sandbox(including the fake clock)
this._sandbox.restore();
this._clearOriginalPendingTimers(); // clear all real timers after restoring sandbox (to stop all timers set up before using fake timers)
}
activateFakeTimer() {
if (this._fakeTimer) {
return this._fakeTimer;
}
this._fakeTimer = this._sandbox.useFakeTimers(); // from here on the Timer functions will be mocked.
if (this._fakeSetIntervalSpy || this._fakeSetTimeoutSpy) {
this._clearFakeTimers();
}
this._fakeSetIntervalSpy = this._sandbox.spy(global, 'setInterval');
this._fakeSetTimeoutSpy = this._sandbox.spy(global, 'setTimeout');
return this._fakeTimer;
}
_clearOriginalPendingTimers() {
this._originalSetIntervalSpy.returnValues.map((timerId) => global.clearInterval(timerId));
this._originalSetTimeoutSpy.returnValues.map((timerId) => global.clearTimeout(timerId));
}
_clearFakeTimers() {
this._fakeSetIntervalSpy.returnValues.map((timerId) => global.clearInterval(timerId));
this._fakeSetTimeoutSpy.returnValues.map((timerId) => global.clearTimeout(timerId));
}
}
no comments