Skip to content

Commit

Permalink
spy on timer functions
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed May 13, 2018
1 parent 124defb commit 7b0d0e2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
6 changes: 5 additions & 1 deletion packages/jest-environment-jsdom/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ class JSDOMEnvironment {

this.moduleMocker = new mock.ModuleMocker(global);

this.fakeTimers = new FakeTimers({config, global});
this.fakeTimers = new FakeTimers({
config,
global,
moduleMocker: this.moduleMocker,
});
}

setup(): Promise<void> {
Expand Down
6 changes: 5 additions & 1 deletion packages/jest-environment-node/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ class NodeEnvironment {
installCommonGlobals(global, config.globals);
this.moduleMocker = new mock.ModuleMocker(global);

this.fakeTimers = new FakeTimers({config, global});
this.fakeTimers = new FakeTimers({
config,
global,
moduleMocker: this.moduleMocker,
});
}

setup(): Promise<void> {
Expand Down
43 changes: 39 additions & 4 deletions packages/jest-util/src/fake_timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,50 @@

import type {ProjectConfig} from 'types/Config';
import type {Global} from 'types/Global';
import type {ModuleMocker} from 'types/Mock';

import {withGlobal as lolexWithGlobal} from 'lolex';
import {formatStackTrace} from 'jest-message-util';

const functionsToSpyOn: Array<string> = [
'clearImmediate',
'clearInterval',
'clearTimeout',
'nextTick',
'setImmediate',
'setInterval',
'setTimeout',
];

export default class FakeTimers {
_clock: LolexClock;
_config: ProjectConfig;
_fakingTime: boolean;
_global: Global;
_maxLoops: number;
_lolex: LolexExports;
_maxLoops: number;
_moduleMocker: ModuleMocker;
_timerMocks: Array<JestMockFn>;

constructor({
global,
moduleMocker,
config,
maxLoops,
}: {
global: Global,
moduleMocker: ModuleMocker,
config: ProjectConfig,
maxLoops?: number,
}) {
this._global = global;
this._config = config;
this._maxLoops = maxLoops || 100000;
this._moduleMocker = moduleMocker;

this._fakingTime = false;
this._lolex = lolexWithGlobal(global);
this._timerMocks = [];
}

clearAllTimers() {
Expand Down Expand Up @@ -81,20 +98,38 @@ export default class FakeTimers {

useRealTimers() {
if (this._fakingTime) {
this._timerMocks.forEach(func => {
func.mockRestore();
});
this._clock.uninstall();
this._fakingTime = false;
this._timerMocks = [];
}
}

useFakeTimers() {
if (!this._fakingTime) {
// This creates stubs based on the host environment, we want it to be based
// on `this._global`. See https://github.com/sinonjs/lolex/issues/146
const toFake = Object.keys(this._lolex.timers);
this._clock = this._lolex.install({
loopLimit: this._maxLoops,
target: this._global,
toFake: Object.keys(this._lolex.timers),
toFake,
});

this._timerMocks = toFake
.filter(func => functionsToSpyOn.includes(func))
.map(func => {
if (func === 'hrtime' || func === 'nextTick') {
return this._moduleMocker.spyOn(this._global.process, func);
}

if (func === 'performance') {
return this._moduleMocker.spyOn(this._global.performance, 'now');
}

return this._moduleMocker.spyOn(this._global, func);
});

this._fakingTime = true;
}
}
Expand Down

0 comments on commit 7b0d0e2

Please sign in to comment.