Skip to content

Commit 7bd11a9

Browse files
authored
fix(runner): fast sequential task updates missing (#8121)
1 parent 1d8ebf9 commit 7bd11a9

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

packages/runner/src/run.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type {
1717
TestContext,
1818
WriteableTestContext,
1919
} from './types/tasks'
20-
import { shuffle } from '@vitest/utils'
20+
import { getSafeTimers, shuffle } from '@vitest/utils'
2121
import { processError } from '@vitest/utils/error'
2222
import { collectTests } from './collect'
2323
import { abortContextSignal, getFileContext } from './context'
@@ -32,6 +32,7 @@ import { hasFailed, hasTests } from './utils/tasks'
3232

3333
const now = globalThis.performance ? globalThis.performance.now.bind(globalThis.performance) : Date.now
3434
const unixNow = Date.now
35+
const { clearTimeout, setTimeout } = getSafeTimers()
3536

3637
function updateSuiteHookState(
3738
task: Task,
@@ -211,12 +212,21 @@ export async function finishSendTasksUpdate(runner: VitestRunner): Promise<void>
211212

212213
function throttle<T extends (...args: any[]) => void>(fn: T, ms: number): T {
213214
let last = 0
214-
return function (this: any, ...args: any[]) {
215+
let pendingCall: ReturnType<typeof setTimeout> | undefined
216+
217+
return function call(this: any, ...args: any[]) {
215218
const now = unixNow()
216219
if (now - last > ms) {
217220
last = now
221+
222+
clearTimeout(pendingCall)
223+
pendingCall = undefined
224+
218225
return fn.apply(this, args)
219226
}
227+
228+
// Make sure fn is still called even if there are no further calls
229+
pendingCall ??= setTimeout(() => call.bind(this)(...args), ms)
220230
} as any
221231
}
222232

test/reporters/tests/test-run.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { UserConsoleLog } from 'vitest'
12
import type {
23
ReportedHookContext,
34
Reporter,
@@ -159,7 +160,10 @@ describe('TestCase', () => {
159160
test('single test case', async () => {
160161
const report = await run({
161162
'example.test.ts': ts`
162-
test('single test case', () => {});
163+
test('single test case', async () => {
164+
await new Promise(resolve => setTimeout(resolve, 150))
165+
console.log("Test running!")
166+
});
163167
`,
164168
})
165169

@@ -169,6 +173,7 @@ describe('TestCase', () => {
169173
onTestModuleCollected (example.test.ts)
170174
onTestModuleStart (example.test.ts)
171175
onTestCaseReady (example.test.ts) |single test case|
176+
onUserConsoleLog (example.test.ts) |single test case| > Test running!
172177
onTestCaseResult (example.test.ts) |single test case|
173178
onTestModuleEnd (example.test.ts)"
174179
`)
@@ -1141,9 +1146,14 @@ async function run(
11411146

11421147
class CustomReporter implements Reporter {
11431148
calls: string[] = []
1149+
ctx!: Vitest
11441150

11451151
constructor(private options: ReporterOptions = {}) {}
11461152

1153+
onInit(ctx: Vitest) {
1154+
this.ctx = ctx
1155+
}
1156+
11471157
onTestRunStart(specifications: ReadonlyArray<TestSpecification>) {
11481158
if (this.options.printTestRunEvents) {
11491159
this.calls.push(`onTestRunStart (${specifications.length} specifications)`)
@@ -1188,6 +1198,13 @@ class CustomReporter implements Reporter {
11881198
this.calls.push(`${padded(test, 'onTestCaseResult')} (${this.normalizeFilename(test.module)}) |${test.name}|`)
11891199
}
11901200

1201+
onUserConsoleLog(log: UserConsoleLog) {
1202+
const task = this.ctx.state.idMap.get(log.taskId!)
1203+
const test = task && this.ctx.state.getReportedEntity(task) as TestCase
1204+
1205+
this.calls.push(`${padded(test!, 'onUserConsoleLog')} (${this.normalizeFilename(test!.module)}) |${test!.name}| > ${log.content.replaceAll('\n', '')}`)
1206+
}
1207+
11911208
onHookStart(hook: ReportedHookContext) {
11921209
const module = hook.entity.type === 'module' ? hook.entity : hook.entity.module
11931210
const name = hook.entity.type !== 'module' ? ` |${hook.entity.name}|` : ''

0 commit comments

Comments
 (0)