Describe the bug
When sinon.useFakeTimers is used in a nested fashion, or code crashes or early exist before a timer is restored, it becomes impossible to reset the timers to their default configuration.
To Reproduce
Steps to reproduce the behavior:
- Go to https://npm.runkit.com/sinon
- Run this code:
var sinon = require("sinon")
let fakeClock;
console.log("Original time: " + new Date().getTime());
fakeClock = sinon.useFakeTimers(Date.parse("2014-06-05T12:07:07.662Z"));
console.log("First fake: " + new Date().getTime());
fakeClock = sinon.useFakeTimers(Date.parse("2018-04-11T14:08:00Z"));
console.log("Second fake: " + new Date().getTime());
fakeClock.restore();
console.log("Expect either 'first fake' or 'original time'");
console.log("First restore: " + new Date().getTime());
fakeClock.restore();
console.log("Expect 'original time'");
console.log("Second restore: " + new Date().getTime());
fakeClock.restore();
console.log("Expect 'original time'");
console.log("Third restore: " + new Date().getTime());
Expected behavior
I expect there to be some way to get the original timers back.
Context:
When writing Mocha tests, often there are multiple nested describe blocks. If each block doesn't handle the timers correctly, particularly child blocks, then this can easily happen with no way to recover or reset. This gets particularly tricky if before* or after* blocks are used to fake timers and then an individual it block also messes with timers.
Additional context
Granted, all these cases above could be consider a bug or poor usage, but there really should be some way to get things back to normal. The problem was realized when trying to debug intermittent failures in tests (we randomize the order of our tests to catch stuff like this). It took quite a while to hunt this problem down. Then, the fix was rather painfully going through every place were a timer was used and making sure that, if a decedent test was using a timer, it was declared locally and cleaned up in a finally block. So, now our code has lots of try...finally in it where there was none before. Otherwise, an abnormal function termination would cause the fake timers to leak and break other tests.
Describe the bug
When
sinon.useFakeTimersis used in a nested fashion, or code crashes or early exist before a timer isrestored, it becomes impossible to reset the timers to their default configuration.To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expect there to be some way to get the original timers back.
Context:
When writing Mocha tests, often there are multiple nested
describeblocks. If each block doesn't handle the timers correctly, particularly child blocks, then this can easily happen with no way to recover or reset. This gets particularly tricky ifbefore*orafter*blocks are used to fake timers and then an individualitblock also messes with timers.Additional context
Granted, all these cases above could be consider a bug or poor usage, but there really should be some way to get things back to normal. The problem was realized when trying to debug intermittent failures in tests (we randomize the order of our tests to catch stuff like this). It took quite a while to hunt this problem down. Then, the fix was rather painfully going through every place were a timer was used and making sure that, if a decedent test was using a timer, it was declared locally and cleaned up in a
finallyblock. So, now our code has lots oftry...finallyin it where there was none before. Otherwise, an abnormal function termination would cause the fake timers to leak and break other tests.