[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix(coverage): avoid matching sibling project roots (#10311)

Co-authored-by: Shin JaeHee <jaeheesin@gmail.com>
Co-authored-by: Ari Perkkiö <ari.perkkio@gmail.com>

authored by

innoprej
Shin JaeHee
Ari Perkkiö
and committed by
GitHub
(Jun 1, 2026, 4:24 PM +0300) e30dd9cf 65547d6b

+17 -3
+14 -1
test/coverage-test/test/include-exclude.unit.test.ts
··· 144 144 expect(isIncluded(resolve(process.cwd(), '../../package-b/src/two.ts'))).toBe(false) 145 145 }) 146 146 147 - async function init(options: Partial<CoverageOptions> & { testInclude?: string[] }) { 147 + test('files with almost matching name, outside project when allowExternal: false', async () => { 148 + const isIncluded = await init({ 149 + include: ['**/*.ts'], 150 + root: './something/', 151 + allowExternal: false, 152 + }) 153 + 154 + expect(isIncluded(resolve(process.cwd(), './something/src/one.ts'))).toBe(true) 155 + expect(isIncluded(resolve(process.cwd(), './not-something/src/two.ts'))).toBe(false) 156 + expect(isIncluded(resolve(process.cwd(), './something-else/src/three.ts'))).toBe(false) 157 + }) 158 + 159 + async function init(options: Partial<CoverageOptions> & { testInclude?: string[]; root?: string }) { 148 160 const vitest = await createVitest('test', { 149 161 config: false, 150 162 include: ['dont-match-anything', ...(options.testInclude || [])], 163 + root: options.root, 151 164 coverage: { 152 165 ...options, 153 166 enabled: true,
+3 -2
packages/vitest/src/node/coverage.ts
··· 156 156 return cacheHit 157 157 } 158 158 159 + const matchingRoot = roots.find(root => filename.startsWith(`${slash(root)}/`) || filename === slash(root)) 160 + 159 161 // File outside project root with default allowExternal 160 - if (this.options.allowExternal === false && roots.every(root => !filename.startsWith(root))) { 162 + if (this.options.allowExternal === false && !matchingRoot) { 161 163 this.globCache.set(filename, false) 162 164 163 165 return false 164 166 } 165 167 166 - const matchingRoot = roots.find(root => filename.startsWith(`${slash(root)}/`) || filename === slash(root)) 167 168 const relativeFilename = matchingRoot ? relative(matchingRoot, filename) : filename 168 169 169 170 if (pm.isMatch(relativeFilename, this.options.exclude, { dot: true })) {