Skip to content

Commit

Permalink
fix(watch): don't indicate exit when no matching files (#7246)
Browse files Browse the repository at this point in the history
Co-authored-by: Ari Perkkiö <[email protected]>
  • Loading branch information
sheremet-va and AriPerkkio authored Jan 15, 2025
1 parent 48645bf commit 003c0be
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 64 deletions.
14 changes: 5 additions & 9 deletions packages/vitest/src/node/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { VitestPackageInstaller } from './packageInstaller'
import { createPool } from './pool'
import { TestProject } from './project'
import { BlobReporter, readBlobs } from './reporters/blob'
import { HangingProcessReporter } from './reporters/hanging-process'
import { createBenchmarkReporters, createReporters } from './reporters/utils'
import { VitestSpecifications } from './specifications'
import { StateManager } from './state'
Expand Down Expand Up @@ -564,8 +565,6 @@ export class Vitest {
// Report coverage for uncovered files
await this.reportCoverage(coverage, true)

this.logger.printNoTestFound(filters)

if (throwAnError) {
throw new FilesNotFoundError(this.mode)
}
Expand Down Expand Up @@ -671,11 +670,6 @@ export class Vitest {
}

private async runFiles(specs: TestSpecification[], allTestsRun: boolean): Promise<TestRunResult> {
const filepaths = specs.map(spec => spec.moduleId)
this.state.collectPaths(filepaths)

await this.report('onPathsCollected', filepaths)
await this.report('onSpecsCollected', specs.map(spec => spec.toJSON()))
await this._testRun.start(specs)

// previous run
Expand Down Expand Up @@ -1140,7 +1134,7 @@ export class Vitest {
this.state.getProcessTimeoutCauses().forEach(cause => console.warn(cause))

if (!this.pool) {
const runningServers = [this.vite, ...this.resolvedProjects.map(p => p.vite)].filter(Boolean).length
const runningServers = [this._vite, ...this.resolvedProjects.map(p => p._vite)].filter(Boolean).length

if (runningServers === 1) {
console.warn('Tests closed successfully but something prevents Vite server from exiting')
Expand All @@ -1152,7 +1146,9 @@ export class Vitest {
console.warn('Tests closed successfully but something prevents the main process from exiting')
}

console.warn('You can try to identify the cause by enabling "hanging-process" reporter. See https://vitest.dev/config/#reporters')
if (!this.reporters.some(r => r instanceof HangingProcessReporter)) {
console.warn('You can try to identify the cause by enabling "hanging-process" reporter. See https://vitest.dev/config/#reporters')
}
}

process.exit()
Expand Down
43 changes: 25 additions & 18 deletions packages/vitest/src/node/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,29 @@ export class Logger {

printNoTestFound(filters?: string[]) {
const config = this.ctx.config

if (config.watch && (config.changed || config.related?.length)) {
this.log(`No affected ${config.mode} files found\n`)
}
else if (config.watch) {
this.log(
c.red(`No ${config.mode} files found. You can change the file name pattern by pressing "p"\n`),
)
}
else {
if (config.passWithNoTests) {
this.log(`No ${config.mode} files found, exiting with code 0\n`)
}
else {
this.error(
c.red(`No ${config.mode} files found, exiting with code 1\n`),
)
}
}

const comma = c.dim(', ')
if (filters?.length) {
this.console.error(c.dim('filter: ') + c.yellow(filters.join(comma)))
this.console.error(c.dim('filter: ') + c.yellow(filters.join(comma)))
}
const projectsFilter = toArray(config.project)
if (projectsFilter.length) {
Expand All @@ -140,9 +160,9 @@ export class Logger {
}
this.ctx.projects.forEach((project) => {
const config = project.config
const output = (project.isRootProject() || !project.name) ? '' : `[${project.name}]`
if (output) {
this.console.error(c.bgCyan(`${output} Config`))
const printConfig = !project.isRootProject() && project.name
if (printConfig) {
this.console.error(`\n${formatProjectName(project.name)}\n`)
}
if (config.include) {
this.console.error(
Expand All @@ -165,20 +185,7 @@ export class Logger {
)
}
})

if (config.watch && (config.changed || config.related?.length)) {
this.log(`No affected ${config.mode} files found\n`)
}
else {
if (config.passWithNoTests) {
this.log(`No ${config.mode} files found, exiting with code 0\n`)
}
else {
this.error(
c.red(`\nNo ${config.mode} files found, exiting with code 1`),
)
}
}
this.console.error()
}

printBanner() {
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/node/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class TestProject {
/** @internal */ vitenode!: ViteNodeServer
/** @internal */ typechecker?: Typechecker
/** @internal */ _config?: ResolvedConfig
/** @internal */ _vite?: ViteDevServer

private runner!: ViteNodeRunner

Expand All @@ -75,7 +76,6 @@ export class TestProject {

private _globalSetups?: GlobalSetupFile[]
private _provided: ProvidedContext = {} as any
private _vite?: ViteDevServer

constructor(
/** @deprecated */
Expand Down
7 changes: 6 additions & 1 deletion packages/vitest/src/node/reporters/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ export abstract class BaseReporter implements Reporter {

onFinished(files = this.ctx.state.getFiles(), errors = this.ctx.state.getUnhandledErrors()) {
this.end = performance.now()
this.reportSummary(files, errors)
if (!files.length && !errors.length) {
this.ctx.logger.printNoTestFound(this.ctx.filenamePattern)
}
else {
this.reportSummary(files, errors)
}
}

onTaskUpdate(packs: TaskResultPack[]) {
Expand Down
18 changes: 7 additions & 11 deletions packages/vitest/src/node/reporters/default.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { File } from '@vitest/runner'
import type { Vitest } from '../core'
import type { TestSpecification } from '../spec'
import type { BaseOptions } from './base'
import type { ReportedHookContext, TestCase, TestModule } from './reported-tasks'
import { BaseReporter } from './base'
Expand Down Expand Up @@ -29,6 +29,10 @@ export class DefaultReporter extends BaseReporter {
}
}

onTestRunStart(specifications: ReadonlyArray<TestSpecification>) {
this.summary?.onTestRunStart(specifications)
}

onTestModuleQueued(file: TestModule) {
this.summary?.onTestModuleQueued(file)
}
Expand Down Expand Up @@ -72,17 +76,9 @@ export class DefaultReporter extends BaseReporter {
this.renderSucceed = paths.length <= 1
}
}

this.summary?.onPathsCollected(paths)
}

onWatcherRerun(files: string[], trigger?: string) {
this.summary?.onWatcherRerun()
super.onWatcherRerun(files, trigger)
}

onFinished(files?: File[], errors?: unknown[]) {
this.summary?.onFinished()
super.onFinished(files, errors)
onTestRunEnd() {
this.summary?.onTestRunEnd()
}
}
2 changes: 1 addition & 1 deletion packages/vitest/src/node/reporters/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export class JsonReporter implements Reporter {
const numTodoTests = tests.filter(t => t.mode === 'todo').length
const testResults: Array<JsonTestResult> = []

const success = numFailedTestSuites === 0 && numFailedTests === 0
const success = !!(files.length > 0 || this.ctx.config.passWithNoTests) && numFailedTestSuites === 0 && numFailedTests === 0

for (const file of files) {
const tests = getTests([file])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class WindowRenderer {

start() {
this.finished = false
this.renderInterval = setInterval(() => this.flushBuffer(), this.options.interval)
this.renderInterval = setInterval(() => this.flushBuffer(), this.options.interval).unref()
}

stop() {
Expand Down
13 changes: 5 additions & 8 deletions packages/vitest/src/node/reporters/summary.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Vitest } from '../core'
import type { TestSpecification } from '../spec'
import type { Reporter } from '../types/reporter'
import type { ReportedHookContext, TestCase, TestModule } from './reported-tasks'
import c from 'tinyrainbow'
Expand Down Expand Up @@ -75,29 +76,25 @@ export class SummaryReporter implements Reporter {
getWindow: () => this.createSummary(),
})

this.startTimers()

this.ctx.onClose(() => {
clearInterval(this.durationInterval)
this.renderer.stop()
})
}

onPathsCollected(paths?: string[]) {
this.modules.total = (paths || []).length
}

onWatcherRerun() {
onTestRunStart(specifications: ReadonlyArray<TestSpecification>) {
this.runningModules.clear()
this.finishedModules.clear()
this.modules = emptyCounters()
this.tests = emptyCounters()

this.startTimers()
this.renderer.start()

this.modules.total = specifications.length
}

onFinished() {
onTestRunEnd() {
this.runningModules.clear()
this.finishedModules.clear()
this.renderer.finish()
Expand Down
5 changes: 5 additions & 0 deletions packages/vitest/src/node/test-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export class TestRun {
constructor(private vitest: Vitest) {}

async start(specifications: TestSpecification[]) {
const filepaths = specifications.map(spec => spec.moduleId)
this.vitest.state.collectPaths(filepaths)

await this.vitest.report('onPathsCollected', Array.from(new Set(filepaths)))
await this.vitest.report('onSpecsCollected', specifications.map(spec => spec.toJSON()))
await this.vitest.report('onTestRunStart', [...specifications])
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default defineConfig({
test: {
include: ['browser-basic.test.ts'],
browser: {
name: 'chromium',
instances: [{ browser: 'chromium' }],
enabled: true,
headless: true,
provider: 'playwright',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default defineConfig({
test: {
include: ['./browser-custom.test.ts'],
browser: {
name: 'chromium',
instances: [{ browser: 'chromium' }],
enabled: true,
headless: true,
provider: 'playwright',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default defineConfig({
test: {
include: ['./browser-custom.test.ts'],
browser: {
name: 'chromium',
instances: [{ browser: 'chromium' }],
enabled: true,
headless: true,
provider: 'playwright',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default defineConfig({
test: {
include: ['./browser-basic.test.ts'],
browser: {
name: 'chromium',
instances: [{ browser: 'chromium' }],
enabled: true,
headless: true,
provider: 'playwright',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
name: 'chromium',
instances: [{ browser: 'chromium' }],
enabled: true,
headless: true,
provider: 'playwright',
Expand Down
1 change: 1 addition & 0 deletions test/core/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default defineConfig({
setupFiles: [
'./test/setup.ts',
],
reporters: [['default', { summary: true }], 'hanging-process'],
testNamePattern: '^((?!does not include test that).)*$',
coverage: {
provider: 'istanbul',
Expand Down
87 changes: 87 additions & 0 deletions test/reporters/tests/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,93 @@ describe('json reporter', async () => {
expect(result).toMatchSnapshot()
}, 40000)

it('generates empty json with success: false', async () => {
const { stdout } = await runVitest({
reporters: 'json',
root,
includeTaskLocation: true,
}, ['json-non-existing-files'])

const json = JSON.parse(stdout)
json.startTime = 0
expect(json).toMatchInlineSnapshot(`
{
"numFailedTestSuites": 0,
"numFailedTests": 0,
"numPassedTestSuites": 0,
"numPassedTests": 0,
"numPendingTestSuites": 0,
"numPendingTests": 0,
"numTodoTests": 0,
"numTotalTestSuites": 0,
"numTotalTests": 0,
"snapshot": {
"added": 0,
"didUpdate": false,
"failure": false,
"filesAdded": 0,
"filesRemoved": 0,
"filesRemovedList": [],
"filesUnmatched": 0,
"filesUpdated": 0,
"matched": 0,
"total": 0,
"unchecked": 0,
"uncheckedKeysByFile": [],
"unmatched": 0,
"updated": 0,
},
"startTime": 0,
"success": false,
"testResults": [],
}
`)
})

it('generates empty json with success: true', async () => {
const { stdout } = await runVitest({
reporters: 'json',
root,
includeTaskLocation: true,
passWithNoTests: true,
}, ['json-non-existing-files'])

const json = JSON.parse(stdout)
json.startTime = 0
expect(json).toMatchInlineSnapshot(`
{
"numFailedTestSuites": 0,
"numFailedTests": 0,
"numPassedTestSuites": 0,
"numPassedTests": 0,
"numPendingTestSuites": 0,
"numPendingTests": 0,
"numTodoTests": 0,
"numTotalTestSuites": 0,
"numTotalTests": 0,
"snapshot": {
"added": 0,
"didUpdate": false,
"failure": false,
"filesAdded": 0,
"filesRemoved": 0,
"filesRemovedList": [],
"filesUnmatched": 0,
"filesUpdated": 0,
"matched": 0,
"total": 0,
"unchecked": 0,
"uncheckedKeysByFile": [],
"unmatched": 0,
"updated": 0,
},
"startTime": 0,
"success": true,
"testResults": [],
}
`)
})

it.each([
['passed', 'all-passing-or-skipped'],
['passed', 'all-skipped'],
Expand Down
Loading

0 comments on commit 003c0be

Please sign in to comment.