diff --git a/integration_tests/__tests__/timer_after_resetAllMocks-test.js b/integration_tests/__tests__/timer_after_resetAllMocks-test.js new file mode 100644 index 000000000000..907355de2f3f --- /dev/null +++ b/integration_tests/__tests__/timer_after_resetAllMocks-test.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @emails oncall+jsinfra + */ +'use strict'; + +const runJest = require('../runJest'); +const skipOnWindows = require('skipOnWindows'); + +skipOnWindows.suite(); + +test('run timers after resetAllMocks test', () => { + const result = runJest('timer_after_resetAllMocks'); + expect(result.status).toBe(0); +}); diff --git a/integration_tests/timer_after_resetAllMocks/index.js b/integration_tests/timer_after_resetAllMocks/index.js new file mode 100644 index 000000000000..065ab53aaf25 --- /dev/null +++ b/integration_tests/timer_after_resetAllMocks/index.js @@ -0,0 +1,11 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +module.exports = () => {}; diff --git a/integration_tests/timer_after_resetAllMocks/package.json b/integration_tests/timer_after_resetAllMocks/package.json new file mode 100644 index 000000000000..24b23cafe0e3 --- /dev/null +++ b/integration_tests/timer_after_resetAllMocks/package.json @@ -0,0 +1,6 @@ +{ + "jest": { + "testEnvironment": "node", + "resetMocks": false + } +} diff --git a/integration_tests/timer_after_resetAllMocks/timer_and_mock.test.js b/integration_tests/timer_after_resetAllMocks/timer_and_mock.test.js new file mode 100644 index 000000000000..969cd00ede8d --- /dev/null +++ b/integration_tests/timer_after_resetAllMocks/timer_and_mock.test.js @@ -0,0 +1,18 @@ +describe('timers', () => { + it('should work before calling resetAllMocks', () => { + jest.useFakeTimers(); + const f = jest.fn(); + setImmediate(() => f()); + jest.runAllImmediates(); + expect(f.mock.calls.length).toBe(1); + }); + + it('should not break after calling resetAllMocks', () => { + jest.resetAllMocks(); + jest.useFakeTimers(); + const f = jest.fn(); + setImmediate(() => f()); + jest.runAllImmediates(); + expect(f.mock.calls.length).toBe(1); + }); +}); diff --git a/packages/jest-util/src/FakeTimers.js b/packages/jest-util/src/FakeTimers.js index ffb0e4f425c4..ce5bbaf83fa3 100644 --- a/packages/jest-util/src/FakeTimers.js +++ b/packages/jest-util/src/FakeTimers.js @@ -53,6 +53,7 @@ class FakeTimers { _global: Global; _immediates: Array; _maxLoops: number; + _moduleMocker: ModuleMocker; _now: number; _ticks: Array; _timerAPIs: TimerAPI; @@ -70,8 +71,7 @@ class FakeTimers { this._config = config; this._maxLoops = maxLoops || 100000; this._uuidCounter = 1; - - this.reset(); + this._moduleMocker = moduleMocker; // Store original timer APIs for future reference this._timerAPIs = { @@ -83,25 +83,16 @@ class FakeTimers { setTimeout: global.setTimeout, }; - const fn = impl => moduleMocker.getMockFn().mockImpl(impl); - - this._fakeTimerAPIs = { - clearImmediate: fn(this._fakeClearImmediate.bind(this)), - clearInterval: fn(this._fakeClearTimer.bind(this)), - clearTimeout: fn(this._fakeClearTimer.bind(this)), - setImmediate: fn(this._fakeSetImmediate.bind(this)), - setInterval: fn(this._fakeSetInterval.bind(this)), - setTimeout: fn(this._fakeSetTimeout.bind(this)), - }; - // If there's a process.nextTick on the global, mock it out // (only applicable to node/node-emulating environments) if (typeof global.process === 'object' && typeof global.process.nextTick === 'function') { this._timerAPIs.nextTick = global.process.nextTick; - this._fakeTimerAPIs.nextTick = fn(this._fakeNextTick.bind(this)); } + this.reset(); + this._createMocks(); + // These globally-accessible function are now deprecated! // They will go away very soon, so do not use them! // Instead, use the versions available on the `jest` object @@ -330,6 +321,8 @@ class FakeTimers { typeof this._global.process === 'object' && typeof this._global.process.nextTick === 'function'; + this._createMocks(); + this._global.clearImmediate = this._fakeTimerAPIs.clearImmediate; this._global.clearInterval = this._fakeTimerAPIs.clearInterval; this._global.clearTimeout = this._fakeTimerAPIs.clearTimeout; @@ -355,6 +348,25 @@ class FakeTimers { } } + _createMocks() { + const fn = impl => this._moduleMocker.getMockFn().mockImpl(impl); + + this._fakeTimerAPIs = { + clearImmediate: fn(this._fakeClearImmediate.bind(this)), + clearInterval: fn(this._fakeClearTimer.bind(this)), + clearTimeout: fn(this._fakeClearTimer.bind(this)), + setImmediate: fn(this._fakeSetImmediate.bind(this)), + setInterval: fn(this._fakeSetInterval.bind(this)), + setTimeout: fn(this._fakeSetTimeout.bind(this)), + }; + + // If there's a process.nextTick on the global, mock it out + // (only applicable to node/node-emulating environments) + if (this._timerAPIs.nextTick) { + this._fakeTimerAPIs.nextTick = fn(this._fakeNextTick.bind(this)); + } + } + _fakeClearTimer(uuid: TimerID) { if (this._timers.hasOwnProperty(uuid)) { delete this._timers[uuid];