Skip to content

Commit

Permalink
feat: add explicit extension support when using Typescript and ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
Marsup committed Jul 26, 2024
1 parent aaa1676 commit 78ec46c
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 1 deletion.
26 changes: 26 additions & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,28 @@ exports.run = async function () {
};


internals.addTsEsmHook = function () {

const Module = require('module');

const originalResolveFilename = Module._resolveFilename;

Module._resolveFilename = function (request, parent, ...rest) {

if (request.endsWith('.js') && (parent.filename.endsWith('.ts') || parent.filename.endsWith('.tsx'))) {
const target = Path.join(parent.path, request);
const tsEquivalent = `${target.slice(0, -3)}.ts`;

if (!Fs.existsSync(target) && Fs.existsSync(tsEquivalent)) {
return tsEquivalent;
}
}

return originalResolveFilename.call(this, request, parent, ...rest);
};
};


internals.traverse = async function (paths, options) {

let nextPath = null;
Expand Down Expand Up @@ -141,6 +163,10 @@ internals.traverse = async function (paths, options) {

const scripts = [];

if (options.typescript && testFiles.some(([, defaultToESM]) => defaultToESM)) {
internals.addTsEsmHook();
}

for (const [unresolvedFile, defaultToESM] of testFiles) {

global._labScriptRun = false;
Expand Down
8 changes: 8 additions & 0 deletions test/cli_typescript_esm/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export * from './types.js';

export function add(a: number, b: number) {

return a + b;
}

export const X = new (Date || Date)(); // $lab:coverage:ignore$
12 changes: 12 additions & 0 deletions test/cli_typescript_esm/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { expect } from '@hapi/code';
import * as _Lab from '../../test_runner/index.js';

const { describe, it } = exports.lab = _Lab.script();

describe('Test CLI', () => {

it('adds two numbers together', () => {

expect(1 + 1).to.equal(4);
});
});
1 change: 1 addition & 0 deletions test/cli_typescript_esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "type": "module" }
20 changes: 20 additions & 0 deletions test/cli_typescript_esm/simple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect } from '@hapi/code';
import * as _Lab from '../../test_runner/index.js';

import { add } from './api.js';


const { describe, it } = exports.lab = _Lab.script();

describe('Test CLI', () => {

it('adds two numbers together', () => {

expect(add(1, 1)).to.equal(2);
});

it('subtracts two numbers', () => {

expect(add(2, - 2)).to.equal(0);
});
});
8 changes: 8 additions & 0 deletions test/cli_typescript_esm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"target": "es2021",
"module": "commonjs",
"moduleResolution": "node",
"removeComments": true
}
}
1 change: 1 addition & 0 deletions test/cli_typescript_esm/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Test = string;
2 changes: 1 addition & 1 deletion test/reporters.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe('Reporter', () => {
expect(code).to.equal(0);
expect(output).to.equal(await Fs.readFile(filename, 'utf8'));

await Fs.rmdir(folder, { recursive: true });
await Fs.rm(folder, { recursive: true });
});

it('outputs to a file with output is passed as an array and reporter is an array', async () => {
Expand Down
12 changes: 12 additions & 0 deletions test/typescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ describe('TypeScript', () => {
expect(result.output).to.contain('2 tests complete');
});

it('supports TypeScript with ESM', async () => {

process.chdir(Path.join(__dirname, 'cli_typescript_esm'));
const result = await RunCli(['simple.ts', '-m', '2000', '--typescript']);
expect(result.errorOutput).to.equal('');
expect(result.code).to.equal(0);
expect(result.output).to.contain('2 tests complete');

// Ensure scripts are run together, not independently
expect(result.output.split('Test duration').length - 1).to.equal(1);
});

it('handles errors', async () => {

process.chdir(Path.join(__dirname, 'cli_typescript'));
Expand Down

0 comments on commit 78ec46c

Please sign in to comment.