GeezerVison is showing github.com — test_runner: make mock_loader not confuse CJS and ESM resolution · nodejs/node@56cbc80
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/test/mock_loader.js +15-4Lines changed: 15 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -23,6 +23,8 @@ let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => { | 23 | 23 | debug = fn; | 24 | 24 | }); | 25 | 25 | const { createRequire, isBuiltin } = require('module'); | | 26 | +const { defaultGetFormatWithoutErrors } = require('internal/modules/esm/get_format'); | | 27 | +const { defaultResolve } = require('internal/modules/esm/resolve'); | 26 | 28 |
| 27 | 29 | // TODO(cjihrig): This file should not be exposed publicly, but register() does | 28 | 30 | // not handle internal loaders. Before marking this API as stable, one of the | @@ -88,11 +90,20 @@ async function resolve(specifier, context, nextResolve) { | 88 | 90 | if (isBuiltin(specifier)) { | 89 | 91 | mockSpecifier = ensureNodeScheme(specifier); | 90 | 92 | } else { | 91 | | - // TODO(cjihrig): This try...catch should be replaced by defaultResolve(), | 92 | | - // but there are some edge cases that caused the tests to fail on Windows. | | 93 | + let format; | | 94 | + | | 95 | + if (context.parentURL) { | | 96 | + format = defaultGetFormatWithoutErrors(pathToFileURL(context.parentURL)); | | 97 | + } | | 98 | + | 93 | 99 | try { | 94 | | - const req = createRequire(context.parentURL); | 95 | | - specifier = pathToFileURL(req.resolve(specifier)).href; | | 100 | + if (format === 'module') { | | 101 | + specifier = defaultResolve(specifier, context).url; | | 102 | + } else { | | 103 | + specifier = pathToFileURL( | | 104 | + createRequire(context.parentURL).resolve(specifier), | | 105 | + ).href; | | 106 | + } | 96 | 107 | } catch { | 97 | 108 | const parentURL = normalizeReferrerURL(context.parentURL); | 98 | 109 | const parsedURL = URL.parse(specifier, parentURL)?.href; | |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +export let string = 'original esm string'; |
Collapse file Copy file name to clipboard +8Lines changed: 8 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +import { mock } from 'node:test'; | | 2 | + | | 3 | +try { | | 4 | + mock.module?.('Whatever, this is not significant', { namedExports: {} }); | | 5 | +} catch {} | | 6 | + | | 7 | +const { string } = await import('./basic-esm-without-extension'); | | 8 | +console.log(`Found string: ${string}`); // prints 'original esm string' |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-runner-module-mocking.js +15Lines changed: 15 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -638,3 +638,18 @@ test('defaultExports work with ESM mocks in both module systems', async (t) => { | 638 | 638 | assert.strictEqual((await import(fixture)).default, defaultExport); | 639 | 639 | assert.strictEqual(require(fixture), defaultExport); | 640 | 640 | }); | | 641 | + | | 642 | +test('wrong import syntax should throw error after module mocking.', async () => { | | 643 | + const { stdout, stderr, code } = await common.spawnPromisified( | | 644 | + process.execPath, | | 645 | + [ | | 646 | + '--experimental-test-module-mocks', | | 647 | + '--experimental-default-type=module', | | 648 | + fixtures.path('module-mocking/wrong-import-after-module-mocking.js'), | | 649 | + ] | | 650 | + ); | | 651 | + | | 652 | + assert.strictEqual(stdout, ''); | | 653 | + assert.match(stderr, /Error \[ERR_MODULE_NOT_FOUND\]: Cannot find module/); | | 654 | + assert.strictEqual(code, 1); | | 655 | +}); |
|