1- import type { Custom , File , Task , TaskResultPack , Test } from '@vitest/runner'
1+ import type { Custom , File , Test } from '@vitest/runner'
22import type { Vitest } from '../core'
33import type { Reporter } from '../types/reporter'
4+ import type { HookOptions } from './task-parser'
45import { getTests } from '@vitest/runner/utils'
56import c from 'tinyrainbow'
67import { F_POINTER , F_TREE_NODE_END , F_TREE_NODE_MIDDLE } from './renderers/figures'
78import { formatProjectName , formatTime , formatTimeString , padSummaryTitle } from './renderers/utils'
89import { WindowRenderer } from './renderers/windowedRenderer'
10+ import { TaskParser } from './task-parser'
911
1012const DURATION_UPDATE_INTERVAL_MS = 100
1113const FINISHED_TEST_CLEANUP_TIME_MS = 1_000
@@ -23,14 +25,6 @@ interface Counter {
2325 todo : number
2426}
2527
26- interface HookOptions {
27- name : string
28- file : File
29- id : File [ 'id' ] | Test [ 'id' ]
30- type : Task [ 'type' ]
31-
32- }
33-
3428interface SlowTask {
3529 name : string
3630 visible : boolean
@@ -50,8 +44,7 @@ interface RunningTest extends Pick<Counter, 'total' | 'completed'> {
5044 * Reporter extension that renders summary and forwards all other logs above itself.
5145 * Intended to be used by other reporters, not as a standalone reporter.
5246 */
53- export class SummaryReporter implements Reporter {
54- private ctx ! : Vitest
47+ export class SummaryReporter extends TaskParser implements Reporter {
5548 private options ! : Options
5649 private renderer ! : WindowRenderer
5750
@@ -98,66 +91,6 @@ export class SummaryReporter implements Reporter {
9891 this . suites . total = ( paths || [ ] ) . length
9992 }
10093
101- onTaskUpdate ( packs : TaskResultPack [ ] ) {
102- const startingTestFiles : File [ ] = [ ]
103- const finishedTestFiles : File [ ] = [ ]
104-
105- const startingTests : ( Test | Custom ) [ ] = [ ]
106- const finishedTests : ( Test | Custom ) [ ] = [ ]
107-
108- const startingHooks : HookOptions [ ] = [ ]
109- const endingHooks : HookOptions [ ] = [ ]
110-
111- for ( const pack of packs ) {
112- const task = this . ctx . state . idMap . get ( pack [ 0 ] )
113-
114- if ( task ?. type === 'suite' && 'filepath' in task && task . result ?. state ) {
115- if ( task ?. result ?. state === 'run' ) {
116- startingTestFiles . push ( task )
117- }
118- else {
119- // Skipped tests are not reported, do it manually
120- for ( const test of getTests ( task ) ) {
121- if ( ! test . result || test . result ?. state === 'skip' ) {
122- finishedTests . push ( test )
123- }
124- }
125-
126- finishedTestFiles . push ( task . file )
127- }
128- }
129-
130- if ( task ?. type === 'test' || task ?. type === 'custom' ) {
131- if ( task . result ?. state === 'run' ) {
132- startingTests . push ( task )
133- }
134- else if ( task . result ?. hooks ?. afterEach !== 'run' ) {
135- finishedTests . push ( task )
136- }
137- }
138-
139- if ( task ?. result ?. hooks ) {
140- for ( const [ hook , state ] of Object . entries ( task . result . hooks ) ) {
141- if ( state === 'run' ) {
142- startingHooks . push ( { name : hook , file : task . file , id : task . id , type : task . type } )
143- }
144- else {
145- endingHooks . push ( { name : hook , file : task . file , id : task . id , type : task . type } )
146- }
147- }
148- }
149- }
150-
151- endingHooks . forEach ( hook => this . onHookEnd ( hook ) )
152- finishedTests . forEach ( test => this . onTestFinished ( test ) )
153- finishedTestFiles . forEach ( file => this . onTestFileFinished ( file ) )
154-
155- startingTestFiles . forEach ( file => this . onTestFilePrepare ( file ) )
156- startingTests . forEach ( test => this . onTestStart ( test ) )
157- startingHooks . forEach ( hook => this . onHookStart ( hook ) ,
158- )
159- }
160-
16194 onWatcherRerun ( ) {
16295 this . runningTests . clear ( )
16396 this . finishedTests . clear ( )
@@ -177,7 +110,7 @@ export class SummaryReporter implements Reporter {
177110 clearInterval ( this . durationInterval )
178111 }
179112
180- private onTestFilePrepare ( file : File ) {
113+ onTestFilePrepare ( file : File ) {
181114 if ( this . allFinishedTests . has ( file . id ) || this . runningTests . has ( file . id ) ) {
182115 return
183116 }
@@ -202,40 +135,7 @@ export class SummaryReporter implements Reporter {
202135 this . maxParallelTests = Math . max ( this . maxParallelTests , this . runningTests . size )
203136 }
204137
205- private getTestStats ( test : Test | Custom ) {
206- const file = test . file
207- let stats = this . runningTests . get ( file . id )
208-
209- if ( ! stats ) {
210- // It's possible that that test finished before it's preparation was even reported
211- this . onTestFilePrepare ( test . file )
212- stats = this . runningTests . get ( file . id ) !
213-
214- // It's also possible that this update came after whole test file was reported as finished
215- if ( ! stats ) {
216- return
217- }
218- }
219-
220- return stats
221- }
222-
223- private getHookStats ( { file, id, type } : HookOptions ) {
224- // Track slow running hooks only on verbose mode
225- if ( ! this . options . verbose ) {
226- return
227- }
228-
229- const stats = this . runningTests . get ( file . id )
230-
231- if ( ! stats ) {
232- return
233- }
234-
235- return type === 'suite' ? stats : stats ?. tests . get ( id )
236- }
237-
238- private onHookStart ( options : HookOptions ) {
138+ onHookStart ( options : HookOptions ) {
239139 const stats = this . getHookStats ( options )
240140
241141 if ( ! stats ) {
@@ -258,7 +158,7 @@ export class SummaryReporter implements Reporter {
258158 hook . onFinish = ( ) => clearTimeout ( timeout )
259159 }
260160
261- private onHookEnd ( options : HookOptions ) {
161+ onHookEnd ( options : HookOptions ) {
262162 const stats = this . getHookStats ( options )
263163
264164 if ( stats ?. hook ?. name !== options . name ) {
@@ -269,7 +169,7 @@ export class SummaryReporter implements Reporter {
269169 stats . hook . visible = false
270170 }
271171
272- private onTestStart ( test : Test | Custom ) {
172+ onTestStart ( test : Test | Custom ) {
273173 // Track slow running tests only on verbose mode
274174 if ( ! this . options . verbose ) {
275175 return
@@ -300,7 +200,7 @@ export class SummaryReporter implements Reporter {
300200 stats . tests . set ( test . id , slowTest )
301201 }
302202
303- private onTestFinished ( test : Test | Custom ) {
203+ onTestFinished ( test : Test | Custom ) {
304204 const stats = this . getTestStats ( test )
305205
306206 if ( ! stats ) {
@@ -324,7 +224,7 @@ export class SummaryReporter implements Reporter {
324224 }
325225 }
326226
327- private onTestFileFinished ( file : File ) {
227+ onTestFileFinished ( file : File ) {
328228 if ( this . allFinishedTests . has ( file . id ) ) {
329229 return
330230 }
@@ -362,6 +262,39 @@ export class SummaryReporter implements Reporter {
362262 }
363263 }
364264
265+ private getTestStats ( test : Test | Custom ) {
266+ const file = test . file
267+ let stats = this . runningTests . get ( file . id )
268+
269+ if ( ! stats ) {
270+ // It's possible that that test finished before it's preparation was even reported
271+ this . onTestFilePrepare ( test . file )
272+ stats = this . runningTests . get ( file . id ) !
273+
274+ // It's also possible that this update came after whole test file was reported as finished
275+ if ( ! stats ) {
276+ return
277+ }
278+ }
279+
280+ return stats
281+ }
282+
283+ private getHookStats ( { file, id, type } : HookOptions ) {
284+ // Track slow running hooks only on verbose mode
285+ if ( ! this . options . verbose ) {
286+ return
287+ }
288+
289+ const stats = this . runningTests . get ( file . id )
290+
291+ if ( ! stats ) {
292+ return
293+ }
294+
295+ return type === 'suite' ? stats : stats ?. tests . get ( id )
296+ }
297+
365298 private createSummary ( ) {
366299 const summary = [ '' ]
367300
0 commit comments