From 84daa0f5dc443d689293b46ddd813fc6aa6777ab Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Wed, 30 Apr 2025 13:33:54 -0700 Subject: [PATCH] fix(Clock): Ensure that uninstalling the clock also stops auto tick The autotick feature mistakenly does not account for the clock being a singleton and the re-installation of the clock causes the auto ticking exit conditions to become true again, before it has a chance to break. --- spec/core/ClockSpec.js | 20 ++++++++++++++++++++ src/core/Clock.js | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/spec/core/ClockSpec.js b/spec/core/ClockSpec.js index dbdbbfd6..3eba9032 100644 --- a/spec/core/ClockSpec.js +++ b/spec/core/ClockSpec.js @@ -776,6 +776,26 @@ describe('Clock (acceptance)', function() { }); }); + it('aborts auto ticking when uninstalled, even if installed again synchonrously', async () => { + clock.uninstall(); + clock.install(); + + let resolved = false; + const promise = new Promise(resolve => { + clock.setTimeout(resolve, 1); + }).then(() => { + resolved = true; + }); + + // wait some real time and verify that the clock did not flush the timer above automatically + await new Promise(resolve => setTimeout(resolve, 2)); + expect(resolved).toBe(false); + + // enabling auto tick again will flush the timer + clock.autoTick(); + await expectAsync(promise).toBeResolved(); + }); + it('speeds up the execution of the timers in all browsers', async () => { const startTimeMs = performance.now() / 1000; await new Promise(resolve => clock.setTimeout(resolve, 5000)); diff --git a/src/core/Clock.js b/src/core/Clock.js index dc2378d6..f610c551 100644 --- a/src/core/Clock.js +++ b/src/core/Clock.js @@ -69,6 +69,10 @@ getJasmineRequireObj().Clock = function() { * @function */ this.uninstall = function() { + // Ensure auto ticking loop is aborted when clock is uninstalled + if (tickMode.mode === 'auto') { + tickMode = { mode: 'manual', counter: tickMode.counter + 1 }; + } delayedFunctionScheduler = null; mockDate.uninstall(); replace(global, realTimingFunctions);