[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.

refactor(runner): add docs to @vitest/runner, remove barrel files (#6126)

authored by

Vladimir and committed by
GitHub
(Jul 15, 2024, 5:43 PM +0200) f1ef2f63 f55dc008

+593 -216
+3 -1
packages/pretty-format/tsconfig.json
··· 1 1 { 2 2 "extends": "../../tsconfig.base.json", 3 3 "compilerOptions": { 4 - "lib": ["ESNext", "DOM", "DOM.Iterable"] 4 + "lib": ["ESNext", "DOM", "DOM.Iterable"], 5 + "moduleResolution": "Bundler", 6 + "isolatedDeclarations": true 5 7 }, 6 8 "include": ["src/**/*"], 7 9 "exclude": ["**/dist/**"]
+1 -1
packages/runner/rollup.config.js
··· 17 17 const entries = { 18 18 index: 'src/index.ts', 19 19 utils: 'src/utils/index.ts', 20 - types: 'src/types/index.ts', 20 + types: 'src/types.ts', 21 21 } 22 22 23 23 const plugins = [
+6
packages/runner/tsconfig.json
··· 1 1 { 2 2 "extends": "../../tsconfig.base.json", 3 + "compilerOptions": { 4 + "target": "ESNext", 5 + "module": "ESNext", 6 + "moduleResolution": "Bundler", 7 + "isolatedDeclarations": true 8 + }, 3 9 "include": ["./src/**/*.ts"], 4 10 "exclude": ["./dist"] 5 11 }
+4
packages/utils/tsconfig.json
··· 1 1 { 2 2 "extends": "../../tsconfig.base.json", 3 + "compilerOptions": { 4 + "moduleResolution": "Bundler", 5 + "isolatedDeclarations": true 6 + }, 3 7 "include": ["src/**/*"], 4 8 "exclude": ["**/dist/**"] 5 9 }
+9 -2
packages/pretty-format/src/index.ts
··· 402 402 keyof typeof DEFAULT_THEME 403 403 > 404 404 405 - export const DEFAULT_OPTIONS = { 405 + export const DEFAULT_OPTIONS: Options = { 406 406 callToJSON: true, 407 407 compareKeys: undefined, 408 408 escapeRegex: false, ··· 528 528 return printComplexValue(val, getConfig(options), '', 0, []) 529 529 } 530 530 531 - export const plugins = { 531 + export const plugins: { 532 + AsymmetricMatcher: NewPlugin 533 + DOMCollection: NewPlugin 534 + DOMElement: NewPlugin 535 + Immutable: NewPlugin 536 + ReactElement: NewPlugin 537 + ReactTestComponent: NewPlugin 538 + } = { 532 539 AsymmetricMatcher, 533 540 DOMCollection, 534 541 DOMElement,
+1 -1
packages/runner/src/collect.ts
··· 1 1 import { processError } from '@vitest/utils/error' 2 - import type { File, SuiteHooks } from './types' 2 + import type { File, SuiteHooks } from './types/tasks' 3 3 import type { VitestRunner } from './types/runner' 4 4 import { 5 5 calculateSuiteHash,
+3 -3
packages/runner/src/context.ts
··· 7 7 SuiteCollector, 8 8 TaskContext, 9 9 Test, 10 - } from './types' 10 + } from './types/tasks' 11 11 import type { VitestRunner } from './types/runner' 12 12 import { PendingError } from './errors' 13 13 ··· 16 16 currentSuite: null, 17 17 } 18 18 19 - export function collectTask(task: SuiteCollector) { 19 + export function collectTask(task: SuiteCollector): void { 20 20 collectorContext.currentSuite?.tasks.push(task) 21 21 } 22 22 23 23 export async function runWithSuite( 24 24 suite: SuiteCollector, 25 25 fn: () => Awaitable<void>, 26 - ) { 26 + ): Promise<void> { 27 27 const prev = collectorContext.currentSuite 28 28 collectorContext.currentSuite = suite 29 29 await fn()
+1 -1
packages/runner/src/errors.ts
··· 1 - import type { TaskBase } from './types' 1 + import type { TaskBase } from './types/tasks' 2 2 3 3 export class PendingError extends Error { 4 4 public code = 'VITEST_PENDING'
+6 -4
packages/runner/src/fixture.ts
··· 1 1 import { createDefer, isObject } from '@vitest/utils' 2 2 import { getFixture } from './map' 3 - import type { FixtureOptions, TestContext } from './types' 3 + import type { FixtureOptions, TestContext } from './types/tasks' 4 4 5 5 export interface FixtureItem extends FixtureOptions { 6 6 prop: string ··· 18 18 export function mergeContextFixtures( 19 19 fixtures: Record<string, any>, 20 20 context: { fixtures?: FixtureItem[] } = {}, 21 - ) { 21 + ): { 22 + fixtures?: FixtureItem[] 23 + } { 22 24 const fixtureOptionKeys = ['auto'] 23 25 const fixtureArray: FixtureItem[] = Object.entries(fixtures).map( 24 26 ([prop, value]) => { ··· 69 71 Array<() => void | Promise<void>> 70 72 >() 71 73 72 - export async function callFixtureCleanup(context: TestContext) { 74 + export async function callFixtureCleanup(context: TestContext): Promise<void> { 73 75 const cleanupFnArray = cleanupFnArrayMap.get(context) ?? [] 74 76 for (const cleanup of cleanupFnArray.reverse()) { 75 77 await cleanup() ··· 78 80 } 79 81 80 82 export function withFixtures(fn: Function, testContext?: TestContext) { 81 - return (hookContext?: TestContext) => { 83 + return (hookContext?: TestContext): any => { 82 84 const context: (TestContext & { [key: string]: any }) | undefined 83 85 = hookContext || testContext 84 86
+130 -19
packages/runner/src/hooks.ts
··· 1 1 import type { 2 + AfterAllListener, 3 + AfterEachListener, 4 + BeforeAllListener, 5 + BeforeEachListener, 2 6 OnTestFailedHandler, 3 7 OnTestFinishedHandler, 4 - SuiteHooks, 8 + TaskHook, 5 9 TaskPopulated, 6 - } from './types' 10 + } from './types/tasks' 7 11 import { getCurrentSuite, getRunner } from './suite' 8 12 import { getCurrentTest } from './test-state' 9 13 import { withTimeout } from './context' ··· 13 17 return getRunner().config.hookTimeout 14 18 } 15 19 16 - // suite hooks 17 - export function beforeAll(fn: SuiteHooks['beforeAll'][0], timeout?: number) { 20 + /** 21 + * Registers a callback function to be executed once before all tests within the current suite. 22 + * This hook is useful for scenarios where you need to perform setup operations that are common to all tests in a suite, such as initializing a database connection or setting up a test environment. 23 + * 24 + * **Note:** The `beforeAll` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. 25 + * 26 + * @param {Function} fn - The callback function to be executed before all tests. 27 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 28 + * @returns {void} 29 + * 30 + * @example 31 + * // Example of using beforeAll to set up a database connection 32 + * beforeAll(async () => { 33 + * await database.connect(); 34 + * }); 35 + */ 36 + export function beforeAll(fn: BeforeAllListener, timeout?: number): void { 18 37 return getCurrentSuite().on( 19 38 'beforeAll', 20 39 withTimeout(fn, timeout ?? getDefaultHookTimeout(), true), 21 40 ) 22 41 } 23 - export function afterAll(fn: SuiteHooks['afterAll'][0], timeout?: number) { 42 + 43 + /** 44 + * Registers a callback function to be executed once after all tests within the current suite have completed. 45 + * This hook is useful for scenarios where you need to perform cleanup operations after all tests in a suite have run, such as closing database connections or cleaning up temporary files. 46 + * 47 + * **Note:** The `afterAll` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. 48 + * 49 + * @param {Function} fn - The callback function to be executed after all tests. 50 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 51 + * @returns {void} 52 + * 53 + * @example 54 + * // Example of using afterAll to close a database connection 55 + * afterAll(async () => { 56 + * await database.disconnect(); 57 + * }); 58 + */ 59 + export function afterAll(fn: AfterAllListener, timeout?: number): void { 24 60 return getCurrentSuite().on( 25 61 'afterAll', 26 62 withTimeout(fn, timeout ?? getDefaultHookTimeout(), true), 27 63 ) 28 64 } 65 + 66 + /** 67 + * Registers a callback function to be executed before each test within the current suite. 68 + * This hook is useful for scenarios where you need to reset or reinitialize the test environment before each test runs, such as resetting database states, clearing caches, or reinitializing variables. 69 + * 70 + * **Note:** The `beforeEach` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file. 71 + * 72 + * @param {Function} fn - The callback function to be executed before each test. This function receives an `TestContext` parameter if additional test context is needed. 73 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 74 + * @returns {void} 75 + * 76 + * @example 77 + * // Example of using beforeEach to reset a database state 78 + * beforeEach(async () => { 79 + * await database.reset(); 80 + * }); 81 + */ 29 82 export function beforeEach<ExtraContext = object>( 30 - fn: SuiteHooks<ExtraContext>['beforeEach'][0], 83 + fn: BeforeEachListener<ExtraContext>, 31 84 timeout?: number, 32 - ) { 85 + ): void { 33 86 return getCurrentSuite<ExtraContext>().on( 34 87 'beforeEach', 35 88 withTimeout(withFixtures(fn), timeout ?? getDefaultHookTimeout(), true), 36 89 ) 37 90 } 91 + 92 + /** 93 + * Registers a callback function to be executed after each test within the current suite has completed. 94 + * This hook is useful for scenarios where you need to clean up or reset the test environment after each test runs, such as deleting temporary files, clearing test-specific database entries, or resetting mocked functions. 95 + * 96 + * **Note:** The `afterEach` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. 97 + * 98 + * @param {Function} fn - The callback function to be executed after each test. This function receives an `TestContext` parameter if additional test context is needed. 99 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 100 + * @returns {void} 101 + * 102 + * @example 103 + * // Example of using afterEach to delete temporary files created during a test 104 + * afterEach(async () => { 105 + * await fileSystem.deleteTempFiles(); 106 + * }); 107 + */ 38 108 export function afterEach<ExtraContext = object>( 39 - fn: SuiteHooks<ExtraContext>['afterEach'][0], 109 + fn: AfterEachListener<ExtraContext>, 40 110 timeout?: number, 41 - ) { 111 + ): void { 42 112 return getCurrentSuite<ExtraContext>().on( 43 113 'afterEach', 44 114 withTimeout(withFixtures(fn), timeout ?? getDefaultHookTimeout(), true), 45 115 ) 46 116 } 47 117 48 - export const onTestFailed = createTestHook<OnTestFailedHandler>( 118 + /** 119 + * Registers a callback function to be executed when a test fails within the current suite. 120 + * This function allows for custom actions to be performed in response to test failures, such as logging, cleanup, or additional diagnostics. 121 + * 122 + * **Note:** The `onTestFailed` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. 123 + * 124 + * @param {Function} fn - The callback function to be executed upon a test failure. The function receives the test result (including errors). 125 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 126 + * @throws {Error} Throws an error if the function is not called within a test. 127 + * @returns {void} 128 + * 129 + * @example 130 + * // Example of using onTestFailed to log failure details 131 + * onTestFailed(({ errors }) => { 132 + * console.log(`Test failed: ${test.name}`, errors); 133 + * }); 134 + */ 135 + export const onTestFailed: TaskHook<OnTestFailedHandler> = createTestHook( 49 136 'onTestFailed', 50 - (test, handler) => { 137 + (test, handler, timeout) => { 51 138 test.onFailed ||= [] 52 - test.onFailed.push(handler) 139 + test.onFailed.push( 140 + withTimeout(handler, timeout ?? getDefaultHookTimeout(), true), 141 + ) 53 142 }, 54 143 ) 55 144 56 - export const onTestFinished = createTestHook<OnTestFinishedHandler>( 145 + /** 146 + * Registers a callback function to be executed when the current test finishes, regardless of the outcome (pass or fail). 147 + * This function is ideal for performing actions that should occur after every test execution, such as cleanup, logging, or resetting shared resources. 148 + * 149 + * This hook is useful if you have access to a resource in the test itself and you want to clean it up after the test finishes. It is a more compact way to clean up resources than using the combination of `beforeEach` and `afterEach`. 150 + * 151 + * **Note:** The `onTestFinished` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file. 152 + * 153 + * @param {Function} fn - The callback function to be executed after a test finishes. The function can receive parameters providing details about the completed test, including its success or failure status. 154 + * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used. 155 + * @throws {Error} Throws an error if the function is not called within a test. 156 + * @returns {void} 157 + * 158 + * @example 159 + * // Example of using onTestFinished for cleanup 160 + * const db = await connectToDatabase(); 161 + * onTestFinished(async () => { 162 + * await db.disconnect(); 163 + * }); 164 + */ 165 + export const onTestFinished: TaskHook<OnTestFinishedHandler> = createTestHook( 57 166 'onTestFinished', 58 - (test, handler) => { 167 + (test, handler, timeout) => { 59 168 test.onFinished ||= [] 60 - test.onFinished.push(handler) 169 + test.onFinished.push( 170 + withTimeout(handler, timeout ?? getDefaultHookTimeout(), true), 171 + ) 61 172 }, 62 173 ) 63 174 64 175 function createTestHook<T>( 65 176 name: string, 66 - handler: (test: TaskPopulated, handler: T) => void, 67 - ) { 68 - return (fn: T) => { 177 + handler: (test: TaskPopulated, handler: T, timeout?: number) => void, 178 + ): TaskHook<T> { 179 + return (fn: T, timeout?: number) => { 69 180 const current = getCurrentTest() 70 181 71 182 if (!current) { 72 183 throw new Error(`Hook ${name}() can only be called inside a test`) 73 184 } 74 185 75 - return handler(current, fn) 186 + return handler(current, fn, timeout) 76 187 } 77 188 }
+2 -1
packages/runner/src/index.ts
··· 18 18 export { setFn, getFn, getHooks, setHooks } from './map' 19 19 export { getCurrentTest } from './test-state' 20 20 export { processError } from '@vitest/utils/error' 21 - export * from './types' 21 + 22 + export type * from './types'
+4 -4
packages/runner/src/map.ts
··· 1 1 import type { Awaitable } from '@vitest/utils' 2 - import type { Custom, Suite, SuiteHooks, Test, TestContext } from './types' 2 + import type { Custom, Suite, SuiteHooks, Test, TestContext } from './types/tasks' 3 3 import type { FixtureItem } from './fixture' 4 4 5 5 // use WeakMap here to make the Test and Suite object serializable ··· 7 7 const fixtureMap = new WeakMap() 8 8 const hooksMap = new WeakMap() 9 9 10 - export function setFn(key: Test | Custom, fn: () => Awaitable<void>) { 10 + export function setFn(key: Test | Custom, fn: () => Awaitable<void>): void { 11 11 fnMap.set(key, fn) 12 12 } 13 13 ··· 18 18 export function setFixture( 19 19 key: TestContext, 20 20 fixture: FixtureItem[] | undefined, 21 - ) { 21 + ): void { 22 22 fixtureMap.set(key, fixture) 23 23 } 24 24 ··· 26 26 return fixtureMap.get(key as any) 27 27 } 28 28 29 - export function setHooks(key: Suite, hooks: SuiteHooks) { 29 + export function setHooks(key: Suite, hooks: SuiteHooks): void { 30 30 hooksMap.set(key, hooks) 31 31 } 32 32
+10 -11
packages/runner/src/run.ts
··· 17 17 TaskResultPack, 18 18 TaskState, 19 19 Test, 20 - } from './types' 20 + } from './types/tasks' 21 21 import { partitionSuiteChildren } from './utils/suite' 22 22 import { limitConcurrency } from './utils/limit-concurrency' 23 23 import { getFn, getHooks } from './map' ··· 90 90 91 91 const callbacks: HookCleanupCallback[] = [] 92 92 // stop at file level 93 - const parentSuite: Suite | null 94 - = 'filepath' in suite ? null : suite.suite || suite.file 93 + const parentSuite: Suite | null = 'filepath' in suite ? null : suite.suite || suite.file 95 94 96 95 if (name === 'beforeEach' && parentSuite) { 97 96 callbacks.push( ··· 105 104 106 105 if (sequence === 'parallel') { 107 106 callbacks.push( 108 - ...(await Promise.all(hooks.map(fn => fn(...(args as any))))), 107 + ...(await Promise.all(hooks.map(hook => (hook as any)(...args)))), 109 108 ) 110 109 } 111 110 else { 112 111 for (const hook of hooks) { 113 - callbacks.push(await hook(...(args as any))) 112 + callbacks.push(await (hook as any)(...args)) 114 113 } 115 114 } 116 115 ··· 129 128 let updateTimer: any 130 129 let previousUpdate: Promise<void> | undefined 131 130 132 - export function updateTask(task: Task, runner: VitestRunner) { 131 + export function updateTask(task: Task, runner: VitestRunner): void { 133 132 packs.set(task.id, [task.result, task.meta]) 134 133 135 134 const { clearTimeout, setTimeout } = getSafeTimers() ··· 166 165 ) 167 166 } 168 167 169 - export async function runTest(test: Test | Custom, runner: VitestRunner) { 168 + export async function runTest(test: Test | Custom, runner: VitestRunner): Promise<void> { 170 169 await runner.onBeforeRunTask?.(test) 171 170 172 171 if (test.mode !== 'run') { ··· 364 363 }) 365 364 } 366 365 367 - export async function runSuite(suite: Suite, runner: VitestRunner) { 366 + export async function runSuite(suite: Suite, runner: VitestRunner): Promise<void> { 368 367 await runner.onBeforeRunSuite?.(suite) 369 368 370 369 if (suite.result?.state === 'fail') { ··· 477 476 } 478 477 } 479 478 480 - export async function runFiles(files: File[], runner: VitestRunner) { 479 + export async function runFiles(files: File[], runner: VitestRunner): Promise<void> { 481 480 limitMaxConcurrency ??= limitConcurrency(runner.config.maxConcurrency) 482 481 483 482 for (const file of files) { ··· 496 495 } 497 496 } 498 497 499 - export async function startTests(paths: string[], runner: VitestRunner) { 498 + export async function startTests(paths: string[], runner: VitestRunner): Promise<File[]> { 500 499 await runner.onBeforeCollect?.(paths) 501 500 502 501 const files = await collectTests(paths, runner) ··· 513 512 return files 514 513 } 515 514 516 - async function publicCollect(paths: string[], runner: VitestRunner) { 515 + async function publicCollect(paths: string[], runner: VitestRunner): Promise<File[]> { 517 516 await runner.onBeforeCollect?.(paths) 518 517 519 518 const files = await collectTests(paths, runner)
+2 -2
packages/runner/src/setup.ts
··· 1 1 import { toArray } from '@vitest/utils' 2 - import type { VitestRunner, VitestRunnerConfig } from './types' 2 + import type { VitestRunner, VitestRunnerConfig } from './types/runner' 3 3 4 4 export async function runSetupFiles( 5 5 config: VitestRunnerConfig, 6 6 runner: VitestRunner, 7 - ) { 7 + ): Promise<void> { 8 8 const files = toArray(config.setupFiles) 9 9 if (config.sequence.setupFiles === 'parallel') { 10 10 await Promise.all(
+121 -13
packages/runner/src/suite.ts
··· 24 24 TestAPI, 25 25 TestFunction, 26 26 TestOptions, 27 - } from './types' 27 + } from './types/tasks' 28 28 import type { VitestRunner } from './types/runner' 29 29 import { createChainable } from './utils/chain' 30 30 import { ··· 39 39 import { mergeContextFixtures, withFixtures } from './fixture' 40 40 import { getCurrentTest } from './test-state' 41 41 42 - // apis 43 - export const suite = createSuite() 44 - export const test = createTest(function ( 42 + /** 43 + * Creates a suite of tests, allowing for grouping and hierarchical organization of tests. 44 + * Suites can contain both tests and other suites, enabling complex test structures. 45 + * 46 + * @param {string} name - The name of the suite, used for identification and reporting. 47 + * @param {Function} fn - A function that defines the tests and suites within this suite. 48 + * 49 + * @example 50 + * // Define a suite with two tests 51 + * suite('Math operations', () => { 52 + * test('should add two numbers', () => { 53 + * expect(add(1, 2)).toBe(3); 54 + * }); 55 + * 56 + * test('should subtract two numbers', () => { 57 + * expect(subtract(5, 2)).toBe(3); 58 + * }); 59 + * }); 60 + * 61 + * @example 62 + * // Define nested suites 63 + * suite('String operations', () => { 64 + * suite('Trimming', () => { 65 + * test('should trim whitespace from start and end', () => { 66 + * expect(' hello '.trim()).toBe('hello'); 67 + * }); 68 + * }); 69 + * 70 + * suite('Concatenation', () => { 71 + * test('should concatenate two strings', () => { 72 + * expect('hello' + ' ' + 'world').toBe('hello world'); 73 + * }); 74 + * }); 75 + * }); 76 + */ 77 + export const suite: SuiteAPI = createSuite() 78 + /** 79 + * Defines a test case with a given name and test function. The test function can optionally be configured with test options. 80 + * 81 + * @param {string | Function} name - The name of the test or a function that will be used as a test name. 82 + * @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. 83 + * @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. 84 + * @throws {Error} If called inside another test function. 85 + * 86 + * @example 87 + * // Define a simple test 88 + * test('should add two numbers', () => { 89 + * expect(add(1, 2)).toBe(3); 90 + * }); 91 + * 92 + * @example 93 + * // Define a test with options 94 + * test('should subtract two numbers', { retry: 3 }, () => { 95 + * expect(subtract(5, 2)).toBe(3); 96 + * }); 97 + */ 98 + export const test: TestAPI = createTest(function ( 45 99 name: string | Function, 46 100 optionsOrFn?: TestOptions | TestFunction, 47 101 optionsOrTest?: number | TestOptions | TestFunction, ··· 60 114 ) 61 115 }) 62 116 63 - // alias 64 - export const describe = suite 65 - export const it = test 117 + /** 118 + * Creates a suite of tests, allowing for grouping and hierarchical organization of tests. 119 + * Suites can contain both tests and other suites, enabling complex test structures. 120 + * 121 + * @param {string} name - The name of the suite, used for identification and reporting. 122 + * @param {Function} fn - A function that defines the tests and suites within this suite. 123 + * 124 + * @example 125 + * // Define a suite with two tests 126 + * describe('Math operations', () => { 127 + * test('should add two numbers', () => { 128 + * expect(add(1, 2)).toBe(3); 129 + * }); 130 + * 131 + * test('should subtract two numbers', () => { 132 + * expect(subtract(5, 2)).toBe(3); 133 + * }); 134 + * }); 135 + * 136 + * @example 137 + * // Define nested suites 138 + * describe('String operations', () => { 139 + * describe('Trimming', () => { 140 + * test('should trim whitespace from start and end', () => { 141 + * expect(' hello '.trim()).toBe('hello'); 142 + * }); 143 + * }); 144 + * 145 + * describe('Concatenation', () => { 146 + * test('should concatenate two strings', () => { 147 + * expect('hello' + ' ' + 'world').toBe('hello world'); 148 + * }); 149 + * }); 150 + * }); 151 + */ 152 + export const describe: SuiteAPI = suite 153 + /** 154 + * Defines a test case with a given name and test function. The test function can optionally be configured with test options. 155 + * 156 + * @param {string | Function} name - The name of the test or a function that will be used as a test name. 157 + * @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided. 158 + * @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters. 159 + * @throws {Error} If called inside another test function. 160 + * 161 + * @example 162 + * // Define a simple test 163 + * it('adds two numbers', () => { 164 + * expect(add(1, 2)).toBe(3); 165 + * }); 166 + * 167 + * @example 168 + * // Define a test with options 169 + * it('subtracts two numbers', { retry: 3 }, () => { 170 + * expect(subtract(5, 2)).toBe(3); 171 + * }); 172 + */ 173 + export const it: TestAPI = test 66 174 67 175 let runner: VitestRunner 68 176 let defaultSuite: SuiteCollector 69 177 let currentTestFilepath: string 70 178 71 - export function getDefaultSuite() { 179 + export function getDefaultSuite(): SuiteCollector<object> { 72 180 return defaultSuite 73 181 } 74 182 75 - export function getTestFilepath() { 183 + export function getTestFilepath(): string { 76 184 return currentTestFilepath 77 185 } 78 186 79 - export function getRunner() { 187 + export function getRunner(): VitestRunner { 80 188 return runner 81 189 } 82 190 ··· 89 197 export function clearCollectorContext( 90 198 filepath: string, 91 199 currentRunner: VitestRunner, 92 - ) { 200 + ): void { 93 201 if (!defaultSuite) { 94 202 defaultSuite = createDefaultSuite(currentRunner) 95 203 } ··· 105 213 || defaultSuite) as SuiteCollector<ExtraContext> 106 214 } 107 215 108 - export function createSuiteHooks() { 216 + export function createSuiteHooks(): SuiteHooks { 109 217 return { 110 218 beforeAll: [], 111 219 afterAll: [], ··· 468 576 export function createTaskCollector( 469 577 fn: (...args: any[]) => any, 470 578 context?: Record<string, unknown>, 471 - ) { 579 + ): CustomAPI { 472 580 const taskFn = fn as any 473 581 474 582 taskFn.each = function <T>(
+2 -2
packages/runner/src/test-state.ts
··· 1 - import type { Custom, Test } from './types' 1 + import type { Custom, Test } from './types/tasks.ts' 2 2 3 3 let _test: Test | Custom | undefined 4 4 5 - export function setCurrentTest<T extends Test | Custom>(test: T | undefined) { 5 + export function setCurrentTest<T extends Test | Custom>(test: T | undefined): void { 6 6 _test = test 7 7 } 8 8
+52
packages/runner/src/types.ts
··· 1 + export type { 2 + RunMode, 3 + TaskState, 4 + TaskBase, 5 + TaskPopulated, 6 + TaskMeta, 7 + TaskResult, 8 + TaskResultPack, 9 + Suite, 10 + File, 11 + Test, 12 + Custom, 13 + Task, 14 + DoneCallback, 15 + TestFunction, 16 + TestOptions, 17 + CustomAPI, 18 + TestAPI, 19 + FixtureOptions, 20 + Use, 21 + FixtureFn, 22 + Fixture, 23 + Fixtures, 24 + InferFixturesTypes, 25 + SuiteAPI, 26 + HookListener, 27 + HookCleanupCallback, 28 + SuiteHooks, 29 + TaskCustomOptions, 30 + SuiteCollector, 31 + SuiteFactory, 32 + RuntimeContext, 33 + TestContext, 34 + TaskContext, 35 + ExtendedContext, 36 + OnTestFailedHandler, 37 + OnTestFinishedHandler, 38 + SequenceHooks, 39 + SequenceSetupFiles, 40 + AfterAllListener, 41 + AfterEachListener, 42 + BeforeAllListener, 43 + BeforeEachListener, 44 + TaskHook, 45 + } from './types/tasks' 46 + export type { 47 + VitestRunnerConfig, 48 + VitestRunnerImportSource, 49 + VitestRunnerConstructor, 50 + CancelReason, 51 + VitestRunner, 52 + } from './types/runner'
-22
packages/utils/src/base.ts
··· 1 - interface ErrorOptions { 2 - message?: string 3 - stackTraceLimit?: number 4 - } 5 - /** 6 - * Get original stacktrace without source map support the most performant way. 7 - * - Create only 1 stack frame. 8 - * - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). 9 - */ 10 - export function createSimpleStackTrace(options?: ErrorOptions) { 11 - const { message = '$$stack trace error', stackTraceLimit = 1 } 12 - = options || {} 13 - const limit = Error.stackTraceLimit 14 - const prepareStackTrace = Error.prepareStackTrace 15 - Error.stackTraceLimit = stackTraceLimit 16 - Error.prepareStackTrace = e => e.stack 17 - const err = new Error(message) 18 - const stackTrace = err.stack || '' 19 - Error.prepareStackTrace = prepareStackTrace 20 - Error.stackTraceLimit = limit 21 - return stackTrace 22 - }
-2
packages/utils/src/constants.ts
··· 1 - export const SAFE_TIMERS_SYMBOL = Symbol('vitest:SAFE_TIMERS') 2 - export const SAFE_COLORS_SYMBOL = Symbol('vitest:SAFE_COLORS')
+57 -1
packages/utils/src/display.ts
··· 1 1 // since this is already part of Vitest via Chai, we can just reuse it without increasing the size of bundle 2 2 import * as loupe from 'loupe' 3 + import type { PrettyFormatOptions } from '@vitest/pretty-format' 4 + import { 5 + format as prettyFormat, 6 + plugins as prettyFormatPlugins, 7 + } from '@vitest/pretty-format' 3 8 4 9 type Inspect = (value: unknown, options: Options) => string 5 10 interface Options { ··· 18 23 19 24 type LoupeOptions = Partial<Options> 20 25 26 + const { 27 + AsymmetricMatcher, 28 + DOMCollection, 29 + DOMElement, 30 + Immutable, 31 + ReactElement, 32 + ReactTestComponent, 33 + } = prettyFormatPlugins 34 + 35 + const PLUGINS = [ 36 + ReactTestComponent, 37 + ReactElement, 38 + DOMElement, 39 + DOMCollection, 40 + Immutable, 41 + AsymmetricMatcher, 42 + ] 43 + 44 + export function stringify( 45 + object: unknown, 46 + maxDepth = 10, 47 + { maxLength, ...options }: PrettyFormatOptions & { maxLength?: number } = {}, 48 + ): string { 49 + const MAX_LENGTH = maxLength ?? 10000 50 + let result 51 + 52 + try { 53 + result = prettyFormat(object, { 54 + maxDepth, 55 + escapeString: false, 56 + // min: true, 57 + plugins: PLUGINS, 58 + ...options, 59 + }) 60 + } 61 + catch { 62 + result = prettyFormat(object, { 63 + callToJSON: false, 64 + maxDepth, 65 + escapeString: false, 66 + // min: true, 67 + plugins: PLUGINS, 68 + ...options, 69 + }) 70 + } 71 + 72 + return result.length >= MAX_LENGTH && maxDepth > 1 73 + ? stringify(object, Math.floor(maxDepth / 2)) 74 + : result 75 + } 76 + 21 77 const formatRegExp = /%[sdjifoOc%]/g 22 78 23 - export function format(...args: unknown[]) { 79 + export function format(...args: unknown[]): string { 24 80 if (typeof args[0] !== 'string') { 25 81 const objects = [] 26 82 for (let i = 0; i < args.length; i++) {
+10 -8
packages/utils/src/error.ts
··· 1 1 import { type DiffOptions, diff } from './diff' 2 - import { format } from './display' 2 + import { format, stringify } from './display' 3 3 import { deepClone, getOwnProperties, getType } from './helpers' 4 - import { stringify } from './stringify' 5 4 6 5 // utils is bundled for any environment and might not support `Element` 7 6 declare class Element { ··· 28 27 } 29 28 30 29 // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm 31 - export function serializeError(val: any, seen = new WeakMap()): any { 30 + export function serializeError(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any { 32 31 if (!val || typeof val === 'string') { 33 32 return val 34 33 } ··· 113 112 export function processError( 114 113 err: any, 115 114 diffOptions?: DiffOptions, 116 - seen = new WeakSet(), 117 - ) { 115 + seen: WeakSet<WeakKey> = new WeakSet(), 116 + ): any { 118 117 if (!err || typeof err !== 'object') { 119 118 return { message: err } 120 119 } ··· 199 198 export function replaceAsymmetricMatcher( 200 199 actual: any, 201 200 expected: any, 202 - actualReplaced = new WeakSet(), 203 - expectedReplaced = new WeakSet(), 204 - ) { 201 + actualReplaced: WeakSet<WeakKey> = new WeakSet(), 202 + expectedReplaced: WeakSet<WeakKey> = new WeakSet(), 203 + ): { 204 + replacedActual: any 205 + replacedExpected: any 206 + } { 205 207 if (!isReplaceable(actual, expected)) { 206 208 return { replacedActual: actual, replacedExpected: expected } 207 209 }
+31 -7
packages/utils/src/helpers.ts
··· 4 4 forceWritable?: boolean 5 5 } 6 6 7 + interface ErrorOptions { 8 + message?: string 9 + stackTraceLimit?: number 10 + } 11 + 12 + /** 13 + * Get original stacktrace without source map support the most performant way. 14 + * - Create only 1 stack frame. 15 + * - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). 16 + */ 17 + export function createSimpleStackTrace(options?: ErrorOptions): string { 18 + const { message = '$$stack trace error', stackTraceLimit = 1 } 19 + = options || {} 20 + const limit = Error.stackTraceLimit 21 + const prepareStackTrace = Error.prepareStackTrace 22 + Error.stackTraceLimit = stackTraceLimit 23 + Error.prepareStackTrace = e => e.stack 24 + const err = new Error(message) 25 + const stackTrace = err.stack || '' 26 + Error.prepareStackTrace = prepareStackTrace 27 + Error.stackTraceLimit = limit 28 + return stackTrace 29 + } 30 + 7 31 export function notNullish<T>(v: T | null | undefined): v is NonNullable<T> { 8 32 return v != null 9 33 } ··· 22 46 } 23 47 } 24 48 25 - export function isPrimitive(value: unknown) { 49 + export function isPrimitive(value: unknown): boolean { 26 50 return ( 27 51 value === null || (typeof value !== 'function' && typeof value !== 'object') 28 52 ) 29 53 } 30 54 31 - export function slash(path: string) { 55 + export function slash(path: string): string { 32 56 return path.replace(/\\/g, '/') 33 57 } 34 58 ··· 93 117 Object.getOwnPropertySymbols(obj).forEach(collect) 94 118 } 95 119 96 - export function getOwnProperties(obj: any) { 120 + export function getOwnProperties(obj: any): (string | symbol)[] { 97 121 const ownProps = new Set<string | symbol>() 98 122 if (isFinalObj(obj)) { 99 123 return [] ··· 170 194 return val 171 195 } 172 196 173 - export function noop() {} 197 + export function noop(): void {} 174 198 175 199 export function objectAttr( 176 200 source: any, 177 201 path: string, 178 202 defaultValue = undefined, 179 - ) { 203 + ): any { 180 204 // a[3].b -> a.3.b 181 205 const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.') 182 206 let result = source ··· 217 241 * toBeAliased('123') 218 242 * ``` 219 243 */ 220 - export function getCallLastIndex(code: string) { 244 + export function getCallLastIndex(code: string): number | null { 221 245 let charIndex = -1 222 246 let inString: string | null = null 223 247 let startedBracers = 0 ··· 255 279 return null 256 280 } 257 281 258 - export function isNegativeNaN(val: number) { 282 + export function isNegativeNaN(val: number): boolean { 259 283 if (!Number.isNaN(val)) { 260 284 return false 261 285 }
+1 -1
packages/utils/src/highlight.ts
··· 39 39 export function highlight( 40 40 code: string, 41 41 options: HighlightOptions = { jsx: false }, 42 - ) { 42 + ): string { 43 43 return baseHighlight(code, { 44 44 jsx: options.jsx, 45 45 colors: getDefs(options.colors || c),
+50 -10
packages/utils/src/index.ts
··· 1 - export * from './helpers' 2 - export * from './types' 3 - export * from './stringify' 4 - export * from './timers' 5 - export * from './random' 6 - export * from './display' 7 - export * from './constants' 8 - export * from './base' 9 - export * from './offset' 10 - export * from './highlight' 1 + export { 2 + notNullish, 3 + assertTypes, 4 + isPrimitive, 5 + slash, 6 + parseRegexp, 7 + isObject, 8 + getType, 9 + getOwnProperties, 10 + deepClone, 11 + clone, 12 + noop, 13 + objectAttr, 14 + createDefer, 15 + getCallLastIndex, 16 + isNegativeNaN, 17 + createSimpleStackTrace, 18 + toArray, 19 + } from './helpers' 20 + export type { DeferPromise } from './helpers' 21 + 22 + export { getSafeTimers, setSafeTimers } from './timers' 23 + export type { SafeTimers } from './timers' 24 + 25 + export { shuffle } from './random' 26 + export { 27 + stringify, 28 + format, 29 + inspect, 30 + objDisplay, 31 + } from './display' 32 + export { 33 + positionToOffset, 34 + offsetToLineNumber, 35 + lineSplitRE, 36 + } from './offset' 37 + export { highlight } from './highlight' 38 + 39 + export type { 40 + Awaitable, 41 + Nullable, 42 + Arrayable, 43 + ArgumentsType, 44 + MergeInsertions, 45 + DeepMerge, 46 + MutableArray, 47 + Constructable, 48 + ParsedStack, 49 + ErrorWithDiff, 50 + } from './types'
+1 -1
packages/utils/src/offset.ts
··· 1 - export const lineSplitRE = /\r?\n/ 1 + export const lineSplitRE: RegExp = /\r?\n/ 2 2 3 3 export function positionToOffset( 4 4 source: string,
+1 -1
packages/utils/src/random.ts
··· 5 5 return x - Math.floor(x) 6 6 } 7 7 8 - export function shuffle<T>(array: T[], seed = RealDate.now()): T[] { 8 + export function shuffle<T>(array: T[], seed: number = RealDate.now()): T[] { 9 9 let length = array.length 10 10 11 11 while (length) {
+1 -1
packages/utils/src/source-map.ts
··· 107 107 } 108 108 } 109 109 110 - export function parseSingleStack(raw: string) { 110 + export function parseSingleStack(raw: string): ParsedStack | null { 111 111 const line = raw.trim() 112 112 if (!CHROME_IE_STACK_REGEXP.test(line)) { 113 113 return parseSingleFFOrSafariStack(line)
-56
packages/utils/src/stringify.ts
··· 1 - import type { PrettyFormatOptions } from '@vitest/pretty-format' 2 - import { 3 - format as prettyFormat, 4 - plugins as prettyFormatPlugins, 5 - } from '@vitest/pretty-format' 6 - 7 - const { 8 - AsymmetricMatcher, 9 - DOMCollection, 10 - DOMElement, 11 - Immutable, 12 - ReactElement, 13 - ReactTestComponent, 14 - } = prettyFormatPlugins 15 - 16 - const PLUGINS = [ 17 - ReactTestComponent, 18 - ReactElement, 19 - DOMElement, 20 - DOMCollection, 21 - Immutable, 22 - AsymmetricMatcher, 23 - ] 24 - 25 - export function stringify( 26 - object: unknown, 27 - maxDepth = 10, 28 - { maxLength, ...options }: PrettyFormatOptions & { maxLength?: number } = {}, 29 - ): string { 30 - const MAX_LENGTH = maxLength ?? 10000 31 - let result 32 - 33 - try { 34 - result = prettyFormat(object, { 35 - maxDepth, 36 - escapeString: false, 37 - // min: true, 38 - plugins: PLUGINS, 39 - ...options, 40 - }) 41 - } 42 - catch { 43 - result = prettyFormat(object, { 44 - callToJSON: false, 45 - maxDepth, 46 - escapeString: false, 47 - // min: true, 48 - plugins: PLUGINS, 49 - ...options, 50 - }) 51 - } 52 - 53 - return result.length >= MAX_LENGTH && maxDepth > 1 54 - ? stringify(object, Math.floor(maxDepth / 2)) 55 - : result 56 - }
+13 -3
packages/utils/src/timers.ts
··· 1 - import { SAFE_TIMERS_SYMBOL } from './constants' 1 + const SAFE_TIMERS_SYMBOL = Symbol('vitest:SAFE_TIMERS') 2 2 3 - export function getSafeTimers() { 3 + export interface SafeTimers { 4 + nextTick: (cb: () => void) => void 5 + setTimeout: typeof setTimeout 6 + setInterval: typeof setInterval 7 + clearInterval: typeof clearInterval 8 + clearTimeout: typeof clearTimeout 9 + setImmediate: typeof setImmediate 10 + clearImmediate: typeof clearImmediate 11 + } 12 + 13 + export function getSafeTimers(): SafeTimers { 4 14 const { 5 15 setTimeout: safeSetTimeout, 6 16 setInterval: safeSetInterval, ··· 24 34 } 25 35 } 26 36 27 - export function setSafeTimers() { 37 + export function setSafeTimers(): void { 28 38 const { 29 39 setTimeout: safeSetTimeout, 30 40 setInterval: safeSetInterval,
-2
packages/runner/src/types/index.ts
··· 1 - export * from './tasks' 2 - export * from './runner'
+33 -9
packages/runner/src/types/tasks.ts
··· 360 360 runIf: (condition: any) => ChainableSuiteAPI<ExtraContext> 361 361 } 362 362 363 + /** 364 + * @deprecated 365 + */ 363 366 export type HookListener<T extends any[], Return = void> = ( 364 367 ...args: T 365 368 ) => Awaitable<Return> 366 369 367 370 export type HookCleanupCallback = (() => Awaitable<unknown>) | void 368 371 372 + export interface BeforeAllListener { 373 + (suite: Readonly<Suite | File>): Awaitable<HookCleanupCallback> 374 + } 375 + 376 + export interface AfterAllListener { 377 + (suite: Readonly<Suite | File>): Awaitable<void> 378 + } 379 + 380 + export interface BeforeEachListener<ExtraContext = object> { 381 + ( 382 + context: ExtendedContext<Test | Custom> & ExtraContext, 383 + suite: Readonly<Suite> 384 + ): Awaitable<HookCleanupCallback> 385 + } 386 + 387 + export interface AfterEachListener<ExtraContext = object> { 388 + ( 389 + context: ExtendedContext<Test | Custom> & ExtraContext, 390 + suite: Readonly<Suite> 391 + ): Awaitable<void> 392 + } 393 + 369 394 export interface SuiteHooks<ExtraContext = object> { 370 - beforeAll: HookListener<[Readonly<Suite | File>], HookCleanupCallback>[] 371 - afterAll: HookListener<[Readonly<Suite | File>]>[] 372 - beforeEach: HookListener< 373 - [ExtendedContext<Test | Custom> & ExtraContext, Readonly<Suite>], 374 - HookCleanupCallback 375 - >[] 376 - afterEach: HookListener< 377 - [ExtendedContext<Test | Custom> & ExtraContext, Readonly<Suite>] 378 - >[] 395 + beforeAll: BeforeAllListener[] 396 + afterAll: AfterAllListener[] 397 + beforeEach: BeforeEachListener<ExtraContext>[] 398 + afterEach: AfterEachListener<ExtraContext>[] 379 399 } 380 400 381 401 export interface TaskCustomOptions extends TestOptions { ··· 450 470 451 471 export type OnTestFailedHandler = (result: TaskResult) => Awaitable<void> 452 472 export type OnTestFinishedHandler = (result: TaskResult) => Awaitable<void> 473 + 474 + export interface TaskHook<HookListener> { 475 + (fn: HookListener, timeout?: number): void 476 + } 453 477 454 478 export type SequenceHooks = 'stack' | 'list' | 'parallel' 455 479 export type SequenceSetupFiles = 'list' | 'parallel'
+4 -4
packages/runner/src/utils/collect.ts
··· 1 1 import { processError } from '@vitest/utils/error' 2 2 import { relative } from 'pathe' 3 - import type { File, Suite, TaskBase } from '../types' 3 + import type { File, Suite, TaskBase } from '../types/tasks' 4 4 5 5 /** 6 6 * If any tasks been marked as `only`, mark all other tasks as `skip`. ··· 11 11 onlyMode?: boolean, 12 12 parentIsOnly?: boolean, 13 13 allowOnly?: boolean, 14 - ) { 14 + ): void { 15 15 const suiteIsOnly = parentIsOnly || suite.mode === 'only' 16 16 17 17 suite.tasks.forEach((t) => { ··· 105 105 return `${hash}` 106 106 } 107 107 108 - export function calculateSuiteHash(parent: Suite) { 108 + export function calculateSuiteHash(parent: Suite): void { 109 109 parent.tasks.forEach((t, idx) => { 110 110 t.id = `${parent.id}_${idx}` 111 111 if (t.type === 'suite') { ··· 119 119 root: string, 120 120 projectName: string, 121 121 pool?: string, 122 - ) { 122 + ): File { 123 123 const path = relative(root, filepath) 124 124 const file: File = { 125 125 id: generateHash(`${path}${projectName || ''}`),
+19 -5
packages/runner/src/utils/index.ts
··· 1 - export * from './collect' 2 - export * from './suite' 3 - export * from './tasks' 4 - export * from './chain' 5 - export * from './limit-concurrency' 1 + export { 2 + interpretTaskModes, 3 + someTasksAreOnly, 4 + generateHash, 5 + calculateSuiteHash, 6 + createFileTask, 7 + } from './collect' 8 + export { partitionSuiteChildren } from './suite' 9 + export { 10 + isAtomTest, 11 + getTests, 12 + getTasks, 13 + getSuites, 14 + hasTests, 15 + hasFailed, 16 + getNames, 17 + } from './tasks' 18 + export { createChainable, type ChainableFunction } from './chain' 19 + export { limitConcurrency } from './limit-concurrency'
+1 -1
packages/runner/src/utils/limit-concurrency.ts
··· 4 4 /** 5 5 * Return a function for running multiple async operations with limited concurrency. 6 6 */ 7 - export function limitConcurrency(concurrency = Infinity): <Args extends unknown[], T>(func: (...args: Args) => PromiseLike<T> | T, ...args: Args) => Promise<T> { 7 + export function limitConcurrency(concurrency: number = Infinity): <Args extends unknown[], T>(func: (...args: Args) => PromiseLike<T> | T, ...args: Args) => Promise<T> { 8 8 // The number of currently active + pending tasks. 9 9 let count = 0 10 10
+2 -2
packages/runner/src/utils/suite.ts
··· 1 - import type { Suite, Task } from '../types' 1 + import type { Suite, Task } from '../types/tasks' 2 2 3 3 /** 4 4 * Partition in tasks groups by consecutive concurrent 5 5 */ 6 - export function partitionSuiteChildren(suite: Suite) { 6 + export function partitionSuiteChildren(suite: Suite): Task[][] { 7 7 let tasksGroup: Task[] = [] 8 8 const tasksGroups: Task[][] = [] 9 9 for (const c of suite.tasks) {
+2 -2
packages/runner/src/utils/tasks.ts
··· 1 1 import { type Arrayable, toArray } from '@vitest/utils' 2 - import type { Custom, Suite, Task, Test } from '../types' 2 + import type { Custom, Suite, Task, Test } from '../types/tasks' 3 3 4 4 export function isAtomTest(s: Task): s is Test | Custom { 5 5 return s.type === 'test' || s.type === 'custom' ··· 54 54 ) 55 55 } 56 56 57 - export function getNames(task: Task) { 57 + export function getNames(task: Task): string[] { 58 58 const names = [task.name] 59 59 let current: Task | undefined = task 60 60
+3 -3
packages/utils/src/ast/esmWalker.ts
··· 27 27 } 28 28 29 29 const isNodeInPatternWeakSet = new WeakSet<_Node>() 30 - export function setIsNodeInPattern(node: Property) { 30 + export function setIsNodeInPattern(node: Property): WeakSet<_Node> { 31 31 return isNodeInPatternWeakSet.add(node) 32 32 } 33 33 export function isNodeInPattern(node: _Node): node is Property { ··· 41 41 export function esmWalker( 42 42 root: Node, 43 43 { onIdentifier, onImportMeta, onDynamicImport }: Visitors, 44 - ) { 44 + ): void { 45 45 const parentStack: Node[] = [] 46 46 const varKindStack: VariableDeclaration['kind'][] = [] 47 47 const scopeMap = new WeakMap<_Node, Set<string>>() ··· 292 292 return node && node.type === 'Property' && !node.computed 293 293 } 294 294 295 - export function isStaticPropertyKey(node: _Node, parent: _Node) { 295 + export function isStaticPropertyKey(node: _Node, parent: _Node): boolean { 296 296 return isStaticProperty(parent) && parent.key === node 297 297 } 298 298
+3 -3
packages/utils/src/ast/index.ts
··· 47 47 } 48 48 49 49 const isNodeInPatternWeakSet = new WeakSet<_Node>() 50 - export function setIsNodeInPattern(node: Property) { 50 + export function setIsNodeInPattern(node: Property): WeakSet<_Node> { 51 51 return isNodeInPatternWeakSet.add(node) 52 52 } 53 53 export function isNodeInPattern(node: _Node): node is Property { ··· 61 61 export function esmWalker( 62 62 root: Node, 63 63 { onIdentifier, onImportMeta, onDynamicImport, onCallExpression }: Visitors, 64 - ) { 64 + ): void { 65 65 const parentStack: Node[] = [] 66 66 const varKindStack: VariableDeclaration['kind'][] = [] 67 67 const scopeMap = new WeakMap<_Node, Set<string>>() ··· 340 340 return node && node.type === 'Property' && !node.computed 341 341 } 342 342 343 - export function isStaticPropertyKey(node: _Node, parent: _Node) { 343 + export function isStaticPropertyKey(node: _Node, parent: _Node): boolean { 344 344 return isStaticProperty(parent) && parent.key === node 345 345 } 346 346
+1 -1
packages/utils/src/diff/cleanupSemantic.ts
··· 189 189 * Reduce the number of edits by eliminating semantically trivial equalities. 190 190 * @param {!Array.<!diff_match_patch.Diff>} diffs Array of diff tuples. 191 191 */ 192 - const diff_cleanupSemantic = function (diffs: Array<Diff>) { 192 + const diff_cleanupSemantic = function (diffs: Array<Diff>): void { 193 193 let changes = false 194 194 const equalities = [] // Stack of indices where equalities are found. 195 195 let equalitiesLength = 0 // Keeping our own length var is faster in JS.
+2 -2
packages/utils/src/diff/constants.ts
··· 5 5 * LICENSE file in the root directory of this source tree. 6 6 */ 7 7 8 - export const NO_DIFF_MESSAGE = 'Compared values have no visual difference.' 8 + export const NO_DIFF_MESSAGE: string = 'Compared values have no visual difference.' 9 9 10 - export const SIMILAR_MESSAGE 10 + export const SIMILAR_MESSAGE: string 11 11 = 'Compared values serialize to the same structure.\n' 12 12 + 'Printing internal object structure without calling `toJSON` instead.'
+1 -4
packages/vitest/src/node/reporters/base.ts
··· 12 12 } from '../../types' 13 13 import { 14 14 getFullName, 15 - getSafeTimers, 16 15 getSuites, 17 16 getTestName, 18 17 getTests, ··· 72 71 73 72 private _filesInWatchMode = new Map<string, number>() 74 73 private _lastRunTimeout = 0 75 - private _lastRunTimer: NodeJS.Timer | undefined 74 + private _lastRunTimer: NodeJS.Timeout | undefined 76 75 private _lastRunCount = 0 77 76 private _timeStart = new Date() 78 77 private _offUnhandledRejection?: () => void ··· 216 215 ] 217 216 this.ctx.logger.logUpdate(BADGE_PADDING + LAST_RUN_TEXTS[0]) 218 217 this._lastRunTimeout = 0 219 - const { setInterval } = getSafeTimers() 220 218 this._lastRunTimer = setInterval(() => { 221 219 this._lastRunTimeout += 1 222 220 if (this._lastRunTimeout >= LAST_RUN_TEXTS.length) { ··· 232 230 } 233 231 234 232 private resetLastRunLog() { 235 - const { clearInterval } = getSafeTimers() 236 233 clearInterval(this._lastRunTimer) 237 234 this._lastRunTimer = undefined 238 235 this.ctx.logger.logUpdate.clear()