[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

feat(runner): Add full names to tasks (#9087)

authored by

Raul Macarie and committed by
GitHub
(Nov 25, 2025, 2:50 PM +0100) 821aa200 2cc34e0d

+453 -9
+1 -1
packages/runner/src/collect.ts
··· 42 42 43 43 runner.onCollectStart?.(file) 44 44 45 - clearCollectorContext(filepath, runner) 45 + clearCollectorContext(file, runner) 46 46 47 47 try { 48 48 const setupFiles = toArray(config.setupFiles)
+19 -4
packages/runner/src/suite.ts
··· 38 38 import { getCurrentTest } from './test-state' 39 39 import { findTestFileStackTrace } from './utils' 40 40 import { createChainable } from './utils/chain' 41 + import { createTaskName } from './utils/tasks' 41 42 42 43 /** 43 44 * Creates a suite of tests, allowing for grouping and hierarchical organization of tests. ··· 213 214 } 214 215 215 216 export function clearCollectorContext( 216 - filepath: string, 217 + file: File, 217 218 currentRunner: VitestRunner, 218 219 ): void { 219 220 if (!defaultSuite) { 220 221 defaultSuite = createDefaultSuite(currentRunner) 221 222 } 223 + defaultSuite.file = file 222 224 runner = currentRunner 223 - currentTestFilepath = filepath 225 + currentTestFilepath = file.filepath 224 226 collectorContext.tasks.length = 0 225 227 defaultSuite.clear() 226 228 collectorContext.currentSuite = defaultSuite ··· 297 299 298 300 const task = function (name = '', options: TaskCustomOptions = {}) { 299 301 const timeout = options?.timeout ?? runner.config.testTimeout 302 + const currentSuite = collectorContext.currentSuite?.suite 300 303 const task: Test = { 301 304 id: '', 302 305 name, 303 - suite: collectorContext.currentSuite?.suite, 306 + fullName: createTaskName([ 307 + currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName, 308 + name, 309 + ]), 310 + fullTestName: createTaskName([currentSuite?.fullTestName, name]), 311 + suite: currentSuite, 304 312 each: options.each, 305 313 fails: options.fails, 306 314 context: undefined!, ··· 439 447 suiteOptions = { timeout: suiteOptions } 440 448 } 441 449 450 + const currentSuite = collectorContext.currentSuite?.suite 451 + 442 452 suite = { 443 453 id: '', 444 454 type: 'suite', 445 455 name, 446 - suite: collectorContext.currentSuite?.suite, 456 + fullName: createTaskName([ 457 + currentSuite?.fullName ?? collectorContext.currentSuite?.file?.fullName, 458 + name, 459 + ]), 460 + fullTestName: createTaskName([currentSuite?.fullTestName, name]), 461 + suite: currentSuite, 447 462 mode, 448 463 each, 449 464 file: undefined!,
+325
test/core/test/task-names.test.ts
··· 1 + /** 2 + * This test is self-referential - it validates its own structure and the structure of the tests defined below. 3 + * 4 + * The order and nesting of these test definitions MUST match the assertions, or the test will fail. The assertions use array indices (e.g., `task.file.tasks[0]`) to access specific tests, so reordering will break the test. 5 + * 6 + * If you need to modify this structure, update both the setup below AND the corresponding assertions above to maintain consistency. 7 + */ 8 + import type { RunnerTestSuite } from 'vitest' 9 + import { describe, test } from 'vitest' 10 + 11 + test('tasks have correct `fullName` and `fullTestName` properties', ({ expect, task }) => { 12 + // this test validates the structure defined at the bottom of this file. 13 + // 14 + // structure (must match setup at bottom): 15 + // 16 + // task-names.test.ts 17 + // ├─ [0] tasks have correct `fullName` and `fullTestName` properties (this test) 18 + // ├─ [1] creates new recipe 19 + // ├─ [2] searches by ingredient 20 + // ├─ [3] recipe management/ 21 + // │ ├─ [0] saves recipe 22 + // │ └─ [1] deletes recipe 23 + // └─ [4] meal planning/ 24 + // ├─ [0] generates weekly plan 25 + // ├─ [1] grocery lists/ 26 + // │ ├─ [0] calculates ingredients 27 + // │ ├─ [1] combines duplicate items 28 + // │ └─ [2] shopping/ 29 + // │ ├─ [0] marks items as purchased 30 + // │ └─ [1] estimates total cost 31 + // ├─ [2] exports calendar 32 + // └─ [3] nutrition tracking/ 33 + // ├─ [0] calculates daily calories 34 + // └─ [1] tracks macros 35 + 36 + // validate this test itself (task.file.tasks[0]) 37 + expect(task.suite).toBe(undefined) 38 + expect( 39 + task.fullName, 40 + ).toBe('test/task-names.test.ts > tasks have correct `fullName` and `fullTestName` properties') 41 + expect( 42 + task.fullTestName, 43 + ).toBe('tasks have correct `fullName` and `fullTestName` properties') 44 + 45 + expect(task.file.fullName).toBe('test/task-names.test.ts') 46 + expect(task.file.fullTestName).toBe(undefined) 47 + 48 + const thisTest = task.file.tasks[0] 49 + expect(thisTest.suite).toBe(undefined) 50 + expect(thisTest.fullName).toBe( 51 + 'test/task-names.test.ts > tasks have correct `fullName` and `fullTestName` properties', 52 + ) 53 + expect(thisTest.fullTestName).toBe( 54 + 'tasks have correct `fullName` and `fullTestName` properties', 55 + ) 56 + 57 + expect( 58 + task.file.tasks, 59 + ).toHaveLength(5) 60 + 61 + // top-level tests 62 + const createsRecipe = task.file.tasks[1] 63 + expect(createsRecipe.suite).toBe(undefined) 64 + expect(createsRecipe.fullName).toBe( 65 + 'test/task-names.test.ts > creates new recipe', 66 + ) 67 + expect(createsRecipe.fullTestName).toBe( 68 + 'creates new recipe', 69 + ) 70 + 71 + const searchIngredient = task.file.tasks[2] 72 + expect(searchIngredient.suite).toBe(undefined) 73 + expect(searchIngredient.fullName).toBe( 74 + 'test/task-names.test.ts > searches by ingredient', 75 + ) 76 + expect(searchIngredient.fullTestName).toBe( 77 + 'searches by ingredient', 78 + ) 79 + 80 + // single-level suite 81 + const recipeManagement = task.file.tasks[3] as RunnerTestSuite 82 + expect(recipeManagement.suite).toBe(undefined) 83 + expect(recipeManagement.fullName).toBe( 84 + 'test/task-names.test.ts > recipe management', 85 + ) 86 + expect(recipeManagement.fullTestName).toBe( 87 + 'recipe management', 88 + ) 89 + 90 + expect(recipeManagement.tasks).toHaveLength(2) 91 + 92 + const savesRecipe = recipeManagement.tasks[0] 93 + expect(savesRecipe.suite?.fullName).toBe( 94 + 'test/task-names.test.ts > recipe management', 95 + ) 96 + expect(savesRecipe.suite?.fullTestName).toBe( 97 + 'recipe management', 98 + ) 99 + expect(savesRecipe.fullName).toBe( 100 + 'test/task-names.test.ts > recipe management > saves recipe', 101 + ) 102 + expect(savesRecipe.fullTestName).toBe( 103 + 'recipe management > saves recipe', 104 + ) 105 + 106 + const deletesRecipe = recipeManagement.tasks[1] 107 + expect(deletesRecipe.suite?.fullName).toBe( 108 + 'test/task-names.test.ts > recipe management', 109 + ) 110 + expect(deletesRecipe.suite?.fullTestName).toBe( 111 + 'recipe management', 112 + ) 113 + expect(deletesRecipe.fullName).toBe( 114 + 'test/task-names.test.ts > recipe management > deletes recipe', 115 + ) 116 + expect(deletesRecipe.fullTestName).toBe( 117 + 'recipe management > deletes recipe', 118 + ) 119 + 120 + // nested suites with mixed patterns 121 + const mealPlanning = task.file.tasks[4] as RunnerTestSuite 122 + expect(mealPlanning.suite).toBe(undefined) 123 + expect(mealPlanning.fullName).toBe( 124 + 'test/task-names.test.ts > meal planning', 125 + ) 126 + expect(mealPlanning.fullTestName).toBe( 127 + 'meal planning', 128 + ) 129 + 130 + expect(mealPlanning.tasks).toHaveLength(4) 131 + 132 + const generatesPlan = mealPlanning.tasks[0] 133 + expect(generatesPlan.suite?.fullName).toBe( 134 + 'test/task-names.test.ts > meal planning', 135 + ) 136 + expect(generatesPlan.suite?.fullTestName).toBe( 137 + 'meal planning', 138 + ) 139 + expect(generatesPlan.fullName).toBe( 140 + 'test/task-names.test.ts > meal planning > generates weekly plan', 141 + ) 142 + expect(generatesPlan.fullTestName).toBe( 143 + 'meal planning > generates weekly plan', 144 + ) 145 + 146 + const groceryList = mealPlanning.tasks[1] as RunnerTestSuite 147 + expect(groceryList.suite?.fullName).toBe( 148 + 'test/task-names.test.ts > meal planning', 149 + ) 150 + expect(groceryList.suite?.fullTestName).toBe( 151 + 'meal planning', 152 + ) 153 + expect(groceryList.fullName).toBe( 154 + 'test/task-names.test.ts > meal planning > grocery lists', 155 + ) 156 + expect(groceryList.fullTestName).toBe( 157 + 'meal planning > grocery lists', 158 + ) 159 + 160 + expect(groceryList.tasks).toHaveLength(3) 161 + 162 + const calculatesIngredients = groceryList.tasks[0] 163 + expect(calculatesIngredients.suite?.fullName).toBe( 164 + 'test/task-names.test.ts > meal planning > grocery lists', 165 + ) 166 + expect(calculatesIngredients.suite?.fullTestName).toBe( 167 + 'meal planning > grocery lists', 168 + ) 169 + expect(calculatesIngredients.fullName).toBe( 170 + 'test/task-names.test.ts > meal planning > grocery lists > calculates ingredients', 171 + ) 172 + expect(calculatesIngredients.fullTestName).toBe( 173 + 'meal planning > grocery lists > calculates ingredients', 174 + ) 175 + 176 + const combinesItems = groceryList.tasks[1] 177 + expect(combinesItems.suite?.fullName).toBe( 178 + 'test/task-names.test.ts > meal planning > grocery lists', 179 + ) 180 + expect(combinesItems.suite?.fullTestName).toBe( 181 + 'meal planning > grocery lists', 182 + ) 183 + expect(combinesItems.fullName).toBe( 184 + 'test/task-names.test.ts > meal planning > grocery lists > combines duplicate items', 185 + ) 186 + expect(combinesItems.fullTestName).toBe( 187 + 'meal planning > grocery lists > combines duplicate items', 188 + ) 189 + 190 + const shopping = groceryList.tasks[2] as RunnerTestSuite 191 + expect(shopping.suite?.fullName).toBe( 192 + 'test/task-names.test.ts > meal planning > grocery lists', 193 + ) 194 + expect(shopping.suite?.fullTestName).toBe( 195 + 'meal planning > grocery lists', 196 + ) 197 + expect(shopping.fullName).toBe( 198 + 'test/task-names.test.ts > meal planning > grocery lists > shopping', 199 + ) 200 + expect(shopping.fullTestName).toBe( 201 + 'meal planning > grocery lists > shopping', 202 + ) 203 + 204 + expect(shopping.tasks).toHaveLength(2) 205 + 206 + const marksItemsPurchased = shopping.tasks[0] 207 + expect(marksItemsPurchased.suite?.fullName).toBe( 208 + 'test/task-names.test.ts > meal planning > grocery lists > shopping', 209 + ) 210 + expect(marksItemsPurchased.suite?.fullTestName).toBe( 211 + 'meal planning > grocery lists > shopping', 212 + ) 213 + expect(marksItemsPurchased.fullName).toBe( 214 + 'test/task-names.test.ts > meal planning > grocery lists > shopping > marks items as purchased', 215 + ) 216 + expect(marksItemsPurchased.fullTestName).toBe( 217 + 'meal planning > grocery lists > shopping > marks items as purchased', 218 + ) 219 + 220 + const estimatesTotalCost = shopping.tasks[1] 221 + expect(estimatesTotalCost.suite?.fullName).toBe( 222 + 'test/task-names.test.ts > meal planning > grocery lists > shopping', 223 + ) 224 + expect(estimatesTotalCost.suite?.fullTestName).toBe( 225 + 'meal planning > grocery lists > shopping', 226 + ) 227 + expect(estimatesTotalCost.fullName).toBe( 228 + 'test/task-names.test.ts > meal planning > grocery lists > shopping > estimates total cost', 229 + ) 230 + expect(estimatesTotalCost.fullTestName).toBe( 231 + 'meal planning > grocery lists > shopping > estimates total cost', 232 + ) 233 + 234 + const exportsCalendar = mealPlanning.tasks[2] 235 + expect(exportsCalendar.suite?.fullName).toBe( 236 + 'test/task-names.test.ts > meal planning', 237 + ) 238 + expect(exportsCalendar.suite?.fullTestName).toBe( 239 + 'meal planning', 240 + ) 241 + expect(exportsCalendar.fullName).toBe( 242 + 'test/task-names.test.ts > meal planning > exports calendar', 243 + ) 244 + expect(exportsCalendar.fullTestName).toBe( 245 + 'meal planning > exports calendar', 246 + ) 247 + 248 + const nutritionTracking = mealPlanning.tasks[3] as RunnerTestSuite 249 + expect(nutritionTracking.suite?.fullName).toBe( 250 + 'test/task-names.test.ts > meal planning', 251 + ) 252 + expect(nutritionTracking.suite?.fullTestName).toBe( 253 + 'meal planning', 254 + ) 255 + expect(nutritionTracking.fullName).toBe( 256 + 'test/task-names.test.ts > meal planning > nutrition tracking', 257 + ) 258 + expect(nutritionTracking.fullTestName).toBe( 259 + 'meal planning > nutrition tracking', 260 + ) 261 + 262 + expect(nutritionTracking.tasks).toHaveLength(2) 263 + 264 + const calculatesCalories = nutritionTracking.tasks[0] 265 + expect(calculatesCalories.suite?.fullName).toBe( 266 + 'test/task-names.test.ts > meal planning > nutrition tracking', 267 + ) 268 + expect(calculatesCalories.suite?.fullTestName).toBe( 269 + 'meal planning > nutrition tracking', 270 + ) 271 + expect(calculatesCalories.fullName).toBe( 272 + 'test/task-names.test.ts > meal planning > nutrition tracking > calculates daily calories', 273 + ) 274 + expect(calculatesCalories.fullTestName).toBe( 275 + 'meal planning > nutrition tracking > calculates daily calories', 276 + ) 277 + 278 + const tracksMacros = nutritionTracking.tasks[1] 279 + expect(tracksMacros.suite?.fullName).toBe( 280 + 'test/task-names.test.ts > meal planning > nutrition tracking', 281 + ) 282 + expect(tracksMacros.suite?.fullTestName).toBe( 283 + 'meal planning > nutrition tracking', 284 + ) 285 + expect(tracksMacros.fullName).toBe( 286 + 'test/task-names.test.ts > meal planning > nutrition tracking > tracks macros', 287 + ) 288 + expect(tracksMacros.fullTestName).toBe( 289 + 'meal planning > nutrition tracking > tracks macros', 290 + ) 291 + }) 292 + 293 + // setup 294 + 295 + // top-level tests 296 + test('creates new recipe') 297 + test('searches by ingredient') 298 + 299 + // single-level suite 300 + describe('recipe management', () => { 301 + test('saves recipe') 302 + test('deletes recipe') 303 + }) 304 + 305 + // nested suites with mixed patterns 306 + describe('meal planning', () => { 307 + test('generates weekly plan') 308 + 309 + describe('grocery lists', () => { 310 + test('calculates ingredients') 311 + test('combines duplicate items') 312 + 313 + describe('shopping', () => { 314 + test('marks items as purchased') 315 + test('estimates total cost') 316 + }) 317 + }) 318 + 319 + test('exports calendar') 320 + 321 + describe('nutrition tracking', () => { 322 + test('calculates daily calories') 323 + test('tracks macros') 324 + }) 325 + })
+24 -1
test/reporters/src/data.ts
··· 12 12 duration: 145.99284195899963, 13 13 } 14 14 15 + const suiteName = 'suite' 15 16 const suite: RunnerTestSuite = { 16 17 id: `${file.id}_0`, 17 18 type: 'suite', 18 - name: 'suite', 19 + name: suiteName, 20 + fullName: `${file.fullName} > ${suiteName}`, 21 + fullTestName: `${file.fullTestName} > ${suiteName}`, 19 22 mode: 'run', 20 23 meta: {}, 21 24 file, ··· 34 37 id: `${file.id}_1`, 35 38 type: 'test', 36 39 name: 'Math.sqrt()', 40 + fullName: `${suite.fullName} > Math.sqrt()`, 41 + fullTestName: `${suite.fullTestName} > Math.sqrt()`, 37 42 mode: 'run', 38 43 fails: undefined, 39 44 suite, ··· 75 80 id: `${suite.id}_0`, 76 81 type: 'test', 77 82 name: 'Math.sqrt()', 83 + fullName: `${suite.fullName} > Math.sqrt()`, 84 + fullTestName: `${suite.fullTestName} > Math.sqrt()`, 78 85 mode: 'run', 79 86 fails: undefined, 80 87 meta: {}, ··· 98 105 id: `${suite.id}_1`, 99 106 type: 'test', 100 107 name: 'JSON', 108 + fullName: `${suite.fullName} > JSON`, 109 + fullTestName: `${suite.fullTestName} > JSON`, 101 110 mode: 'run', 102 111 annotations: [], 103 112 artifacts: [], ··· 113 122 id: `${suite.id}_3`, 114 123 type: 'test', 115 124 name: 'async with timeout', 125 + fullName: `${suite.fullName} > async with timeout`, 126 + fullTestName: `${suite.fullTestName} > async with timeout`, 116 127 mode: 'skip', 117 128 suite, 118 129 fails: undefined, ··· 128 139 id: `${suite.id}_4`, 129 140 type: 'test', 130 141 name: 'timeout', 142 + fullName: `${suite.fullName} > timeout`, 143 + fullTestName: `${suite.fullTestName} > timeout`, 131 144 annotations: [], 132 145 artifacts: [], 133 146 mode: 'run', ··· 143 156 id: `${suite.id}_5`, 144 157 type: 'test', 145 158 name: 'callback setup success ', 159 + fullName: `${suite.fullName} > callback setup success `, 160 + fullTestName: `${suite.fullTestName} > callback setup success `, 146 161 mode: 'run', 147 162 suite, 148 163 fails: undefined, ··· 158 173 id: `${suite.id}_6`, 159 174 type: 'test', 160 175 name: 'callback test success ', 176 + fullName: `${suite.fullName} > callback test success `, 177 + fullTestName: `${suite.fullTestName} > callback test success `, 161 178 mode: 'run', 162 179 suite, 163 180 fails: undefined, ··· 173 190 id: `${suite.id}_7`, 174 191 type: 'test', 175 192 name: 'callback setup success done(false)', 193 + fullName: `${suite.fullName} > callback setup success done(false)`, 194 + fullTestName: `${suite.fullTestName} > callback setup success done(false)`, 176 195 mode: 'run', 177 196 suite, 178 197 fails: undefined, ··· 188 207 id: `${suite.id}_8`, 189 208 type: 'test', 190 209 name: 'callback test success done(false)', 210 + fullName: `${suite.fullName} > callback test success done(false)`, 211 + fullTestName: `${suite.fullTestName} > callback test success done(false)`, 191 212 mode: 'run', 192 213 suite, 193 214 fails: undefined, ··· 211 232 id: `${suite.id}_9`, 212 233 type: 'test', 213 234 name: 'todo test', 235 + fullName: `${suite.fullName} > todo test`, 236 + fullTestName: `${suite.fullTestName} > todo test`, 214 237 mode: 'todo', 215 238 suite, 216 239 timeout: 0,
+9 -2
test/reporters/tests/junit.test.ts
··· 10 10 test('calc the duration used by junit', () => { 11 11 const result: RunnerTaskResult = { state: 'pass', duration: 0 } 12 12 const file: RunnerTestFile = createFileTask('/test.ts', '/', 'test') 13 + const suiteName 14 + = 'suite' 13 15 const suite: RunnerTestSuite = { 14 16 id: '1_0', 15 17 type: 'suite', 16 - name: 'suite', 18 + name: suiteName, 19 + fullName: `${file.fullName} > ${suiteName}`, 20 + fullTestName: `${file.fullTestName} > ${suiteName}`, 17 21 mode: 'run', 18 22 tasks: [], 19 23 file, 20 24 meta: {}, 21 25 } 26 + const taskName = 'timeout' 22 27 const task: RunnerTestCase = { 23 28 id: '1_0_0', 24 29 type: 'test', 25 - name: 'timeout', 30 + name: taskName, 31 + fullName: `${suite.fullName} > ${suiteName}`, 32 + fullTestName: `${suite.fullTestName} > ${suiteName}`, 26 33 mode: 'run', 27 34 result, 28 35 annotations: [],
+2
test/reporters/tests/merge-reports.test.ts
··· 286 286 return { 287 287 type: 'test', 288 288 name, 289 + fullName: `${file.fullName} > ${name}`, 290 + fullTestName: `${file.fullTestName} > ${name}`, 289 291 id: `${file.id}_0`, 290 292 mode: 'run', 291 293 file,
+36
packages/runner/src/types/tasks.ts
··· 19 19 */ 20 20 name: string 21 21 /** 22 + * Full name including the file path, any parent suites, and this task's name. 23 + * 24 + * Uses ` > ` as the separator between levels. 25 + * 26 + * @example 27 + * // file 28 + * 'test/task-names.test.ts' 29 + * @example 30 + * // suite 31 + * 'test/task-names.test.ts > meal planning' 32 + * 'test/task-names.test.ts > meal planning > grocery lists' 33 + * @example 34 + * // test 35 + * 'test/task-names.test.ts > meal planning > grocery lists > calculates ingredients' 36 + */ 37 + fullName: string 38 + /** 39 + * Full name excluding the file path, including any parent suites and this task's name. `undefined` for file tasks. 40 + * 41 + * Uses ` > ` as the separator between levels. 42 + * 43 + * @example 44 + * // file 45 + * undefined 46 + * @example 47 + * // suite 48 + * 'meal planning' 49 + * 'meal planning > grocery lists' 50 + * @example 51 + * // test 52 + * 'meal planning > grocery lists > calculates ingredients' 53 + */ 54 + fullTestName?: string 55 + /** 22 56 * Task mode. 23 57 * - **skip**: task is skipped 24 58 * - **only**: only this task and other tasks with `only` mode will run ··· 291 325 * @experimental 292 326 */ 293 327 artifacts: TestArtifact[] 328 + fullTestName: string 294 329 } 295 330 296 331 export type Task = Test | Suite | File ··· 630 665 )[] 631 666 scoped: (fixtures: Fixtures<any, ExtraContext>) => void 632 667 fixtures: () => FixtureItem[] | undefined 668 + file?: File 633 669 suite?: Suite 634 670 task: (name: string, options?: TaskCustomOptions) => Test<ExtraContext> 635 671 collect: (file: File) => Promise<Suite>
+1
packages/runner/src/utils/collect.ts
··· 187 187 const file: File = { 188 188 id: generateFileHash(path, projectName), 189 189 name: path, 190 + fullName: path, 190 191 type: 'suite', 191 192 mode: 'queued', 192 193 filepath,
+1
packages/runner/src/utils/index.ts
··· 11 11 export { limitConcurrency } from './limit-concurrency' 12 12 export { partitionSuiteChildren } from './suite' 13 13 export { 14 + createTaskName, 14 15 getFullName, 15 16 getNames, 16 17 getSuites,
+4
packages/runner/src/utils/tasks.ts
··· 80 80 export function getTestName(task: Task, separator = ' > '): string { 81 81 return getNames(task).slice(1).join(separator) 82 82 } 83 + 84 + export function createTaskName(names: readonly (string | undefined)[], separator = ' > '): string { 85 + return names.filter(name => name !== undefined).join(separator) 86 + }
+7
packages/vitest/src/node/ast-collect.ts
··· 4 4 import { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping' 5 5 import { 6 6 calculateSuiteHash, 7 + createTaskName, 7 8 generateHash, 8 9 interpretTaskModes, 9 10 someTasksAreOnly, ··· 193 194 type: 'suite', 194 195 id: /* @__PURE__ */ generateHash(`${testFilepath}${project.config.name || ''}`), 195 196 name: testFilepath, 197 + fullName: testFilepath, 196 198 mode: 'run', 197 199 tasks: [], 198 200 start: 0, ··· 252 254 type: 'suite', 253 255 id: /* @__PURE__ */ generateHash(`${testFilepath}${options.name || ''}`), 254 256 name: testFilepath, 257 + fullName: testFilepath, 255 258 mode: 'run', 256 259 tasks: [], 257 260 start: ast.start, ··· 324 327 tasks: [], 325 328 mode, 326 329 name: definition.name, 330 + fullName: createTaskName([latestSuite.fullName, definition.name]), 331 + fullTestName: createTaskName([latestSuite.fullTestName, definition.name]), 327 332 end: definition.end, 328 333 start: definition.start, 329 334 location, ··· 343 348 mode, 344 349 context: {} as any, // not used on the server 345 350 name: definition.name, 351 + fullName: createTaskName([latestSuite.fullName, definition.name]), 352 + fullTestName: createTaskName([latestSuite.fullTestName, definition.name]), 346 353 end: definition.end, 347 354 start: definition.start, 348 355 location,
+6
packages/vitest/src/typecheck/collect.ts
··· 3 3 import type { TestProject } from '../node/project' 4 4 import { 5 5 calculateSuiteHash, 6 + createTaskName, 6 7 generateHash, 7 8 interpretTaskModes, 8 9 someTasksAreOnly, ··· 60 61 type: 'suite', 61 62 id: generateHash(`${testFilepath}${typecheckSubprojectName}`), 62 63 name: testFilepath, 64 + fullName: testFilepath, 63 65 mode: 'run', 64 66 tasks: [], 65 67 start: ast.start, ··· 185 187 tasks: [], 186 188 mode, 187 189 name: definition.name, 190 + fullName: createTaskName([lastSuite.fullName, definition.name]), 191 + fullTestName: createTaskName([lastSuite.fullTestName, definition.name]), 188 192 end: definition.end, 189 193 start: definition.start, 190 194 meta: { ··· 205 209 timeout: 0, 206 210 context: {} as any, // not used in typecheck 207 211 name: definition.name, 212 + fullName: createTaskName([lastSuite.fullName, definition.name]), 213 + fullTestName: createTaskName([lastSuite.fullTestName, definition.name]), 208 214 end: definition.end, 209 215 start: definition.start, 210 216 annotations: [],
+8
test/reporters/tests/__snapshots__/html.test.ts.snap
··· 9 9 "environmentLoad": 0, 10 10 "file": [Circular], 11 11 "filepath": "<rootDir>/test/reporters/fixtures/json-fail.test.ts", 12 + "fullName": "json-fail.test.ts", 12 13 "id": 0, 13 14 "importDurations": {}, 14 15 "meta": {}, ··· 28 29 "annotations": [], 29 30 "artifacts": [], 30 31 "file": [Circular], 32 + "fullName": "json-fail.test.ts > should fail", 33 + "fullTestName": "should fail", 31 34 "id": 0, 32 35 "location": { 33 36 "column": 1, ··· 129 132 "environmentLoad": 0, 130 133 "file": [Circular], 131 134 "filepath": "<rootDir>/test/reporters/fixtures/all-passing-or-skipped.test.ts", 135 + "fullName": "all-passing-or-skipped.test.ts", 132 136 "id": 0, 133 137 "importDurations": {}, 134 138 "meta": {}, ··· 148 152 "annotations": [], 149 153 "artifacts": [], 150 154 "file": [Circular], 155 + "fullName": "all-passing-or-skipped.test.ts > 2 + 3 = 5", 156 + "fullTestName": "2 + 3 = 5", 151 157 "id": 0, 152 158 "location": { 153 159 "column": 1, ··· 170 176 "annotations": [], 171 177 "artifacts": [], 172 178 "file": [Circular], 179 + "fullName": "all-passing-or-skipped.test.ts > 3 + 3 = 6", 180 + "fullTestName": "3 + 3 = 6", 173 181 "id": "1111755131_1", 174 182 "location": { 175 183 "column": 6,
+3
packages/ui/client/components/views/ViewReport.spec.ts
··· 48 48 type: 'suite', 49 49 mode: 'run', 50 50 filepath: 'test/plain-stack-trace.ts', 51 + fullName: 'test/plain-stack-trace.ts', 51 52 meta: {}, 52 53 result: { 53 54 state: 'fail', ··· 98 99 type: 'suite', 99 100 mode: 'run', 100 101 filepath: 'test/plain-stack-trace.ts', 102 + fullName: 'test/plain-stack-trace.ts', 101 103 meta: {}, 102 104 result: { 103 105 state: 'fail', ··· 157 159 type: 'suite', 158 160 mode: 'run', 159 161 filepath: 'test/plain-stack-trace.ts', 162 + fullName: 'test/plain-stack-trace.ts', 160 163 meta: {}, 161 164 result: { 162 165 state: 'fail',
+1
packages/ui/client/components/views/ViewReport.vue
··· 46 46 id: file!.id, 47 47 file: file!, 48 48 name: file!.name, 49 + fullName: file!.name, 49 50 level: 0, 50 51 type: 'suite', 51 52 mode: 'run',
+2
packages/vitest/src/node/reporters/junit.ts
··· 327 327 id: file.id, 328 328 type: 'test', 329 329 name: file.name, 330 + fullName: file.name, 331 + fullTestName: file.name, 330 332 mode: 'run', 331 333 result: file.result, 332 334 meta: {},
+4 -1
test/cli/fixtures/custom-pool/pool/custom-pool.ts
··· 83 83 ) 84 84 taskFile.mode = 'run' 85 85 taskFile.result = { state: 'pass' } 86 + const taskName = 'custom test' 86 87 const taskTest: RunnerTestCase = { 87 88 type: 'test', 88 - name: 'custom test', 89 + name: taskName, 90 + fullName: `${taskFile.fullName} > ${taskName}`, 91 + fullTestName: `${taskFile.fullTestName} > ${taskName}`, 89 92 id: `${taskFile.id}_0`, 90 93 context: {} as any, 91 94 suite: taskFile,