From bdb86aa193641e563bbdbecc478bb4b97823bf4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Menzel?= <8976542+alesmenzel@users.noreply.github.com> Date: Tue, 16 Jan 2024 23:54:58 +0100 Subject: [PATCH] feat: support import.meta.dirname and import.meta.filename (#14854) --- CHANGELOG.md | 1 + e2e/native-esm/__tests__/native-esm.test.js | 21 +++++++++++++++++++ packages/jest-runtime/src/index.ts | 23 +++++++++++++++++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaf7017edd15..d0e400ec492f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - `[@jest/fake-timers]` [**BREAKING**] Upgrade `@sinonjs/fake-timers` to v11 ([#14544](https://github.com/jestjs/jest/pull/14544)) - `[@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)) - `[jest-runtime]` Exposing new modern timers function `jest.advanceTimersToFrame()` from `@jest/fake-timers` ([#14598](https://github.com/jestjs/jest/pull/14598)) +- `[jest-runtime]` Support `import.meta.filename` and `import.meta.dirname` (available from [Node 20.11](https://nodejs.org/en/blog/release/v20.11.0)) - `[@jest/schemas]` Upgrade `@sinclair/typebox` to v0.31 ([#14072](https://github.com/jestjs/jest/pull/14072)) - `[@jest/types]` `test.each()`: Accept a readonly (`as const`) table properly ([#14565](https://github.com/jestjs/jest/pull/14565)) - `[jest-snapshot]` [**BREAKING**] Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in snapshots ([#13965](https://github.com/facebook/jest/pull/13965)) diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js index 3d626995d374..7e0574a33963 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -28,6 +28,8 @@ test('should have correct import.meta', () => { expect(typeof require).toBe('undefined'); expect(typeof jest).toBe('undefined'); expect(import.meta).toEqual({ + dirname: expect.any(String), + filename: expect.any(String), jest: expect.anything(), url: expect.any(String), }); @@ -35,6 +37,25 @@ test('should have correct import.meta', () => { expect( import.meta.url.endsWith('/e2e/native-esm/__tests__/native-esm.test.js'), ).toBe(true); + if (process.platform === 'win32') { + expect( + import.meta.filename.endsWith( + '\\e2e\\native-esm\\__tests__\\native-esm.test.js', + ), + ).toBe(true); + expect(import.meta.dirname.endsWith('\\e2e\\native-esm\\__tests__')).toBe( + true, + ); + } else { + expect( + import.meta.filename.endsWith( + '/e2e/native-esm/__tests__/native-esm.test.js', + ), + ).toBe(true); + expect(import.meta.dirname.endsWith('/e2e/native-esm/__tests__')).toBe( + true, + ); + } }); test('should double stuff', () => { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index db72eafb1e63..72d247e81588 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -520,6 +520,11 @@ export default class Runtime { initializeImportMeta: (meta: JestImportMeta) => { meta.url = pathToFileURL(modulePath).href; + // @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0 + meta.filename = fileURLToPath(meta.url); + // @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0 + meta.dirname = path.dirname(meta.filename); + let jest = this.jestObjectCaches.get(modulePath); if (!jest) { @@ -672,6 +677,13 @@ export default class Runtime { initializeImportMeta(meta: ImportMeta) { // no `jest` here as it's not loaded in a file meta.url = specifier; + + if (meta.url.startsWith('file://')) { + // @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0 + meta.filename = fileURLToPath(meta.url); + // @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0 + meta.dirname = path.dirname(meta.filename); + } }, }); } @@ -685,19 +697,22 @@ export default class Runtime { specifier = fileURLToPath(specifier); } - const [path, query] = specifier.split('?'); + const [specifierPath, query] = specifier.split('?'); if ( await this._shouldMockModule( referencingIdentifier, - path, + specifierPath, this._explicitShouldMockModule, ) ) { - return this.importMock(referencingIdentifier, path, context); + return this.importMock(referencingIdentifier, specifierPath, context); } - const resolved = await this._resolveModule(referencingIdentifier, path); + const resolved = await this._resolveModule( + referencingIdentifier, + specifierPath, + ); if ( // json files are modules when imported in modules