From fcaf63323ecc6fb0d16a1e8f3d7fe301cf4a2581 Mon Sep 17 00:00:00 2001 From: eran shabi Date: Tue, 30 Jul 2019 17:44:52 +0300 Subject: [PATCH 1/8] getTimerCount will not include cancelled immediates --- .../src/__tests__/jestFakeTimers.test.ts | 17 +++++++++++++++++ packages/jest-fake-timers/src/jestFakeTimers.ts | 6 +++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/jest-fake-timers/src/__tests__/jestFakeTimers.test.ts b/packages/jest-fake-timers/src/__tests__/jestFakeTimers.test.ts index d011eee66d2d..56171b64251f 100644 --- a/packages/jest-fake-timers/src/__tests__/jestFakeTimers.test.ts +++ b/packages/jest-fake-timers/src/__tests__/jestFakeTimers.test.ts @@ -1303,5 +1303,22 @@ describe('FakeTimers', () => { expect(timers.getTimerCount()).toEqual(3); }); + + it('not includes cancelled immediates', () => { + const timers = new FakeTimers({ + config, + global, + moduleMocker, + timerConfig, + }); + + timers.useFakeTimers(); + + global.setImmediate(() => {}); + expect(timers.getTimerCount()).toEqual(1); + timers.clearAllTimers(); + + expect(timers.getTimerCount()).toEqual(0); + }); }); }); diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index aea098eadf3d..74de4f4bef4a 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -355,7 +355,11 @@ export default class FakeTimers { getTimerCount() { this._checkFakeTimers(); - return this._timers.size + this._immediates.length + this._ticks.length; + const immediatesCount = this._immediates.filter( + immediate => !this._cancelledImmediates[immediate.uuid], + ).length; + + return this._timers.size + immediatesCount + this._ticks.length; } private _checkFakeTimers() { From 2abfa18e180b217bcdfd6e4fa574cd42465eb88c Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 1 Aug 2019 17:29:28 +0300 Subject: [PATCH 2/8] delete _cancelledImmediates --- .../jest-fake-timers/src/jestFakeTimers.ts | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 74de4f4bef4a..54e0e4353024 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -53,7 +53,6 @@ const setGlobal = ( }; export default class FakeTimers { - private _cancelledImmediates!: Record; private _cancelledTicks!: Record; private _config: StackTraceConfig; private _disposed?: boolean; @@ -105,9 +104,7 @@ export default class FakeTimers { } clearAllTimers() { - this._immediates.forEach(immediate => - this._fakeClearImmediate(immediate.uuid), - ); + this._immediates = []; this._timers.clear(); } @@ -118,7 +115,6 @@ export default class FakeTimers { reset() { this._cancelledTicks = {}; - this._cancelledImmediates = {}; this._now = 0; this._ticks = []; this._immediates = []; @@ -177,11 +173,8 @@ export default class FakeTimers { } private _runImmediate(immediate: Tick) { - if (!this._cancelledImmediates.hasOwnProperty(immediate.uuid)) { - // Callback may throw, so update the map prior calling. - this._cancelledImmediates[immediate.uuid] = true; - immediate.callback(); - } + immediate.callback(); + this._fakeClearImmediate(immediate.uuid); } runAllTimers() { @@ -355,11 +348,7 @@ export default class FakeTimers { getTimerCount() { this._checkFakeTimers(); - const immediatesCount = this._immediates.filter( - immediate => !this._cancelledImmediates[immediate.uuid], - ).length; - - return this._timers.size + immediatesCount + this._ticks.length; + return this._timers.size + this._immediates.length + this._ticks.length; } private _checkFakeTimers() { @@ -406,7 +395,9 @@ export default class FakeTimers { } private _fakeClearImmediate(uuid: TimerID) { - this._cancelledImmediates[uuid] = true; + this._immediates = this._immediates.filter( + immediate => immediate.uuid !== uuid, + ); } private _fakeNextTick(callback: Callback, ...args: Array) { @@ -443,13 +434,11 @@ export default class FakeTimers { uuid: String(uuid), }); - const cancelledImmediates = this._cancelledImmediates; + const immediates = this._immediates; this._timerAPIs.setImmediate(() => { - if (!cancelledImmediates.hasOwnProperty(uuid)) { - // Callback may throw, so update the map prior calling. - cancelledImmediates[String(uuid)] = true; + this._fakeClearImmediate(String(uuid)); + immediates.find(x => x.uuid === String(uuid)) && callback.apply(null, args); - } }); return uuid; From f1dd8f9ffbaed42df094dfe2e251e8d679456589 Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 1 Aug 2019 17:48:58 +0300 Subject: [PATCH 3/8] review fixes --- packages/jest-fake-timers/src/jestFakeTimers.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 54e0e4353024..9b0f2c84b1e5 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -173,8 +173,8 @@ export default class FakeTimers { } private _runImmediate(immediate: Tick) { - immediate.callback(); this._fakeClearImmediate(immediate.uuid); + immediate.callback(); } runAllTimers() { @@ -427,18 +427,17 @@ export default class FakeTimers { return null; } - const uuid = this._uuidCounter++; + const uuid = String(this._uuidCounter++); this._immediates.push({ callback: () => callback.apply(null, args), - uuid: String(uuid), + uuid, }); const immediates = this._immediates; this._timerAPIs.setImmediate(() => { - this._fakeClearImmediate(String(uuid)); - immediates.find(x => x.uuid === String(uuid)) && - callback.apply(null, args); + this._fakeClearImmediate(uuid); + immediates.find(x => x.uuid === uuid) && callback.apply(null, args); }); return uuid; From 9880b246fad64c7ee4999634ad42302b8fddfde2 Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 15 Aug 2019 12:27:55 +0300 Subject: [PATCH 4/8] fix snapshot test fail on incorrect error --- packages/jest-fake-timers/src/jestFakeTimers.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 9b0f2c84b1e5..446801919e58 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -173,8 +173,8 @@ export default class FakeTimers { } private _runImmediate(immediate: Tick) { - this._fakeClearImmediate(immediate.uuid); immediate.callback(); + this._fakeClearImmediate(immediate.uuid); } runAllTimers() { @@ -436,8 +436,14 @@ export default class FakeTimers { const immediates = this._immediates; this._timerAPIs.setImmediate(() => { - this._fakeClearImmediate(uuid); - immediates.find(x => x.uuid === uuid) && callback.apply(null, args); + if (immediates.find(x => x.uuid === uuid)) { + try { + callback.apply(null, args); + } catch (error) { + } finally { + this._fakeClearImmediate(uuid); + } + } }); return uuid; From 7708d7e4a19f534433b2e4a76578e626e68da9be Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 15 Aug 2019 12:29:39 +0300 Subject: [PATCH 5/8] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee98f50fbc50..4dc9662d7f13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - `[jest-snapshots]` Fix test retries that contain snapshots ([#8629](https://github.com/facebook/jest/pull/8629)) - `[jest-mock]` Fix incorrect assignments when restoring mocks in instances where they originally didn't exist ([#8631](https://github.com/facebook/jest/pull/8631)) - `[expect]` Fix stack overflow when matching objects with circular references ([#8687](https://github.com/facebook/jest/pull/8687)) +- `[jest-fake-timers]` `getTimerCount` will not include cancelled immediates ([#8764](https://github.com/facebook/jest/pull/8764)) ### Chore & Maintenance From 307f86ec09c28babbd6101c2fb0fa6040bfc566e Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 15 Aug 2019 15:24:14 +0300 Subject: [PATCH 6/8] remove empty catch --- packages/jest-fake-timers/src/jestFakeTimers.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 446801919e58..48de3b7b4648 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -439,7 +439,6 @@ export default class FakeTimers { if (immediates.find(x => x.uuid === uuid)) { try { callback.apply(null, args); - } catch (error) { } finally { this._fakeClearImmediate(uuid); } From 60900a98e210a1d07217e668b46b36c248434026 Mon Sep 17 00:00:00 2001 From: eran shabi Date: Thu, 15 Aug 2019 19:26:57 +0300 Subject: [PATCH 7/8] wrap immediate callback call with try finally --- packages/jest-fake-timers/src/jestFakeTimers.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 48de3b7b4648..628664e57ea9 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -173,8 +173,11 @@ export default class FakeTimers { } private _runImmediate(immediate: Tick) { - immediate.callback(); - this._fakeClearImmediate(immediate.uuid); + try { + immediate.callback(); + } finally { + this._fakeClearImmediate(immediate.uuid); + } } runAllTimers() { From 88d9f6738a052cc9aec92cf8031ad2dc39667077 Mon Sep 17 00:00:00 2001 From: eran shabi Date: Sun, 18 Aug 2019 11:44:22 +0300 Subject: [PATCH 8/8] fix CI --- packages/jest-fake-timers/src/jestFakeTimers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/jest-fake-timers/src/jestFakeTimers.ts b/packages/jest-fake-timers/src/jestFakeTimers.ts index 628664e57ea9..11e20e7b7ebb 100644 --- a/packages/jest-fake-timers/src/jestFakeTimers.ts +++ b/packages/jest-fake-timers/src/jestFakeTimers.ts @@ -437,9 +437,8 @@ export default class FakeTimers { uuid, }); - const immediates = this._immediates; this._timerAPIs.setImmediate(() => { - if (immediates.find(x => x.uuid === uuid)) { + if (this._immediates.find(x => x.uuid === uuid)) { try { callback.apply(null, args); } finally {