Skip to content

Commit bb40521

Browse files
test_runner: support typescript module mocking
PR-URL: #54878 Fixes: #54428 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Erick Wendel <erick.workspace@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Paolo Insogna <paolo@cowtech.it>
1 parent be4babb commit bb40521

File tree

7 files changed

+55
-6
lines changed

7 files changed

+55
-6
lines changed

lib/internal/modules/esm/translators.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ translators.set('wasm', async function(url, source) {
459459
// Strategy for loading a commonjs TypeScript module
460460
translators.set('commonjs-typescript', function(url, source) {
461461
emitExperimentalWarning('Type Stripping');
462-
assertBufferSource(source, false, 'load');
462+
assertBufferSource(source, true, 'load');
463463
const code = stripTypeScriptTypes(stringify(source), url);
464464
debug(`Translating TypeScript ${url}`);
465465
return FunctionPrototypeCall(translators.get('commonjs'), this, url, code, false);
@@ -468,7 +468,7 @@ translators.set('commonjs-typescript', function(url, source) {
468468
// Strategy for loading an esm TypeScript module
469469
translators.set('module-typescript', function(url, source) {
470470
emitExperimentalWarning('Type Stripping');
471-
assertBufferSource(source, false, 'load');
471+
assertBufferSource(source, true, 'load');
472472
const code = stripTypeScriptTypes(stringify(source), url);
473473
debug(`Translating TypeScript ${url}`);
474474
return FunctionPrototypeCall(translators.get('module'), this, url, code, false);

lib/internal/test_runner/mock/loader.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ async function load(url, context, nextLoad) {
137137
async function createSourceFromMock(mock, format) {
138138
// Create mock implementation from provided exports.
139139
const { exportNames, hasDefaultExport, url } = mock;
140-
const useESM = format === 'module';
140+
const useESM = format === 'module' || format === 'module-typescript';
141141
const source = `${testImportSource(useESM)}
142142
if (!$__test.mock._mockExports.has('${url}')) {
143143
throw new Error(${JSONStringify(`mock exports not found for "${url}"`)});

lib/internal/test_runner/mock/mock.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const kMockUnknownMessage = 3;
7070
const kWaitTimeout = 5_000;
7171
const kBadExportsMessage = 'Cannot create mock because named exports ' +
7272
'cannot be applied to the provided default export.';
73-
const kSupportedFormats = ['builtin', 'commonjs', 'module'];
73+
const kSupportedFormats = ['builtin', 'commonjs', 'module', 'module-typescript', 'commonjs-typescript'];
7474
let sharedModuleState;
7575

7676
class MockFunctionContext {
@@ -517,7 +517,10 @@ class MockTracker {
517517

518518
// Get the file that called this function. We need four stack frames:
519519
// vm context -> getStructuredStack() -> this function -> actual caller.
520-
const caller = pathToFileURL(getStructuredStack()[3]?.getFileName()).href;
520+
const filename = getStructuredStack()[3]?.getFileName();
521+
// If the caller is already a file URL, use it as is. Otherwise, convert it.
522+
const hasFileProtocol = StringPrototypeStartsWith(filename, 'file://');
523+
const caller = hasFileProtocol ? filename : pathToFileURL(filename).href;
521524
const { format, url } = sharedState.moduleLoader.resolveSync(
522525
mockSpecifier, caller, null,
523526
);

test/es-module/test-typescript.mjs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { skip, spawnPromisified } from '../common/index.mjs';
1+
import { skip, spawnPromisified, isWindows } from '../common/index.mjs';
22
import * as fixtures from '../common/fixtures.mjs';
33
import { match, strictEqual } from 'node:assert';
44
import { test } from 'node:test';
@@ -336,3 +336,20 @@ test('execute a JavaScript file importing a cjs TypeScript file', async () => {
336336
match(result.stdout, /Hello, TypeScript!/);
337337
strictEqual(result.code, 0);
338338
});
339+
340+
// TODO(marco-ippolito) Due to a bug in SWC, the TypeScript loader
341+
// does not work on Windows arm64. This test should be re-enabled
342+
// when https://github.com/nodejs/node/issues/54645 is fixed
343+
test('execute a TypeScript test mocking module', { skip: isWindows && process.arch === 'arm64' }, async () => {
344+
const result = await spawnPromisified(process.execPath, [
345+
'--test',
346+
'--experimental-test-module-mocks',
347+
'--experimental-strip-types',
348+
'--no-warnings',
349+
fixtures.path('typescript/ts/test-mock-module.ts'),
350+
]);
351+
strictEqual(result.stderr, '');
352+
match(result.stdout, /Hello, TypeScript-Module!/);
353+
match(result.stdout, /Hello, TypeScript-CommonJS!/);
354+
strictEqual(result.code, 0);
355+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const logger = (): void => { };
2+
3+
module.exports = {
4+
logger
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const logger = (): void => { };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { before, mock, test } from 'node:test';
2+
import { strictEqual } from 'node:assert';
3+
4+
const logger = mock.fn((s) => console.log(`Hello, ${s}!`));
5+
6+
before(async () => {
7+
mock.module('./module-logger.ts', {
8+
namedExports: { logger }
9+
});
10+
mock.module('./commonjs-logger.ts', {
11+
namedExports: { logger }
12+
});
13+
});
14+
15+
test('logger', async () => {
16+
const { logger: mockedModule } = await import('./module-logger.ts');
17+
mockedModule('TypeScript-Module');
18+
strictEqual(logger.mock.callCount(), 1);
19+
20+
const { logger: mockedCommonjs } = await import('./commonjs-logger.ts');
21+
mockedCommonjs('TypeScript-CommonJS');
22+
strictEqual(logger.mock.callCount(), 2);
23+
});

0 commit comments

Comments
 (0)