Skip to content

Commit

Permalink
fix(watch): run test files when added to filesystem
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Apr 14, 2023
1 parent cc819ca commit 7b446e1
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 9 deletions.
21 changes: 15 additions & 6 deletions packages/vitest/src/node/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class Vitest {
this.pool = undefined
this.coverageProvider = undefined
this.runningPromise = undefined
this.projectsTestFiles.clear()

const resolved = resolveConfig(this.mode, options, server.config)

Expand Down Expand Up @@ -591,7 +592,15 @@ export class Vitest {
const onAdd = async (id: string) => {
id = slash(id)
updateLastChanged(id)
if (await this.isTargetFile(id)) {

const matchingProjects: WorkspaceProject[] = []
await Promise.all(this.projects.map(async (project) => {
if (await this.isTargetFile(id, project))
matchingProjects.push(project)
}))

if (matchingProjects.length > 0) {
this.projectsTestFiles.set(id, new Set(matchingProjects))
this.changedTests.add(id)
this.scheduleRerun([id])
}
Expand Down Expand Up @@ -738,13 +747,13 @@ export class Vitest {
return files
}

private async isTargetFile(id: string, source?: string): Promise<boolean> {
const relativeId = relative(this.config.dir || this.config.root, id)
if (mm.isMatch(relativeId, this.config.exclude))
private async isTargetFile(id: string, project: WorkspaceProject, source?: string): Promise<boolean> {
const relativeId = relative(project.config.dir || project.config.root, id)
if (mm.isMatch(relativeId, project.config.exclude))
return false
if (mm.isMatch(relativeId, this.config.include))
if (mm.isMatch(relativeId, project.config.include))
return true
if (this.config.includeSource?.length && mm.isMatch(relativeId, this.config.includeSource)) {
if (project.config.includeSource?.length && mm.isMatch(relativeId, project.config.includeSource)) {
source = source || await fs.readFile(id, 'utf-8')
return this.isInSourceTestFile(source)
}
Expand Down
25 changes: 24 additions & 1 deletion test/watch/test/file-watching.test.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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}
Expand All @@ -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 () => {
Expand Down Expand Up @@ -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')
Expand Down
61 changes: 59 additions & 2 deletions test/watch/test/workspaces.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { fileURLToPath } from 'node:url'
import { readFileSync, writeFileSync } from 'node:fs'
import { afterAll, it } from 'vitest'
import { readFileSync, rmSync, writeFileSync } from 'node:fs'
import { afterAll, afterEach, expect, it } from 'vitest'
import { dirname, resolve } from 'pathe'
import { startWatchMode } from './utils'

const file = fileURLToPath(import.meta.url)
const dir = dirname(file)
const root = resolve(dir, '..', '..', 'workspaces')
const config = resolve(root, 'vitest.config.ts')
const cleanups: (() => void)[] = []

const srcMathFile = resolve(root, 'src', 'math.ts')
const specSpace2File = resolve(root, 'space_2', 'test', 'node.spec.ts')

const srcMathContent = readFileSync(srcMathFile, 'utf-8')
const specSpace2Content = readFileSync(specSpace2File, 'utf-8')

const dynamicTestContent = `// Dynamic test added by test/watch/test/workspaces.test.ts
import { expect, test } from "vitest";
test("dynamic test case", () => {
console.log("Running added dynamic test")
expect(true).toBeTruthy()
})
`

function startVitest() {
return startWatchMode(
{ cwd: root, env: { TEST_WATCH: 'true' } },
Expand All @@ -27,6 +37,10 @@ function startVitest() {
)
}

afterEach(() => {
cleanups.splice(0).forEach(cleanup => cleanup())
})

afterAll(() => {
writeFileSync(srcMathFile, srcMathContent, 'utf8')
writeFileSync(specSpace2File, specSpace2Content, 'utf8')
Expand Down Expand Up @@ -65,3 +79,46 @@ it('filters by test name inside a workspace', async () => {
await vitest.waitForOutput('Test name pattern: /2 x 2 = 4/')
await vitest.waitForOutput('Test Files 1 passed')
})

it('adding a new test file matching core project config triggers re-run', async () => {
const vitest = await startVitest()

const testFile = resolve(root, 'space_2', 'test', 'new-dynamic.test.ts')

cleanups.push(() => rmSync(testFile))
writeFileSync(testFile, dynamicTestContent, 'utf-8')

await vitest.waitForOutput('Running added dynamic test')
await vitest.waitForOutput('RERUN space_2/test/new-dynamic.test.ts')
await vitest.waitForOutput('|space_2| test/new-dynamic.test.ts')

// Wait for tests to end
await vitest.waitForOutput('Waiting for file changes')

// Test case should not be run by other projects
expect(vitest.output).not.include('|space_1|')
expect(vitest.output).not.include('|space_3|')
expect(vitest.output).not.include('|node|')
expect(vitest.output).not.include('|happy-dom|')
})

it('adding a new test file matching project specific config triggers re-run', async () => {
const vitest = await startVitest()

const testFile = resolve(root, 'space_3', 'new-dynamic.space-3-test.ts')
cleanups.push(() => rmSync(testFile))
writeFileSync(testFile, dynamicTestContent, 'utf-8')

await vitest.waitForOutput('Running added dynamic test')
await vitest.waitForOutput('RERUN space_3/new-dynamic.space-3-test.ts')
await vitest.waitForOutput('|space_3| new-dynamic.space-3-test.ts')

// Wait for tests to end
await vitest.waitForOutput('Waiting for file changes')

// Test case should not be run by other projects
expect(vitest.output).not.include('|space_1|')
expect(vitest.output).not.include('|space_2|')
expect(vitest.output).not.include('|node|')
expect(vitest.output).not.include('|happy-dom|')
})

0 comments on commit 7b446e1

Please sign in to comment.