Skip to content

Commit 9914dc4

Browse files
authored
fix: actually add dispose Symbols to Node globals (#14909)
1 parent dcc4bc3 commit 9914dc4

File tree

6 files changed

+45
-42
lines changed

6 files changed

+45
-42
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
- `[@jest/core, @jest/test-sequencer]` [**BREAKING**] Exposes `globalConfig` & `contexts` to `TestSequencer` ([#14535](https://github.com/jestjs/jest/pull/14535), & [#14543](https://github.com/jestjs/jest/pull/14543))
1616
- `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM to v22 ([#13825](https://github.com/jestjs/jest/pull/13825))
1717
- `[@jest/environment-jsdom-abstract]` Introduce new package which abstracts over the `jsdom` environment, allowing usage of custom versions of JSDOM ([#14717](https://github.com/jestjs/jest/pull/14717))
18-
- `[jest-environment-node]` Update jest environment with dispose symbols `Symbol` ([#14888](https://github.com/jestjs/jest/pull/14888))
18+
- `[jest-environment-node]` Update jest environment with dispose symbols `Symbol` ([#14888](https://github.com/jestjs/jest/pull/14888) & [#14909](https://github.com/jestjs/jest/pull/14909))
1919
- `[@jest/fake-timers]` [**BREAKING**] Upgrade `@sinonjs/fake-timers` to v11 ([#14544](https://github.com/jestjs/jest/pull/14544))
2020
- `[@jest/fake-timers]` Exposing new modern timers function `advanceTimersToFrame()` which advances all timers by the needed milliseconds to execute callbacks currently scheduled with `requestAnimationFrame` ([#14598](https://github.com/jestjs/jest/pull/14598))
2121
- `[jest-runtime]` Exposing new modern timers function `jest.advanceTimersToFrame()` from `@jest/fake-timers` ([#14598](https://github.com/jestjs/jest/pull/14598))

e2e/__tests__/__snapshots__/globals.test.ts.snap

+13
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ Time: <<REPLACED>>
124124
Ran all test suites."
125125
`;
126126
127+
exports[`on node ^18.18.0 || >=20.4.0 Symbol's \`dispose\` are available 1`] = `
128+
"PASS __tests__/symbolDispose.test.js
129+
✓ test"
130+
`;
131+
132+
exports[`on node ^18.18.0 || >=20.4.0 Symbol's \`dispose\` are available 2`] = `
133+
"Test Suites: 1 passed, 1 total
134+
Tests: 1 passed, 1 total
135+
Snapshots: 0 total
136+
Time: <<REPLACED>>
137+
Ran all test suites."
138+
`;
139+
127140
exports[`only 1`] = `
128141
"PASS __tests__/onlyConstructs.test.js
129142
✓ test.only

e2e/__tests__/globals.test.ts

+21
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import {tmpdir} from 'os';
99
import * as path from 'path';
10+
import {onNodeVersions} from '@jest/test-utils';
1011
import {
1112
cleanup,
1213
createEmptyPackage,
@@ -295,3 +296,23 @@ test('function as it() descriptor', () => {
295296
expect(summary).toMatchSnapshot();
296297
expect(exitCode).toBe(0);
297298
});
299+
300+
onNodeVersions('^18.18.0 || >=20.4.0', () => {
301+
test("Symbol's `dispose` are available", () => {
302+
const filename = 'symbolDispose.test.js';
303+
const content = `
304+
it('test', () => {
305+
expect(Symbol.dispose).toBeDefined();
306+
expect(Symbol.asyncDispose).toBeDefined();
307+
});
308+
`;
309+
310+
writeFiles(TEST_DIR, {[filename]: content});
311+
const {stderr, exitCode} = runJest(DIR);
312+
313+
const {summary, rest} = extractSummary(stderr);
314+
expect(rest).toMatchSnapshot();
315+
expect(summary).toMatchSnapshot();
316+
expect(exitCode).toBe(0);
317+
});
318+
});

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

-22
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,6 @@ describe('NodeEnvironment', () => {
7272
}
7373
});
7474

75-
it('should configure dispose symbols', () => {
76-
const env = new NodeEnvironment(
77-
{
78-
globalConfig: makeGlobalConfig(),
79-
projectConfig: makeProjectConfig(),
80-
},
81-
context,
82-
);
83-
84-
if ('asyncDispose' in Symbol) {
85-
expect(env.global.Symbol).toHaveProperty('asyncDispose');
86-
} else {
87-
expect(env.global.Symbol).not.toHaveProperty('asyncDispose');
88-
}
89-
90-
if ('dispose' in Symbol) {
91-
expect(env.global.Symbol).toHaveProperty('dispose');
92-
} else {
93-
expect(env.global.Symbol).not.toHaveProperty('dispose');
94-
}
95-
});
96-
9775
it('has modern fake timers implementation', () => {
9876
const env = new NodeEnvironment(
9977
{

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

+8-18
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,6 @@ function isString(value: unknown): value is string {
6060
return typeof value === 'string';
6161
}
6262

63-
function setDisposeSymbols(context: Context): void {
64-
if ('asyncDispose' in Symbol) {
65-
runInContext(
66-
'if (!"asyncDispose" in Symbol) { Symbol.asyncDispose = Symbol.for("nodejs.asyncDispose") }',
67-
context,
68-
);
69-
}
70-
71-
if ('dispose' in Symbol) {
72-
runInContext(
73-
'if (!"dispose" in Symbol) { Symbol.dispose = Symbol.for("nodejs.dispose") }',
74-
context,
75-
);
76-
}
77-
}
78-
7963
const timerIdToRef = (id: number) => ({
8064
id,
8165
ref() {
@@ -102,8 +86,6 @@ export default class NodeEnvironment implements JestEnvironment<Timer> {
10286
const {projectConfig} = config;
10387
this.context = createContext();
10488

105-
setDisposeSymbols(this.context);
106-
10789
const global = runInContext(
10890
'this',
10991
Object.assign(this.context, projectConfig.testEnvironmentOptions),
@@ -170,6 +152,14 @@ export default class NodeEnvironment implements JestEnvironment<Timer> {
170152

171153
installCommonGlobals(global, projectConfig.globals);
172154

155+
if ('asyncDispose' in Symbol && !('asyncDispose' in global.Symbol)) {
156+
const globalSymbol = global.Symbol as unknown as SymbolConstructor;
157+
// @ts-expect-error - it's readonly - but we have checked above that it's not there
158+
globalSymbol.asyncDispose = globalSymbol('nodejs.asyncDispose');
159+
// @ts-expect-error - it's readonly - but we have checked above that it's not there
160+
globalSymbol.dispose = globalSymbol('nodejs.dispose');
161+
}
162+
173163
// Node's error-message stack size is limited at 10, but it's pretty useful
174164
// to see more than that when a test fails.
175165
global.Error.stackTraceLimit = 100;

packages/jest-environment-node/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "../../tsconfig.json",
33
"compilerOptions": {
44
"outDir": "build",
5-
"rootDir": "src"
5+
"rootDir": "src",
6+
"lib": ["es2021", "ESNext.Disposable"]
67
},
78
"include": ["./src/**/*"],
89
"exclude": ["./**/__tests__/**/*"],

0 commit comments

Comments
 (0)