From bb6e5e83bacedd86a6581d73936de58682853f40 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 24 Mar 2026 11:04:49 +0900 Subject: [PATCH 1/3] fix: don't resolve setupFiles from parent directory --- .../vitest/src/node/config/resolveConfig.ts | 5 ++++ .../nested-no-ext/basic.test.ts | 5 ++++ .../nested-no-ext/setup.ts | 1 + .../nested-no-ext/vitest.config.ts | 7 +++++ .../setup-files-resolve/nested/basic.test.ts | 5 ++++ .../setup-files-resolve/nested/setup.ts | 1 + .../nested/vitest.config.ts | 7 +++++ .../cli/fixtures/setup-files-resolve/setup.ts | 1 + test/cli/test/setup-files.test.ts | 28 +++++++++++++++++++ 9 files changed, 60 insertions(+) create mode 100644 test/cli/fixtures/setup-files-resolve/nested-no-ext/basic.test.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested-no-ext/setup.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested-no-ext/vitest.config.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested/basic.test.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested/setup.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested/vitest.config.ts create mode 100644 test/cli/fixtures/setup-files-resolve/setup.ts diff --git a/packages/vitest/src/node/config/resolveConfig.ts b/packages/vitest/src/node/config/resolveConfig.ts index 78964c1829c7..e10fc3756089 100644 --- a/packages/vitest/src/node/config/resolveConfig.ts +++ b/packages/vitest/src/node/config/resolveConfig.ts @@ -29,6 +29,11 @@ import { BaseSequencer } from '../sequencers/BaseSequencer' import { RandomSequencer } from '../sequencers/RandomSequencer' function resolvePath(path: string, root: string) { + // local-pkg resolves resolveModule("./file.js", { paths: ["/some/root"] }) + // into "/some/file.js" but we want "/some/root/file.js". + if (path[0] === '/' || path[0] === '.') { + return resolve(root, path) + } return normalize( /* @__PURE__ */ resolveModule(path, { paths: [root] }) ?? resolve(root, path), diff --git a/test/cli/fixtures/setup-files-resolve/nested-no-ext/basic.test.ts b/test/cli/fixtures/setup-files-resolve/nested-no-ext/basic.test.ts new file mode 100644 index 000000000000..14cf97c886e4 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-no-ext/basic.test.ts @@ -0,0 +1,5 @@ +import { test, expect } from "vitest"; + +test("basic", () => { + expect((globalThis as any).__testSetupResolve).toBe("ok"); +}); diff --git a/test/cli/fixtures/setup-files-resolve/nested-no-ext/setup.ts b/test/cli/fixtures/setup-files-resolve/nested-no-ext/setup.ts new file mode 100644 index 000000000000..72a71bac7429 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-no-ext/setup.ts @@ -0,0 +1 @@ +(globalThis as any).__testSetupResolve = "ok"; diff --git a/test/cli/fixtures/setup-files-resolve/nested-no-ext/vitest.config.ts b/test/cli/fixtures/setup-files-resolve/nested-no-ext/vitest.config.ts new file mode 100644 index 000000000000..34b9b2ee11a4 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-no-ext/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + setupFiles: ["./setup"], + }, +}); diff --git a/test/cli/fixtures/setup-files-resolve/nested/basic.test.ts b/test/cli/fixtures/setup-files-resolve/nested/basic.test.ts new file mode 100644 index 000000000000..14cf97c886e4 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested/basic.test.ts @@ -0,0 +1,5 @@ +import { test, expect } from "vitest"; + +test("basic", () => { + expect((globalThis as any).__testSetupResolve).toBe("ok"); +}); diff --git a/test/cli/fixtures/setup-files-resolve/nested/setup.ts b/test/cli/fixtures/setup-files-resolve/nested/setup.ts new file mode 100644 index 000000000000..72a71bac7429 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested/setup.ts @@ -0,0 +1 @@ +(globalThis as any).__testSetupResolve = "ok"; diff --git a/test/cli/fixtures/setup-files-resolve/nested/vitest.config.ts b/test/cli/fixtures/setup-files-resolve/nested/vitest.config.ts new file mode 100644 index 000000000000..b76b9483efb2 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + setupFiles: ["./setup.ts"], + }, +}); diff --git a/test/cli/fixtures/setup-files-resolve/setup.ts b/test/cli/fixtures/setup-files-resolve/setup.ts new file mode 100644 index 000000000000..d99a4cf6ed33 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/setup.ts @@ -0,0 +1 @@ +(globalThis as any).__testSetupResolve = "not-this"; diff --git a/test/cli/test/setup-files.test.ts b/test/cli/test/setup-files.test.ts index bd320fb7e7da..acddea35346b 100644 --- a/test/cli/test/setup-files.test.ts +++ b/test/cli/test/setup-files.test.ts @@ -41,3 +41,31 @@ describe('setup files with forceRerunTrigger', () => { expect(stdout).toContain('1 passed') }) }) + +it('setup files resolution in nested folder', async () => { + const result = await runVitest({ + root: 'fixtures/setup-files-resolve/nested', + }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(result.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "basic": "passed", + }, + } + `) +}) + +it('setup files resolution in nested folder without extension', async () => { + const result = await runVitest({ + root: 'fixtures/setup-files-resolve/nested-no-ext', + }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(result.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "basic": "passed", + }, + } + `) +}) From a712b9c6b08e3ef934d4f680868b27f2428c6d9d Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 24 Mar 2026 11:20:39 +0900 Subject: [PATCH 2/3] fix: workaround --- .../vitest/src/node/config/resolveConfig.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/vitest/src/node/config/resolveConfig.ts b/packages/vitest/src/node/config/resolveConfig.ts index e10fc3756089..472d15c13715 100644 --- a/packages/vitest/src/node/config/resolveConfig.ts +++ b/packages/vitest/src/node/config/resolveConfig.ts @@ -13,7 +13,7 @@ import crypto from 'node:crypto' import { pathToFileURL } from 'node:url' import { slash, toArray } from '@vitest/utils/helpers' import { resolveModule } from 'local-pkg' -import { normalize, relative, resolve } from 'pathe' +import { join, normalize, relative, resolve } from 'pathe' import c from 'tinyrainbow' import { mergeConfig } from 'vite' import { @@ -29,13 +29,17 @@ import { BaseSequencer } from '../sequencers/BaseSequencer' import { RandomSequencer } from '../sequencers/RandomSequencer' function resolvePath(path: string, root: string) { - // local-pkg resolves resolveModule("./file.js", { paths: ["/some/root"] }) - // into "/some/file.js" but we want "/some/root/file.js". - if (path[0] === '/' || path[0] === '.') { - return resolve(root, path) - } + // local-pkg (mlly)'s resolveModule("./file", { paths: ["/some/root"] }) tries + // /some/file + // /some/file.js + // /some/root/file + // /some/root/file.js + // etc. + // but we don't want to resolve files from parent directories, + // so we ensure passing "/" suffix such as "/some/root/" + // https://github.com/unjs/mlly/blob/401d42983f6f3a9112658d67b0a92ba4fb1d7efa/src/resolve.ts#L104-L110 return normalize( - /* @__PURE__ */ resolveModule(path, { paths: [root] }) + /* @__PURE__ */ resolveModule(path, { paths: [join(root, '/')] }) ?? resolve(root, path), ) } From e9431709c385006c17c81d227123be7ded64bc42 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 24 Mar 2026 13:41:29 +0900 Subject: [PATCH 3/3] test: test bare name --- .../setup-files-resolve/nested-bare/basic.test.ts | 5 +++++ .../setup-files-resolve/nested-bare/setup.ts | 1 + .../nested-bare/vitest.config.ts | 7 +++++++ test/cli/test/setup-files.test.ts | 14 ++++++++++++++ 4 files changed, 27 insertions(+) create mode 100644 test/cli/fixtures/setup-files-resolve/nested-bare/basic.test.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested-bare/setup.ts create mode 100644 test/cli/fixtures/setup-files-resolve/nested-bare/vitest.config.ts diff --git a/test/cli/fixtures/setup-files-resolve/nested-bare/basic.test.ts b/test/cli/fixtures/setup-files-resolve/nested-bare/basic.test.ts new file mode 100644 index 000000000000..14cf97c886e4 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-bare/basic.test.ts @@ -0,0 +1,5 @@ +import { test, expect } from "vitest"; + +test("basic", () => { + expect((globalThis as any).__testSetupResolve).toBe("ok"); +}); diff --git a/test/cli/fixtures/setup-files-resolve/nested-bare/setup.ts b/test/cli/fixtures/setup-files-resolve/nested-bare/setup.ts new file mode 100644 index 000000000000..72a71bac7429 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-bare/setup.ts @@ -0,0 +1 @@ +(globalThis as any).__testSetupResolve = "ok"; diff --git a/test/cli/fixtures/setup-files-resolve/nested-bare/vitest.config.ts b/test/cli/fixtures/setup-files-resolve/nested-bare/vitest.config.ts new file mode 100644 index 000000000000..dac7ccd43cf4 --- /dev/null +++ b/test/cli/fixtures/setup-files-resolve/nested-bare/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + setupFiles: ["setup.ts"], + }, +}); diff --git a/test/cli/test/setup-files.test.ts b/test/cli/test/setup-files.test.ts index acddea35346b..42521eba3cbe 100644 --- a/test/cli/test/setup-files.test.ts +++ b/test/cli/test/setup-files.test.ts @@ -69,3 +69,17 @@ it('setup files resolution in nested folder without extension', async () => { } `) }) + +it('setup files resolution in nested folder with bare name', async () => { + const result = await runVitest({ + root: 'fixtures/setup-files-resolve/nested-bare', + }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + expect(result.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "basic": "passed", + }, + } + `) +})