Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test_runner: mock_loader resolve the cjs and esm formats respectively. #53846

Merged
merged 10 commits into from
Aug 6, 2024
21 changes: 16 additions & 5 deletions lib/test/mock_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ const { normalizeReferrerURL } = require('internal/modules/helpers');
let debug = require('internal/util/debuglog').debuglog('test_runner', (fn) => {
debug = fn;
});
const { createRequire, isBuiltin } = require('module');
const { createRequire, isBuiltin, _resolveFilename } = require('module');
const { defaultGetFormatWithoutErrors } = require('internal/modules/esm/get_format');
const { defaultResolve } = require('internal/modules/esm/resolve');

// TODO(cjihrig): This file should not be exposed publicly, but register() does
// not handle internal loaders. Before marking this API as stable, one of the
Expand Down Expand Up @@ -95,11 +97,20 @@ async function resolve(specifier, context, nextResolve) {
if (isBuiltin(specifier)) {
mockSpecifier = ensureNodeScheme(specifier);
} else {
// TODO(cjihrig): This try...catch should be replaced by defaultResolve(),
// but there are some edge cases that caused the tests to fail on Windows.
let format;

if(context.parentURL) {
format = defaultGetFormatWithoutErrors(pathToFileURL(context.parentURL));
}

try {
const req = createRequire(context.parentURL);
specifier = pathToFileURL(req.resolve(specifier)).href;
if (format === 'module') {
specifier = defaultResolve(specifier, context).url;
aduh95 marked this conversation as resolved.
Show resolved Hide resolved
} else {
specifier = pathToFileURL(
createRequire(context.parentURL).resolve(specifier)
).href;
}
} catch {
const parentURL = normalizeReferrerURL(context.parentURL);
const parsedURL = URL.parse(specifier, parentURL)?.href;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export let string = 'original esm string';
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { mock } from 'node:test';

try {
if (mock.module) mock.module('Whatever, this is not significant', { namedExports: {} });
syi0808 marked this conversation as resolved.
Show resolved Hide resolved
} catch {}

const { string } = await import('./basic-esm-without-extension');
console.log(`Found string: ${string}`); // prints 'original esm string'
15 changes: 15 additions & 0 deletions test/parallel/test-runner-mocking.js
syi0808 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const common = require('../common');
const assert = require('node:assert');
const { mock, test } = require('node:test');
const fixtures = require('../common/fixtures');
test('spies on a function', (t) => {
const sum = t.mock.fn((arg1, arg2) => {
return arg1 + arg2;
Expand Down Expand Up @@ -1054,3 +1055,17 @@ test('setter() fails if getter options is true', (t) => {
t.mock.setter({}, 'method', { getter: true });
}, /The property 'options\.setter' cannot be used with 'options\.getter'/);
});

test('wrong import syntax should throw error after module mocking.', async () => {
const { stdout, stderr } = await common.spawnPromisified(
syi0808 marked this conversation as resolved.
Show resolved Hide resolved
process.execPath,
[
'--experimental-test-module-mocks',
'--experimental-default-type=module',
fixtures.path('module-mocking/wrong-import-after-module-mocking.js'),
]
);

assert.equal(stdout.toString(), '')
assert.match(stderr.toString(), /Error \[ERR_MODULE_NOT_FOUND\]: Cannot find module/)
syi0808 marked this conversation as resolved.
Show resolved Hide resolved
});