Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vitest): rerun tests if a file loaded with query changes #4130

Merged
merged 4 commits into from Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 23 additions & 27 deletions packages/vitest/src/node/core.ts
Expand Up @@ -586,7 +586,7 @@ export class Vitest {

public getModuleProjects(id: string) {
return this.projects.filter((project) => {
return project.getModuleById(id)
return project.getModulesByFilepath(id).size
// TODO: reevaluate || project.browser?.moduleGraph.getModulesByFile(id)?.size
})
}
Expand All @@ -596,9 +596,13 @@ export class Vitest {
const updateLastChanged = (id: string) => {
const projects = this.getModuleProjects(id)
projects.forEach(({ server, browser }) => {
const mod = server.moduleGraph.getModuleById(id) || browser?.moduleGraph.getModuleById(id)
if (mod)
server.moduleGraph.invalidateModule(mod)
const serverMods = server.moduleGraph.getModulesByFile(id)
serverMods?.forEach(mod => server.moduleGraph.invalidateModule(mod))

if (browser) {
const browserMods = browser.moduleGraph.getModulesByFile(id)
browserMods?.forEach(mod => browser.moduleGraph.invalidateModule(mod))
}
})
}

Expand Down Expand Up @@ -675,22 +679,10 @@ export class Vitest {
const files: string[] = []

for (const project of projects) {
const { server, browser } = project
const mod = server.moduleGraph.getModuleById(id) || browser?.moduleGraph.getModuleById(id)
if (!mod) {
// files with `?v=` query from the browser
const mods = browser?.moduleGraph.getModulesByFile(id)
if (!mods?.size)
return []
let rerun = false
mods.forEach((m) => {
if (m.id && this.handleFileChanged(m.id))
rerun = true
})
if (rerun)
files.push(id)
const { server } = project
const mods = project.getModulesByFilepath(id)
if (!mods.size)
continue
}

// remove queries from id
id = normalizeRequestId(id, server.config.base)
Expand All @@ -705,14 +697,18 @@ export class Vitest {
}

let rerun = false
mod.importers.forEach((i) => {
if (!i.id)
return

const heedsRerun = this.handleFileChanged(i.id)
if (heedsRerun)
rerun = true
})
for (const mod of mods) {
if (!mod.id)
continue
mod.importers.forEach((i) => {
if (!i.id)
return

const heedsRerun = this.handleFileChanged(i.id)
if (heedsRerun)
rerun = true
})
}

if (rerun)
files.push(id)
Expand Down
7 changes: 7 additions & 0 deletions packages/vitest/src/node/workspace.ts
Expand Up @@ -77,6 +77,13 @@ export class WorkspaceProject {
return this.ctx.getCoreWorkspaceProject() === this
}

// it's possible that file path was imported with different queries (?raw, ?url, etc)
getModulesByFilepath(file: string) {
const set = this.server.moduleGraph.getModulesByFile(file)
|| this.browser?.moduleGraph.getModulesByFile(file)
return set || new Set()
}

getModuleById(id: string) {
return this.server.moduleGraph.getModuleById(id)
|| this.browser?.moduleGraph.getModuleById(id)
Expand Down
1 change: 1 addition & 0 deletions test/watch/fixtures/42.txt
@@ -0,0 +1 @@
42
7 changes: 7 additions & 0 deletions test/watch/fixtures/example.test.ts
Expand Up @@ -2,6 +2,13 @@ import { expect, test } from 'vitest'

import { getHelloWorld } from './example'

// @ts-expect-error not typed txt
import answer from './42.txt?raw'

test('answer is 42', () => {
expect(answer).toContain('42')
})

test('getHello', async () => {
expect(getHelloWorld()).toBe('Hello world')
})
12 changes: 12 additions & 0 deletions test/watch/test/file-watching.test.ts
Expand Up @@ -50,6 +50,18 @@ test('editing source file triggers re-run', async () => {
await vitest.waitForStdout('1 passed')
})

test('editing file that was imported with a query reruns suite', async () => {
const vitest = await runVitestCli(...cliArgs)

testUtils.editFile(
testUtils.resolvePath(import.meta.url, '../fixtures/42.txt'),
file => `${file}\n`,
)

await vitest.waitForStdout('RERUN ../42.txt')
await vitest.waitForStdout('1 passed')
})

test('editing force rerun trigger reruns all tests', async () => {
const vitest = await runVitestCli(...cliArgs)

Expand Down