From 316eb739154ea251e1bfb0e60ada2c1ed8d47438 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Mon, 22 Apr 2024 16:13:02 +0900 Subject: [PATCH] fix(vitest): fix false positive file filter match with leading slash (#5578) --- packages/vitest/src/node/workspace.ts | 12 ++--- .../fixtures-slash/test/basic-foo/a.test.ts | 3 ++ .../filters/fixtures-slash/test/basic.test.ts | 3 ++ .../fixtures-slash/test/basic/a.test.ts | 3 ++ .../fixtures-slash/test/foo-basic/a.test.ts | 3 ++ test/filters/fixtures-slash/vitest.config.ts | 3 ++ test/filters/package.json | 2 +- test/filters/test/testname-pattern.test.ts | 46 ++++++++++++++++++- 8 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 test/filters/fixtures-slash/test/basic-foo/a.test.ts create mode 100644 test/filters/fixtures-slash/test/basic.test.ts create mode 100644 test/filters/fixtures-slash/test/basic/a.test.ts create mode 100644 test/filters/fixtures-slash/test/foo-basic/a.test.ts create mode 100644 test/filters/fixtures-slash/vitest.config.ts diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index e9920207c6ab..8b8a52af1551 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -284,17 +284,11 @@ export class WorkspaceProject { return testFiles.filter((t) => { 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 - } + if (isAbsolute(f) && t.startsWith(f)) + return true + const relativePath = f.endsWith('/') ? join(relative(dir, f), '/') : relative(dir, f) return testFile.includes(f.toLocaleLowerCase()) || testFile.includes(relativePath.toLocaleLowerCase()) }) }) diff --git a/test/filters/fixtures-slash/test/basic-foo/a.test.ts b/test/filters/fixtures-slash/test/basic-foo/a.test.ts new file mode 100644 index 000000000000..a855cc0f12b8 --- /dev/null +++ b/test/filters/fixtures-slash/test/basic-foo/a.test.ts @@ -0,0 +1,3 @@ +import { test } from 'vitest' + +test('example', () => {}) diff --git a/test/filters/fixtures-slash/test/basic.test.ts b/test/filters/fixtures-slash/test/basic.test.ts new file mode 100644 index 000000000000..a855cc0f12b8 --- /dev/null +++ b/test/filters/fixtures-slash/test/basic.test.ts @@ -0,0 +1,3 @@ +import { test } from 'vitest' + +test('example', () => {}) diff --git a/test/filters/fixtures-slash/test/basic/a.test.ts b/test/filters/fixtures-slash/test/basic/a.test.ts new file mode 100644 index 000000000000..a855cc0f12b8 --- /dev/null +++ b/test/filters/fixtures-slash/test/basic/a.test.ts @@ -0,0 +1,3 @@ +import { test } from 'vitest' + +test('example', () => {}) diff --git a/test/filters/fixtures-slash/test/foo-basic/a.test.ts b/test/filters/fixtures-slash/test/foo-basic/a.test.ts new file mode 100644 index 000000000000..a855cc0f12b8 --- /dev/null +++ b/test/filters/fixtures-slash/test/foo-basic/a.test.ts @@ -0,0 +1,3 @@ +import { test } from 'vitest' + +test('example', () => {}) diff --git a/test/filters/fixtures-slash/vitest.config.ts b/test/filters/fixtures-slash/vitest.config.ts new file mode 100644 index 000000000000..abed6b2116e1 --- /dev/null +++ b/test/filters/fixtures-slash/vitest.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({}) diff --git a/test/filters/package.json b/test/filters/package.json index 5d6a70c5191b..6185d605cefb 100644 --- a/test/filters/package.json +++ b/test/filters/package.json @@ -3,7 +3,7 @@ "type": "module", "private": true, "scripts": { - "test": "vitest run" + "test": "vitest" }, "devDependencies": { "vite": "latest", diff --git a/test/filters/test/testname-pattern.test.ts b/test/filters/test/testname-pattern.test.ts index b6001e69268a..eb050efd050d 100644 --- a/test/filters/test/testname-pattern.test.ts +++ b/test/filters/test/testname-pattern.test.ts @@ -3,8 +3,12 @@ import { expect, test } from 'vitest' import { runVitest } from '../../test-utils' -test('match by partial pattern', async () => { - const { stdout } = await runVitest({ root: './fixtures' }, ['example']) +test.each([ + { filter: 'example' }, + { filter: '/example' }, + { filter: resolve('./fixtures/test/example') }, +])('match by partial pattern $filter', async ({ filter }) => { + const { stdout } = await runVitest({ root: './fixtures' }, [filter]) expect(stdout).toMatch('✓ test/example.test.ts > this will pass') expect(stdout).toMatch('Test Files 1 passed (1)') @@ -42,3 +46,41 @@ test.each([ expect(stdout).toMatch('× test/dont-run-this.test.ts > this will fail') expect(stdout).toMatch('✓ test/example.test.ts > this will pass') }) + +test.each([ + { + filter: 'basic', + files: [ + 'test/basic.test.ts', + 'test/foo-basic/a.test.ts', + 'test/basic/a.test.ts', + 'test/basic-foo/a.test.ts', + ], + }, + { + filter: '/basic', + files: [ + 'test/basic.test.ts', + 'test/basic/a.test.ts', + 'test/basic-foo/a.test.ts', + ], + }, + { + filter: 'basic/', + files: [ + 'test/foo-basic/a.test.ts', + 'test/basic/a.test.ts', + ], + }, + { + filter: '/basic/', + files: [ + 'test/basic/a.test.ts', + ], + }, +])('filter with slash $filter', async ({ filter, files }) => { + const { stdout } = await runVitest({ root: './fixtures-slash' }, [filter]) + expect(stdout).toMatch(`Test Files ${files.length} passed (${files.length})`) + for (const file of files) + expect(stdout).toMatch(`✓ ${file}`) +})