From 91b06ccea951f340a261e7eb063eb58ecff45e08 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 2 Apr 2024 12:50:16 +0200 Subject: [PATCH] fix(vitest): correctly filter by parent folder (#5408) --- packages/vitest/src/node/workspace.ts | 14 ++++++++++++-- test/filters/test/testname-pattern.test.ts | 14 +++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index b73f438ce4fa..7b17e73ed69c 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -1,7 +1,7 @@ import { promises as fs } from 'node:fs' import fg from 'fast-glob' import mm from 'micromatch' -import { dirname, join, relative, resolve, toNamespacedPath } from 'pathe' +import { dirname, isAbsolute, join, relative, resolve, toNamespacedPath } from 'pathe' import type { TransformResult, ViteDevServer, InlineConfig as ViteInlineConfig } from 'vite' import { ViteNodeRunner } from 'vite-node/client' import { ViteNodeServer } from 'vite-node/server' @@ -257,7 +257,7 @@ export class WorkspaceProject { return code.includes('import.meta.vitest') } - filterFiles(testFiles: string[], filters: string[] = [], dir: string) { + filterFiles(testFiles: string[], filters: string[], dir: string) { if (filters.length && process.platform === 'win32') filters = filters.map(f => toNamespacedPath(f)) @@ -266,6 +266,16 @@ export class WorkspaceProject { const testFile = relative(dir, t).toLocaleLowerCase() return filters.some((f) => { const relativePath = f.endsWith('/') ? join(relative(dir, f), '/') : relative(dir, f) + + // if filter is a full file path, we should include it if it's in the same folder + if (isAbsolute(f)) { + // the file is inside the filter path, so we should always include it, + // we don't include ../file because this condition is always true if + // the file doens't exist which cause false positives + if (relativePath === '..' || relativePath === '../' || relativePath.startsWith('../..')) + return true + } + return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase()) }) }) diff --git a/test/filters/test/testname-pattern.test.ts b/test/filters/test/testname-pattern.test.ts index 6a134c6c1615..b6001e69268a 100644 --- a/test/filters/test/testname-pattern.test.ts +++ b/test/filters/test/testname-pattern.test.ts @@ -1,4 +1,4 @@ -import { resolve } from 'pathe' +import { join, resolve } from 'pathe' import { expect, test } from 'vitest' import { runVitest } from '../../test-utils' @@ -30,3 +30,15 @@ test('match by pattern that also matches current working directory', async () => expect(stdout).toMatch('Test Files 1 passed (1)') expect(stdout).not.toMatch('test/example.test.ts') }) + +test.each([ + ['the parent of CWD', resolve(process.cwd(), '..')], + ['the parent of CWD with slash', join(resolve(process.cwd(), '..'), '/')], + ['the parent of a parent of CWD', resolve(process.cwd(), '..', '..')], +])('match by pattern that also matches %s: %s', async (_, filter) => { + const { stdout } = await runVitest({ root: './fixtures' }, [filter]) + + expect(stdout).toMatch('✓ test/filters.test.ts > this will pass') + expect(stdout).toMatch('× test/dont-run-this.test.ts > this will fail') + expect(stdout).toMatch('✓ test/example.test.ts > this will pass') +})