diff --git a/src/cli.ts b/src/cli.ts index 19ca23c55..45e6e408f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,6 +10,7 @@ import { removeArgvFlags, ignoreAfterArgument, } from './remove-argv-flags.js'; +import { testRunnerGlob } from './utils/node-features.js'; const relaySignals = ( childProcess: ChildProcess, @@ -131,15 +132,19 @@ cli({ type: String, alias: 'p', }, - }; + } as const; - const { flags: interceptedFlags } = cli({ + const { + _: firstArgs, + flags: interceptedFlags, + } = cli({ flags: { ...interceptFlags, inputType: String, + test: Boolean, }, help: false, - ignoreArgv: ignoreAfterArgument(), + ignoreArgv: ignoreAfterArgument(false), }); const argvsToRun = removeArgvFlags({ @@ -161,7 +166,16 @@ cli({ }, ); - argvsToRun.push(`--${evalType}`, transformed.code); + argvsToRun.unshift(`--${evalType}`, transformed.code); + } + + // Default --test glob to find TypeScript files + if ( + testRunnerGlob + && interceptedFlags.test + && firstArgs.length === 0 + ) { + argvsToRun.push('**/{test,test/**/*,test-*,*[.-_]test}.?(c|m)@(t|j)s'); } const childProcess = run( diff --git a/src/remove-argv-flags.ts b/src/remove-argv-flags.ts index 081719283..7add1bf73 100644 --- a/src/remove-argv-flags.ts +++ b/src/remove-argv-flags.ts @@ -5,7 +5,7 @@ import { } from 'type-flag'; export const ignoreAfterArgument = ( - ignoreFirstArgument = true, + ignoreFirstArgument = true, // Used for watch ): TypeFlagOptions['ignore'] => { let ignore = false; diff --git a/src/utils/node-features.ts b/src/utils/node-features.ts index 2adb7ca8d..fc33e723e 100644 --- a/src/utils/node-features.ts +++ b/src/utils/node-features.ts @@ -24,3 +24,7 @@ export const importAttributes = ( compareNodeVersion([21, 0, 0]) >= 0 || compareNodeVersion([20, 10, 0]) >= 0 ); + +// Added in v21.0.0 +// https://github.com/nodejs/node/releases/tag/v21.0.0 +export const testRunnerGlob = compareNodeVersion([21, 0, 0]) >= 0; diff --git a/tests/specs/cli.ts b/tests/specs/cli.ts index 25f79508d..6b080a5bc 100644 --- a/tests/specs/cli.ts +++ b/tests/specs/cli.ts @@ -101,20 +101,19 @@ export default testSuite(({ describe }, node: NodeApis) => { }); }); - if ( - compareNodeVersion( - // https://nodejs.org/docs/latest-v18.x/api/cli.html#--test - [18, 1, 0], - node.version.split('.').map(Number) as Version, - ) >= 0 - ) { + const nodeVersion = node.version.split('.').map(Number) as Version; + + // https://nodejs.org/docs/latest-v18.x/api/cli.html#--test + const cliTestFlag = compareNodeVersion([18, 1, 0], nodeVersion) >= 0; + const testRunnerGlob = compareNodeVersion([21, 0, 0], nodeVersion) >= 0; + if (cliTestFlag) { test('Node.js test runner', async ({ onTestFinish }) => { const fixture = await createFixture({ 'test.ts': ` import { test } from 'node:test'; import assert from 'assert'; - test('passing test', () => { + test('some passing test', () => { assert.strictEqual(1, 1); }); `, @@ -124,13 +123,21 @@ export default testSuite(({ describe }, node: NodeApis) => { const tsxProcess = await tsx( [ '--test', - 'test.ts', + ...( + testRunnerGlob + ? [] + : ['test.ts'] + ), ], fixture.path, ); expect(tsxProcess.exitCode).toBe(0); - expect(tsxProcess.stdout).toMatch('# pass 1\n'); + if (testRunnerGlob) { + expect(tsxProcess.stdout).toMatch('some passing test\n'); + } else { + expect(tsxProcess.stdout).toMatch('# pass 1\n'); + } }, 10_000); }