Skip to content

Commit

Permalink
fix: dot reporter scrollback buffer spam (#3415)
Browse files Browse the repository at this point in the history
  • Loading branch information
gtm-nayan committed May 24, 2023
1 parent 9fbb8d3 commit e6792a9
Showing 1 changed file with 41 additions and 21 deletions.
62 changes: 41 additions & 21 deletions packages/vitest/src/node/reporters/renderers/dotRenderer.ts
Expand Up @@ -27,54 +27,74 @@ function getIcon(task: Task) {
}
}

function render(tasks: Task[]): string {
function render(tasks: Task[], width: number): string {
const all = getTests(tasks)
const output: string[] = []
let currentIcon = pending
let currentTasks = 0
let previousLineWidth = 0
let output = ''

// The log-update uses various ANSI helper utilities, e.g. ansi-warp, ansi-slice,
// when printing. Passing it hundreds of single characters containing ANSI codes reduces
// performances. We can optimize it by reducing amount of ANSI codes, e.g. by coloring
// multiple tasks at once instead of each task separately.
let currentIcon = pending
let currentTasks = 0

const addOutput = () => output.push(currentIcon.color(currentIcon.char.repeat(currentTasks)))
const addOutput = () => {
const { char, color } = currentIcon
const availableWidth = width - previousLineWidth
if (availableWidth > currentTasks) {
output += color(char.repeat(currentTasks))
previousLineWidth += currentTasks
}
else {
// We need to split the line otherwise it will mess up log-update's height calculation
// and spam the scrollback buffer with dots.

// Fill the current line first
let buf = `${char.repeat(availableWidth)}\n`
const remaining = currentTasks - availableWidth

// Then fill as many full rows as possible
const fullRows = Math.floor(remaining / width)
buf += `${char.repeat(width)}\n`.repeat(fullRows)

// Add remaining dots which don't make a full row
const partialRow = remaining % width
if (partialRow > 0) {
buf += char.repeat(partialRow)
previousLineWidth = partialRow
}
else {
previousLineWidth = 0
}

output += color(buf)
}
}
for (const task of all) {
const icon = getIcon(task)
const isLast = all.indexOf(task) === all.length - 1

if (icon === currentIcon) {
currentTasks++

if (isLast)
addOutput()

continue
}

// Task mode/state has changed, add previous group to output
addOutput()

// Start tracking new group
currentTasks = 1
currentIcon = icon

if (isLast)
addOutput()
}

return output.join('')
addOutput()
return output
}

export function createDotRenderer(_tasks: Task[], options: DotRendererOptions) {
let tasks = _tasks
let timer: any

const log = options.logger.logUpdate
const { logUpdate: log, outputStream } = options.logger

function update() {
log(render(tasks))
log(render(tasks, outputStream.columns))
}

return {
Expand All @@ -94,7 +114,7 @@ export function createDotRenderer(_tasks: Task[], options: DotRendererOptions) {
timer = undefined
}
log.clear()
options.logger.log(render(tasks))
options.logger.log(render(tasks, outputStream.columns))
return this
},
clear() {
Expand Down

0 comments on commit e6792a9

Please sign in to comment.