Skip to content

Commit

Permalink
fix(reporters): rewrite dot renderer without log-update
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Nov 21, 2024
1 parent dac813a commit c8c3f70
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 167 deletions.
139 changes: 106 additions & 33 deletions packages/vitest/src/node/reporters/dot.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,126 @@
import type { UserConsoleLog } from '../../types/general'
import type { File, TaskResultPack, TaskState, Test } from '@vitest/runner'
import type { Vitest } from '../core'
import c from 'tinyrainbow'
import { BaseReporter } from './base'
import { createDotRenderer } from './renderers/dotRenderer'
import { WindowRenderer } from './renderers/windowedRenderer'
import { TaskParser } from './task-parser'

export class DotReporter extends BaseReporter {
renderer?: ReturnType<typeof createDotRenderer>
private summary?: DotSummary

onTaskUpdate() {}
onInit(ctx: Vitest) {
super.onInit(ctx)

onCollected() {
if (this.isTTY) {
const files = this.ctx.state.getFiles(this.watchFilters)
if (!this.renderer) {
this.renderer = createDotRenderer(files, {
logger: this.ctx.logger,
}).start()
}
else {
this.renderer.update(files)
}
this.summary = new DotSummary()
this.summary.onInit(ctx)
}
}

onTaskUpdate(packs: TaskResultPack[]) {
this.summary?.onTaskUpdate(packs)

if (!this.isTTY) {
super.onTaskUpdate(packs)
}
}

async onFinished(
files = this.ctx.state.getFiles(),
errors = this.ctx.state.getUnhandledErrors(),
) {
await this.stopListRender()
this.ctx.logger.log()
onWatcherRerun(files: string[], trigger?: string) {
this.summary?.onWatcherRerun()
super.onWatcherRerun(files, trigger)
}

onFinished(files?: File[], errors?: unknown[]) {
this.summary?.onFinished()
super.onFinished(files, errors)
}
}

async onWatcherStart() {
await this.stopListRender()
super.onWatcherStart()
class DotSummary extends TaskParser {
private renderer!: WindowRenderer
private tests = new Map<Test['id'], TaskState>()

onInit(ctx: Vitest): void {
this.ctx = ctx

this.renderer = new WindowRenderer({
logger: ctx.logger,
getWindow: () => this.createSummary(),
})

this.ctx.onClose(() => this.renderer.stop())
}

async stopListRender() {
this.renderer?.stop()
this.renderer = undefined
await new Promise(resolve => setTimeout(resolve, 10))
onWatcherRerun() {
this.tests.clear()
this.renderer.start()
}

async onWatcherRerun(files: string[], trigger?: string) {
await this.stopListRender()
super.onWatcherRerun(files, trigger)
onFinished() {
this.tests.clear()
this.renderer.finish()
}

onTestStart(test: Test) {
if (!this.tests.has(test.id)) {
this.tests.set(test.id, 'run')
}
}

onTestFinished(test: Test) {
this.tests.set(test.id, test.result?.state || 'skip')
}

onUserConsoleLog(log: UserConsoleLog) {
this.renderer?.clear()
super.onUserConsoleLog(log)
onTestFileFinished() {
const columns = this.renderer.getColumns()

if (this.tests.size < columns) {
return
}

const finishedTests = Array.from(this.tests).filter(entry => entry[1] !== 'run')

if (finishedTests.length < columns) {
return
}

// Remove finished tests from state and render them in static output
let output = ''
let count = 0

for (const [id, state] of finishedTests) {
if (count++ >= columns) {
break
}

this.tests.delete(id)
output += getIcon(state)
}

this.ctx.logger.log(output)
}

private createSummary() {
const summary = ['']

const row = Array.from(this.tests.values()).map(getIcon).join('')
summary.push(row)

summary.push('')
return summary
}
}

function getIcon(state: TaskState) {
switch (state) {
case 'pass':
return c.green('·')
case 'fail':
return c.red('x')
case 'skip':
case 'todo':
return c.dim(c.gray('-'))
default:
return c.yellow('*')
}
}
130 changes: 0 additions & 130 deletions packages/vitest/src/node/reporters/renderers/dotRenderer.ts

This file was deleted.

11 changes: 7 additions & 4 deletions packages/vitest/src/node/reporters/renderers/windowedRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ export class WindowRenderer {
clearInterval(this.renderInterval)
}

getColumns() {
return 'columns' in this.options.logger.outputStream ? this.options.logger.outputStream.columns : 80
}

private flushBuffer() {
if (this.buffer.length === 0) {
return this.render()
Expand Down Expand Up @@ -113,11 +117,11 @@ export class WindowRenderer {
}

const windowContent = this.options.getWindow()
const rowCount = getRenderedRowCount(windowContent, this.options.logger.outputStream)
const rowCount = getRenderedRowCount(windowContent, this.getColumns())
let padding = this.windowHeight - rowCount

if (padding > 0 && message) {
padding -= getRenderedRowCount([message], this.options.logger.outputStream)
padding -= getRenderedRowCount([message], this.getColumns())
}

this.write(SYNC_START)
Expand Down Expand Up @@ -178,9 +182,8 @@ export class WindowRenderer {
}

/** Calculate the actual row count needed to render `rows` into `stream` */
function getRenderedRowCount(rows: string[], stream: Options['logger']['outputStream']) {
function getRenderedRowCount(rows: string[], columns: number) {
let count = 0
const columns = 'columns' in stream ? stream.columns : 80

for (const row of rows) {
const text = stripVTControlCharacters(row)
Expand Down

0 comments on commit c8c3f70

Please sign in to comment.