diff --git a/packages/core/src/runtime/worker/loadModule.ts b/packages/core/src/runtime/worker/loadModule.ts index 75b0cc88..79a75fa2 100644 --- a/packages/core/src/runtime/worker/loadModule.ts +++ b/packages/core/src/runtime/worker/loadModule.ts @@ -15,7 +15,15 @@ const createRequire = ( assetFiles: Record, interopDefault: boolean, ): NodeJS.Require => { - const _require = createNativeRequire(filename); + const _require = (() => { + try { + // compat with some testPath may not be an available path but the third-party package name + return createNativeRequire(filename); + } catch (_err) { + return createNativeRequire(distPath); + } + })(); + const require = ((id: string) => { const currentDirectory = path.dirname(distPath); diff --git a/packages/core/src/utils/testFiles.ts b/packages/core/src/utils/testFiles.ts index 55406835..e447a40a 100644 --- a/packages/core/src/utils/testFiles.ts +++ b/packages/core/src/utils/testFiles.ts @@ -1,5 +1,6 @@ import { existsSync } from 'node:fs'; import fs from 'node:fs/promises'; +import { createRequire } from 'node:module'; import pathe from 'pathe'; import { glob } from 'tinyglobby'; import { castArray, color, getAbsolutePath, parsePosix } from './helper'; @@ -98,6 +99,15 @@ export const getTestEntries = async ({ ); }; +const tryResolve = (request: string, rootPath: string) => { + try { + const require = createRequire(rootPath); + return require.resolve(request, { paths: [rootPath] }); + } catch (_err) { + return undefined; + } +}; + export const getSetupFiles = ( setups: string[] | string | undefined, rootPath: string, @@ -105,16 +115,23 @@ export const getSetupFiles = ( return Object.fromEntries( castArray(setups).map((setupFile) => { const setupFilePath = getAbsolutePath(rootPath, setupFile); - - if (!existsSync(setupFilePath)) { - let errorMessage = `Setup file ${color.red(setupFile)} not found`; - if (setupFilePath !== setupFile) { - errorMessage += color.gray(` (resolved path: ${setupFilePath})`); + try { + if (!existsSync(setupFilePath)) { + let errorMessage = `Setup file ${color.red(setupFile)} not found`; + if (setupFilePath !== setupFile) { + errorMessage += color.gray(` (resolved path: ${setupFilePath})`); + } + throw errorMessage; + } + const relativePath = pathe.relative(rootPath, setupFilePath); + return [formatTestEntryName(relativePath), setupFilePath]; + } catch (err) { + // support use package name as setupFiles value + if (tryResolve(setupFile, rootPath)) { + return [formatTestEntryName(setupFile), setupFile]; } - throw errorMessage; + throw err; } - const relativePath = pathe.relative(rootPath, setupFilePath); - return [formatTestEntryName(relativePath), setupFilePath]; }), ); }; diff --git a/tests/setup/fixtures/package-name/index.test.ts b/tests/setup/fixtures/package-name/index.test.ts new file mode 100644 index 00000000..889f0816 --- /dev/null +++ b/tests/setup/fixtures/package-name/index.test.ts @@ -0,0 +1,6 @@ +import { expect, it } from '@rstest/core'; + +it('should run setup file correctly', () => { + expect(process.env.RETEST_SETUP_FLAG).toBe('1'); + expect(process.env.NODE_ENV).toBe('rstest:production'); +}); diff --git a/tests/setup/fixtures/package-name/rstest.config.ts b/tests/setup/fixtures/package-name/rstest.config.ts new file mode 100644 index 00000000..2bd065e8 --- /dev/null +++ b/tests/setup/fixtures/package-name/rstest.config.ts @@ -0,0 +1,15 @@ +import { join } from 'node:path'; +import { defineConfig } from '@rstest/core'; + +import fse from 'fs-extra'; + +fse.copySync( + join(__dirname, './test-setup-fixtures'), + join(__dirname, './node_modules/test-setup'), +); + +export default defineConfig({ + passWithNoTests: true, + setupFiles: ['test-setup'], + exclude: ['**/node_modules/**', '**/dist/**'], +}); diff --git a/tests/setup/fixtures/package-name/test-setup-fixtures/index.js b/tests/setup/fixtures/package-name/test-setup-fixtures/index.js new file mode 100644 index 00000000..a778887b --- /dev/null +++ b/tests/setup/fixtures/package-name/test-setup-fixtures/index.js @@ -0,0 +1,2 @@ +process.env.RETEST_SETUP_FLAG = '1'; +process.env.NODE_ENV = 'rstest:production'; diff --git a/tests/setup/fixtures/package-name/test-setup-fixtures/package.json b/tests/setup/fixtures/package-name/test-setup-fixtures/package.json new file mode 100644 index 00000000..a431c32f --- /dev/null +++ b/tests/setup/fixtures/package-name/test-setup-fixtures/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "name": "@rstest/tests-setup", + "main": "index.js", + "version": "1.0.0" +} diff --git a/tests/setup/index.test.ts b/tests/setup/index.test.ts index 14ca61e0..7e9409e6 100644 --- a/tests/setup/index.test.ts +++ b/tests/setup/index.test.ts @@ -46,4 +46,17 @@ describe('test setup file', async () => { logs.find((log) => log.includes('rstest.setup.ts:1:7')), ).toBeTruthy(); }); + + it('should run setup file correctly when setupFiles value is package name', async () => { + const { expectExecSuccess } = await runRstestCli({ + command: 'rstest', + args: ['run'], + options: { + nodeOptions: { + cwd: join(__dirname, 'fixtures/package-name'), + }, + }, + }); + await expectExecSuccess(); + }); });