( file: Suite, namePattern?: string | RegExp, testLocations?: number[] | undefined, testIds?: string[] | undefined, testTagsFilter?: ((testTags: string[]) => boolean) | undefined, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean, )
| 8 | * If any tasks been marked as `only`, mark all other tasks as `skip`. |
| 9 | */ |
| 10 | export function interpretTaskModes( |
| 11 | file: Suite, |
| 12 | namePattern?: string | RegExp, |
| 13 | testLocations?: number[] | undefined, |
| 14 | testIds?: string[] | undefined, |
| 15 | testTagsFilter?: ((testTags: string[]) => boolean) | undefined, |
| 16 | onlyMode?: boolean, |
| 17 | parentIsOnly?: boolean, |
| 18 | allowOnly?: boolean, |
| 19 | ): void { |
| 20 | const matchedLocations: number[] = [] |
| 21 | |
| 22 | const traverseSuite = (suite: Suite, parentIsOnly?: boolean, parentMatchedWithLocation?: boolean) => { |
| 23 | const suiteIsOnly = parentIsOnly || suite.mode === 'only' |
| 24 | |
| 25 | // Check if any tasks in this suite have `.only` - if so, only those should run |
| 26 | const hasSomeTasksOnly = onlyMode && suite.tasks.some( |
| 27 | t => t.mode === 'only' || (t.type === 'suite' && someTasksAreOnly(t)), |
| 28 | ) |
| 29 | |
| 30 | suite.tasks.forEach((t) => { |
| 31 | // Check if either the parent suite or the task itself are marked as included |
| 32 | // If there are tasks with `.only` in this suite, only include those (not all tasks from describe.only) |
| 33 | const includeTask = hasSomeTasksOnly |
| 34 | ? (t.mode === 'only' || (t.type === 'suite' && someTasksAreOnly(t))) |
| 35 | : (suiteIsOnly || t.mode === 'only') |
| 36 | if (onlyMode) { |
| 37 | if (t.type === 'suite' && (includeTask || someTasksAreOnly(t))) { |
| 38 | // Don't skip this suite |
| 39 | if (t.mode === 'only') { |
| 40 | checkAllowOnly(t, allowOnly) |
| 41 | t.mode = 'run' |
| 42 | } |
| 43 | } |
| 44 | else if (t.mode === 'run' && !includeTask) { |
| 45 | t.mode = 'skip' |
| 46 | } |
| 47 | else if (t.mode === 'only') { |
| 48 | checkAllowOnly(t, allowOnly) |
| 49 | t.mode = 'run' |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | let hasLocationMatch = parentMatchedWithLocation |
| 54 | // Match test location against provided locations, only run if present |
| 55 | // in `testLocations`. Note: if `includeTaskLocation` is not enabled, |
| 56 | // all test will be skipped. |
| 57 | if (testLocations !== undefined && testLocations.length !== 0) { |
| 58 | if (t.location && testLocations?.includes(t.location.line)) { |
| 59 | t.mode = 'run' |
| 60 | matchedLocations.push(t.location.line) |
| 61 | hasLocationMatch = true |
| 62 | } |
| 63 | else if (parentMatchedWithLocation) { |
| 64 | t.mode = 'run' |
| 65 | } |
| 66 | else if (t.type === 'test') { |
| 67 | t.mode = 'skip' |
no test coverage detected