Skip to content

Commit 0935f7c

Browse files
authored
feat: add fakeTimersLolex to the test environments (#8925)
* feat: add fakeTimersLolex to the test environments * link to PR
1 parent 04efbeb commit 0935f7c

File tree

10 files changed

+78
-45
lines changed

10 files changed

+78
-45
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
- `[jest-diff]` [**BREAKING**] Export as ECMAScript module ([#8873](https://github.com/facebook/jest/pull/8873))
1313
- `[jest-diff]` Add `includeChangeCounts` and rename `Indicator` options ([#8881](https://github.com/facebook/jest/pull/8881))
1414
- `[jest-diff]` Add `changeColor` and `patchColor` options ([#8911](https://github.com/facebook/jest/pull/8911))
15+
- `[jest-environment-jsdom]` Add `fakeTimersLolex` ([#8925](https://github.com/facebook/jest/pull/8925))
16+
- `[jest-environment-node]` Add `fakeTimersLolex` ([#8925](https://github.com/facebook/jest/pull/8925))
1517
- `[@jest/fake-timers]` Add Lolex as implementation of fake timers ([#8897](https://github.com/facebook/jest/pull/8897))
1618
- `[jest-get-type]` Add `BigInt` support. ([#8382](https://github.com/facebook/jest/pull/8382))
1719
- `[jest-matcher-utils]` Add `BigInt` support to `ensureNumbers` `ensureActualIsNumber`, `ensureExpectedIsNumber` ([#8382](https://github.com/facebook/jest/pull/8382))

TestUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ const DEFAULT_PROJECT_CONFIG: Config.ProjectConfig = {
115115
testPathIgnorePatterns: [],
116116
testRegex: ['\\.test\\.js$'],
117117
testRunner: 'jest-jasmine2',
118-
testURL: '',
118+
testURL: 'http://localhost',
119119
timers: 'real',
120120
transform: [],
121121
transformIgnorePatterns: [],

packages/jest-core/src/lib/__tests__/__snapshots__/log_debug_messages.test.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ exports[`prints the config object 1`] = `
5656
"\\\\.test\\\\.js$"
5757
],
5858
"testRunner": "myRunner",
59-
"testURL": "",
59+
"testURL": "http://localhost",
6060
"timers": "real",
6161
"transform": [],
6262
"transformIgnorePatterns": [],

packages/jest-environment-jsdom/src/__tests__/jsdom_environment.test.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,27 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*/
7-
'use strict';
87

9-
const JSDomEnvironment = jest.requireActual('../');
8+
import JSDomEnvironment = require('../');
9+
import {makeProjectConfig} from '../../../../TestUtils';
1010

1111
describe('JSDomEnvironment', () => {
1212
it('should configure setTimeout/setInterval to use the browser api', () => {
13-
const env1 = new JSDomEnvironment({});
13+
const env = new JSDomEnvironment(makeProjectConfig());
1414

15-
env1.fakeTimers.useFakeTimers();
15+
env.fakeTimers!.useFakeTimers();
1616

17-
const timer1 = env1.global.setTimeout(() => {}, 0);
18-
const timer2 = env1.global.setInterval(() => {}, 0);
17+
const timer1 = env.global.setTimeout(() => {}, 0);
18+
const timer2 = env.global.setInterval(() => {}, 0);
1919

2020
[timer1, timer2].forEach(timer => {
2121
expect(typeof timer).toBe('number');
2222
});
2323
});
24+
25+
it('has Lolex fake timers implementation', () => {
26+
const env = new JSDomEnvironment(makeProjectConfig());
27+
28+
expect(env.fakeTimersLolex).toBeDefined();
29+
});
2430
});

packages/jest-environment-jsdom/src/index.ts

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import {Script} from 'vm';
99
import {Config, Global} from '@jest/types';
1010
import {installCommonGlobals} from 'jest-util';
11-
import mock = require('jest-mock');
12-
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
11+
import {ModuleMocker} from 'jest-mock';
12+
import {
13+
JestFakeTimers as LegacyFakeTimers,
14+
LolexFakeTimers,
15+
} from '@jest/fake-timers';
1316
import {EnvironmentContext, JestEnvironment} from '@jest/environment';
1417
import {JSDOM, VirtualConsole} from 'jsdom';
1518

@@ -24,10 +27,11 @@ type Win = Window &
2427

2528
class JSDOMEnvironment implements JestEnvironment {
2629
dom: JSDOM | null;
27-
fakeTimers: FakeTimers<number> | null;
30+
fakeTimers: LegacyFakeTimers<number> | null;
31+
fakeTimersLolex: LolexFakeTimers | null;
2832
global: Win;
2933
errorEventListener: ((event: Event & {error: Error}) => void) | null;
30-
moduleMocker: mock.ModuleMocker | null;
34+
moduleMocker: ModuleMocker | null;
3135

3236
constructor(config: Config.ProjectConfig, options: EnvironmentContext = {}) {
3337
this.dom = new JSDOM('<!DOCTYPE html>', {
@@ -78,29 +82,32 @@ class JSDOMEnvironment implements JestEnvironment {
7882
return originalRemoveListener.apply(this, args);
7983
};
8084

81-
this.moduleMocker = new mock.ModuleMocker(global as any);
85+
this.moduleMocker = new ModuleMocker(global as any);
8286

8387
const timerConfig = {
8488
idToRef: (id: number) => id,
8589
refToId: (ref: number) => ref,
8690
};
8791

88-
this.fakeTimers = new FakeTimers({
92+
this.fakeTimers = new LegacyFakeTimers({
8993
config,
90-
global: global as any,
94+
global,
9195
moduleMocker: this.moduleMocker,
9296
timerConfig,
9397
});
94-
}
9598

96-
setup() {
97-
return Promise.resolve();
99+
this.fakeTimersLolex = new LolexFakeTimers({config, global});
98100
}
99101

100-
teardown() {
102+
async setup() {}
103+
104+
async teardown() {
101105
if (this.fakeTimers) {
102106
this.fakeTimers.dispose();
103107
}
108+
if (this.fakeTimersLolex) {
109+
this.fakeTimersLolex.dispose();
110+
}
104111
if (this.global) {
105112
if (this.errorEventListener) {
106113
this.global.removeEventListener('error', this.errorEventListener);
@@ -114,7 +121,7 @@ class JSDOMEnvironment implements JestEnvironment {
114121
this.global = null;
115122
this.dom = null;
116123
this.fakeTimers = null;
117-
return Promise.resolve();
124+
this.fakeTimersLolex = null;
118125
}
119126

120127
runScript(script: Script) {

packages/jest-environment-node/src/__tests__/node_environment.test.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,49 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*/
7-
'use strict';
87

9-
const NodeEnvironment = jest.requireActual('../');
8+
import NodeEnvironment = require('../');
9+
import {makeProjectConfig} from '../../../../TestUtils';
1010

1111
describe('NodeEnvironment', () => {
1212
it('uses a copy of the process object', () => {
13-
const env1 = new NodeEnvironment({});
14-
const env2 = new NodeEnvironment({});
13+
const env1 = new NodeEnvironment(makeProjectConfig());
14+
const env2 = new NodeEnvironment(makeProjectConfig());
1515

1616
expect(env1.global.process).not.toBe(env2.global.process);
1717
});
1818

1919
it('exposes process.on', () => {
20-
const env1 = new NodeEnvironment({});
20+
const env1 = new NodeEnvironment(makeProjectConfig());
2121

2222
expect(env1.global.process.on).not.toBe(null);
2323
});
2424

2525
it('exposes global.global', () => {
26-
const env1 = new NodeEnvironment({});
26+
const env1 = new NodeEnvironment(makeProjectConfig());
2727

2828
expect(env1.global.global).toBe(env1.global);
2929
});
3030

3131
it('should configure setTimeout/setInterval to use the node api', () => {
32-
const env1 = new NodeEnvironment({});
32+
const env1 = new NodeEnvironment(makeProjectConfig());
3333

34-
env1.fakeTimers.useFakeTimers();
34+
env1.fakeTimers!.useFakeTimers();
3535

3636
const timer1 = env1.global.setTimeout(() => {}, 0);
3737
const timer2 = env1.global.setInterval(() => {}, 0);
3838

3939
[timer1, timer2].forEach(timer => {
40+
// @ts-ignore
4041
expect(timer.id).not.toBeUndefined();
4142
expect(typeof timer.ref).toBe('function');
4243
expect(typeof timer.unref).toBe('function');
4344
});
4445
});
46+
47+
it('has Lolex fake timers implementation', () => {
48+
const env = new NodeEnvironment(makeProjectConfig());
49+
50+
expect(env.fakeTimersLolex).toBeDefined();
51+
});
4552
});

packages/jest-environment-node/src/index.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {Context, Script, createContext, runInContext} from 'vm';
99
import {Config, Global} from '@jest/types';
1010
import {ModuleMocker} from 'jest-mock';
1111
import {installCommonGlobals} from 'jest-util';
12-
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
12+
import {
13+
JestFakeTimers as LegacyFakeTimers,
14+
LolexFakeTimers,
15+
} from '@jest/fake-timers';
1316
import {JestEnvironment} from '@jest/environment';
1417

1518
type Timer = {
@@ -20,7 +23,8 @@ type Timer = {
2023

2124
class NodeEnvironment implements JestEnvironment {
2225
context: Context | null;
23-
fakeTimers: FakeTimers<Timer> | null;
26+
fakeTimers: LegacyFakeTimers<Timer> | null;
27+
fakeTimersLolex: LolexFakeTimers | null;
2428
global: Global.Global;
2529
moduleMocker: ModuleMocker | null;
2630

@@ -70,25 +74,28 @@ class NodeEnvironment implements JestEnvironment {
7074
refToId: timerRefToId,
7175
};
7276

73-
this.fakeTimers = new FakeTimers({
77+
this.fakeTimers = new LegacyFakeTimers({
7478
config,
7579
global,
7680
moduleMocker: this.moduleMocker,
7781
timerConfig,
7882
});
79-
}
8083

81-
setup() {
82-
return Promise.resolve();
84+
this.fakeTimersLolex = new LolexFakeTimers({config, global});
8385
}
8486

85-
teardown() {
87+
async setup() {}
88+
89+
async teardown() {
8690
if (this.fakeTimers) {
8791
this.fakeTimers.dispose();
8892
}
93+
if (this.fakeTimersLolex) {
94+
this.fakeTimersLolex.dispose();
95+
}
8996
this.context = null;
9097
this.fakeTimers = null;
91-
return Promise.resolve();
98+
this.fakeTimersLolex = null;
9299
}
93100

94101
// TS infers the return type to be `any`, since that's what `runInContext`

packages/jest-environment/src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import {Script} from 'vm';
99
import {Circus, Config, Global} from '@jest/types';
1010
import jestMock = require('jest-mock');
1111
import {ScriptTransformer} from '@jest/transform';
12-
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
12+
import {
13+
JestFakeTimers as LegacyFakeTimers,
14+
LolexFakeTimers,
15+
} from '@jest/fake-timers';
1316

1417
type JestMockFn = typeof jestMock.fn;
1518
type JestMockSpyOn = typeof jestMock.spyOn;
@@ -37,7 +40,8 @@ export type ModuleWrapper = (
3740
export declare class JestEnvironment {
3841
constructor(config: Config.ProjectConfig, context?: EnvironmentContext);
3942
global: Global.Global;
40-
fakeTimers: FakeTimers<unknown> | null;
43+
fakeTimers: LegacyFakeTimers<unknown> | null;
44+
fakeTimersLolex: LolexFakeTimers | null;
4145
moduleMocker: jestMock.ModuleMocker | null;
4246
runScript(
4347
script: Script,

packages/jest-fake-timers/src/FakeTimersLolex.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ export default class FakeTimers {
9494
}
9595

9696
useFakeTimers() {
97-
const toFake = Object.keys(this._lolex.timers) as Array<
98-
keyof LolexWithContext['timers']
99-
>;
100-
10197
if (!this._fakingTime) {
98+
const toFake = Object.keys(this._lolex.timers) as Array<
99+
keyof LolexWithContext['timers']
100+
>;
101+
102102
this._clock = this._lolex.install({
103103
loopLimit: this._maxLoops,
104104
now: Date.now(),

packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Object {
5555
"\\\\.test\\\\.js$",
5656
],
5757
"testRunner": "jest-jasmine2",
58-
"testURL": "",
58+
"testURL": "http://localhost",
5959
"timers": "real",
6060
"transform": Array [
6161
Array [
@@ -218,7 +218,7 @@ exports[`ScriptTransformer uses multiple preprocessors 1`] = `
218218
const TRANSFORMED = {
219219
filename: '/fruits/banana.js',
220220
script: 'module.exports = \\"banana\\";',
221-
config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"],[\\"^.+\\\\\\\\.css$\\",\\"css-preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}',
221+
config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"],[\\"^.+\\\\\\\\.css$\\",\\"css-preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}',
222222
};
223223
224224
}});"
@@ -244,7 +244,7 @@ exports[`ScriptTransformer uses the supplied preprocessor 1`] = `
244244
const TRANSFORMED = {
245245
filename: '/fruits/banana.js',
246246
script: 'module.exports = \\"banana\\";',
247-
config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}',
247+
config: '{\\"automock\\":false,\\"browser\\":false,\\"cache\\":true,\\"cacheDirectory\\":\\"/cache/\\",\\"clearMocks\\":false,\\"coveragePathIgnorePatterns\\":[],\\"cwd\\":\\"/test_root_dir/\\",\\"detectLeaks\\":false,\\"detectOpenHandles\\":false,\\"errorOnDeprecated\\":false,\\"extraGlobals\\":[],\\"filter\\":null,\\"forceCoverageMatch\\":[],\\"globalSetup\\":null,\\"globalTeardown\\":null,\\"globals\\":{},\\"haste\\":{\\"providesModuleNodeModules\\":[]},\\"moduleDirectories\\":[],\\"moduleFileExtensions\\":[\\"js\\"],\\"moduleLoader\\":\\"/test_module_loader_path\\",\\"moduleNameMapper\\":[],\\"modulePathIgnorePatterns\\":[],\\"modulePaths\\":[],\\"name\\":\\"test\\",\\"prettierPath\\":\\"prettier\\",\\"resetMocks\\":false,\\"resetModules\\":false,\\"resolver\\":null,\\"restoreMocks\\":false,\\"rootDir\\":\\"/\\",\\"roots\\":[],\\"runner\\":\\"jest-runner\\",\\"setupFiles\\":[],\\"setupFilesAfterEnv\\":[],\\"skipFilter\\":false,\\"skipNodeResolution\\":false,\\"snapshotResolver\\":null,\\"snapshotSerializers\\":[],\\"testEnvironment\\":\\"node\\",\\"testEnvironmentOptions\\":{},\\"testLocationInResults\\":false,\\"testMatch\\":[],\\"testPathIgnorePatterns\\":[],\\"testRegex\\":[\\"\\\\\\\\.test\\\\\\\\.js$\\"],\\"testRunner\\":\\"jest-jasmine2\\",\\"testURL\\":\\"http://localhost\\",\\"timers\\":\\"real\\",\\"transform\\":[[\\"^.+\\\\\\\\.js$\\",\\"test_preprocessor\\"]],\\"transformIgnorePatterns\\":[\\"/node_modules/\\"],\\"unmockedModulePathPatterns\\":null,\\"watchPathIgnorePatterns\\":[]}',
248248
};
249249
250250
}});"

0 commit comments

Comments
 (0)