diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 9383ee21eea3..58092faeb4af 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -592,6 +592,9 @@ export class Vitest { id = slash(id) updateLastChanged(id) if (await this.isTargetFile(id)) { + const projects = await this.getProjectsByFiles([id]) + this.projectsTestFiles.set(id, new Set(projects)) + this.changedTests.add(id) this.scheduleRerun([id]) } @@ -738,6 +741,13 @@ export class Vitest { return files } + private async getProjectsByFiles(files: string[]) { + return await Promise.all(this.projects.filter(async (project) => { + const projects = await project.globTestFiles(files) + return projects.length > 0 + })) + } + private async isTargetFile(id: string, source?: string): Promise { const relativeId = relative(this.config.dir || this.config.root, id) if (mm.isMatch(relativeId, this.config.exclude)) diff --git a/test/watch/test/file-watching.test.ts b/test/watch/test/file-watching.test.ts index 1d01e0ac2330..d40a97e8aafc 100644 --- a/test/watch/test/file-watching.test.ts +++ b/test/watch/test/file-watching.test.ts @@ -1,4 +1,4 @@ -import { readFileSync, writeFileSync } from 'node:fs' +import { readFileSync, rmSync, writeFileSync } from 'node:fs' import { afterEach, describe, test } from 'vitest' import { startWatchMode } from './utils' @@ -12,6 +12,8 @@ const testFileContent = readFileSync(testFile, 'utf-8') const configFile = 'fixtures/vitest.config.ts' const configFileContent = readFileSync(configFile, 'utf-8') +const cleanups: (() => void)[] = [] + function editFile(fileContent: string) { return `// Modified by file-watching.test.ts ${fileContent} @@ -23,6 +25,7 @@ afterEach(() => { writeFileSync(sourceFile, sourceFileContent, 'utf8') writeFileSync(testFile, testFileContent, 'utf8') writeFileSync(configFile, configFileContent, 'utf8') + cleanups.splice(0).forEach(cleanup => cleanup()) }) test('editing source file triggers re-run', async () => { @@ -64,6 +67,26 @@ test('editing config file reloads new changes', async () => { await vitest.waitForOutput('ok 2') }) +test('adding a new test file triggers re-run', async () => { + const vitest = await startWatchMode() + + const testFile = 'fixtures/new-dynamic.test.ts' + const testFileContent = ` +import { expect, test } from "vitest"; + +test("dynamic test case", () => { + console.log("Running added dynamic test") + expect(true).toBeTruthy() +}) +` + cleanups.push(() => rmSync(testFile)) + writeFileSync(testFile, testFileContent, 'utf-8') + + await vitest.waitForOutput('Running added dynamic test') + await vitest.waitForOutput('RERUN ../new-dynamic.test.ts') + await vitest.waitForOutput('1 passed') +}) + describe('browser', () => { test.runIf((process.platform !== 'win32'))('editing source file triggers re-run', async () => { const vitest = await startWatchMode('--browser.enabled', '--browser.headless', '--browser.name=chrome')