11import { relative } from 'pathe'
22import { processError } from '@vitest/utils/error'
3- import type { File } from './types'
3+ import type { File , SuiteHooks } from './types'
44import type { VitestRunner } from './types/runner'
55import { calculateSuiteHash , generateHash , interpretTaskModes , someTasksAreOnly } from './utils/collect'
6- import { clearCollectorContext , getDefaultSuite } from './suite'
6+ import { clearCollectorContext , createSuiteHooks , getDefaultSuite } from './suite'
77import { getHooks , setHooks } from './map'
88import { collectorContext } from './context'
99import { runSetupFiles } from './setup'
@@ -26,7 +26,9 @@ export async function collectTests(paths: string[], runner: VitestRunner): Promi
2626 tasks : [ ] ,
2727 meta : Object . create ( null ) ,
2828 projectName : config . name ,
29+ file : undefined ! ,
2930 }
31+ file . file = file
3032
3133 clearCollectorContext ( filepath , runner )
3234
@@ -41,24 +43,27 @@ export async function collectTests(paths: string[], runner: VitestRunner): Promi
4143
4244 const defaultTasks = await getDefaultSuite ( ) . collect ( file )
4345
44- setHooks ( file , getHooks ( defaultTasks ) )
46+ const fileHooks = createSuiteHooks ( )
47+ mergeHooks ( fileHooks , getHooks ( defaultTasks ) )
4548
4649 for ( const c of [ ...defaultTasks . tasks , ...collectorContext . tasks ] ) {
47- if ( c . type === 'test' ) {
48- file . tasks . push ( c )
49- }
50- else if ( c . type === 'custom' ) {
51- file . tasks . push ( c )
52- }
53- else if ( c . type === 'suite' ) {
50+ if ( c . type === 'test' || c . type === 'custom' || c . type === 'suite' ) {
5451 file . tasks . push ( c )
5552 }
5653 else if ( c . type === 'collector' ) {
5754 const suite = await c . collect ( file )
58- if ( suite . name || suite . tasks . length )
55+ if ( suite . name || suite . tasks . length ) {
56+ mergeHooks ( fileHooks , getHooks ( suite ) )
5957 file . tasks . push ( suite )
58+ }
59+ }
60+ else {
61+ // check that types are exhausted
62+ c satisfies never
6063 }
6164 }
65+
66+ setHooks ( file , fileHooks )
6267 file . collectDuration = now ( ) - collectStart
6368 }
6469 catch ( e ) {
@@ -74,8 +79,23 @@ export async function collectTests(paths: string[], runner: VitestRunner): Promi
7479 const hasOnlyTasks = someTasksAreOnly ( file )
7580 interpretTaskModes ( file , config . testNamePattern , hasOnlyTasks , false , config . allowOnly )
7681
82+ file . tasks . forEach ( ( task ) => {
83+ // task.suite refers to the internal default suite object
84+ // it should not be reported
85+ if ( task . suite ?. id === '' )
86+ delete task . suite
87+ } )
7788 files . push ( file )
7889 }
7990
8091 return files
8192}
93+
94+ function mergeHooks ( baseHooks : SuiteHooks , hooks : SuiteHooks ) : SuiteHooks {
95+ for ( const _key in hooks ) {
96+ const key = _key as keyof SuiteHooks
97+ baseHooks [ key ] . push ( ...hooks [ key ] as any )
98+ }
99+
100+ return baseHooks
101+ }
0 commit comments