···57575858---------------------------------------
59596060+## @jridgewell/resolve-uri
6161+License: MIT
6262+By: Justin Ridgewell
6363+Repository: https://github.com/jridgewell/resolve-uri
6464+6565+> Copyright 2019 Justin Ridgewell <jridgewell@google.com>
6666+>
6767+> Permission is hereby granted, free of charge, to any person obtaining a copy
6868+> of this software and associated documentation files (the "Software"), to deal
6969+> in the Software without restriction, including without limitation the rights
7070+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7171+> copies of the Software, and to permit persons to whom the Software is
7272+> furnished to do so, subject to the following conditions:
7373+>
7474+> The above copyright notice and this permission notice shall be included in
7575+> all copies or substantial portions of the Software.
7676+>
7777+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7878+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7979+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8080+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8181+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8282+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
8383+> SOFTWARE.
8484+8585+---------------------------------------
8686+8787+## @jridgewell/sourcemap-codec
8888+License: MIT
8989+By: Justin Ridgewell
9090+Repository: git+https://github.com/jridgewell/sourcemaps.git
9191+9292+> Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
9393+>
9494+> Permission is hereby granted, free of charge, to any person obtaining a copy
9595+> of this software and associated documentation files (the "Software"), to deal
9696+> in the Software without restriction, including without limitation the rights
9797+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9898+> copies of the Software, and to permit persons to whom the Software is
9999+> furnished to do so, subject to the following conditions:
100100+>
101101+> The above copyright notice and this permission notice shall be included in
102102+> all copies or substantial portions of the Software.
103103+>
104104+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105105+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106106+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107107+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108108+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109109+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110110+> SOFTWARE.
111111+112112+---------------------------------------
113113+114114+## @jridgewell/trace-mapping
115115+License: MIT
116116+By: Justin Ridgewell
117117+Repository: git+https://github.com/jridgewell/sourcemaps.git
118118+119119+> Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
120120+>
121121+> Permission is hereby granted, free of charge, to any person obtaining a copy
122122+> of this software and associated documentation files (the "Software"), to deal
123123+> in the Software without restriction, including without limitation the rights
124124+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
125125+> copies of the Software, and to permit persons to whom the Software is
126126+> furnished to do so, subject to the following conditions:
127127+>
128128+> The above copyright notice and this permission notice shall be included in
129129+> all copies or substantial portions of the Software.
130130+>
131131+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
132132+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
133133+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
134134+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
135135+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
136136+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
137137+> SOFTWARE.
138138+139139+---------------------------------------
140140+60141## @sinonjs/commons
61142License: BSD-3-Clause
62143Repository: git+https://github.com/sinonjs/commons.git
···44import type { AsymmetricMatcher } from './jest-asymmetric-matchers'
55import type { Assertion, ChaiPlugin } from './types'
66import { isMockFunction } from '@vitest/spy'
77-import { assertTypes } from '@vitest/utils'
77+import { assertTypes } from '@vitest/utils/helpers'
88import c from 'tinyrainbow'
99import { JEST_MATCHERS_OBJECT } from './constants'
1010import {
+2-1
packages/expect/src/jest-matcher-utils.ts
···11import type { Formatter } from 'tinyrainbow'
22import type { MatcherHintOptions, Tester } from './types'
33-import { getType, stringify } from '@vitest/utils'
43import { diff, printDiffOrStringify } from '@vitest/utils/diff'
44+import { stringify } from '@vitest/utils/display'
55+import { getType } from '@vitest/utils/helpers'
56import c from 'tinyrainbow'
67import { JEST_MATCHERS_OBJECT } from './constants'
78
+1-1
packages/expect/src/jest-utils.ts
···2323*/
24242525import type { Tester, TesterContext } from './types'
2626-import { isObject } from '@vitest/utils'
2626+import { isObject } from '@vitest/utils/helpers'
27272828// Extracted out of jasmine 2.5.2
2929export function equals(
+1-1
packages/expect/src/utils.ts
···11import type { Test } from '@vitest/runner/types'
22import type { Assertion } from './types'
33-import { noop } from '@vitest/utils'
43import { processError } from '@vitest/utils/error'
44+import { noop } from '@vitest/utils/helpers'
5566export function createAssertionMessage(
77 util: Chai.ChaiUtils,
+2-2
packages/runner/src/collect.ts
···11import type { FileSpecification, VitestRunner } from './types/runner'
22import type { File, SuiteHooks } from './types/tasks'
33-import { toArray } from '@vitest/utils'
44-import { processError } from '@vitest/utils/error'
33+import { processError } from '@vitest/utils/error' // TODO: load dynamically
44+import { toArray } from '@vitest/utils/helpers'
55import { collectorContext, setFileContext } from './context'
66import { getHooks, setHooks } from './map'
77import { runSetupFiles } from './setup'
+1-1
packages/runner/src/context.ts
···1111 TestContext,
1212 WriteableTestContext,
1313} from './types/tasks'
1414-import { getSafeTimers } from '@vitest/utils'
1414+import { getSafeTimers } from '@vitest/utils/timers'
1515import { PendingError } from './errors'
1616import { finishSendTasksUpdate } from './run'
1717import { getRunner } from './suite'
+32-3
packages/runner/src/fixture.ts
···11import type { VitestRunner } from './types'
22import type { FixtureOptions, TestContext } from './types/tasks'
33-import { createDefer, isObject } from '@vitest/utils'
44-import { stripLiteral } from 'strip-literal'
33+import { createDefer, isObject } from '@vitest/utils/helpers'
54import { getFileContext } from './context'
65import { getTestFixture } from './map'
76···339338}
340339341340function getUsedProps(fn: Function) {
342342- let fnString = stripLiteral(fn.toString())
341341+ let fnString = filterOutComments(fn.toString())
343342 // match lowered async function and strip it off
344343 // example code on esbuild-try https://esbuild.github.io/try/#YgAwLjI0LjAALS1zdXBwb3J0ZWQ6YXN5bmMtYXdhaXQ9ZmFsc2UAZQBlbnRyeS50cwBjb25zdCBvID0gewogIGYxOiBhc3luYyAoKSA9PiB7fSwKICBmMjogYXN5bmMgKGEpID0+IHt9LAogIGYzOiBhc3luYyAoYSwgYikgPT4ge30sCiAgZjQ6IGFzeW5jIGZ1bmN0aW9uKGEpIHt9LAogIGY1OiBhc3luYyBmdW5jdGlvbiBmZihhKSB7fSwKICBhc3luYyBmNihhKSB7fSwKCiAgZzE6IGFzeW5jICgpID0+IHt9LAogIGcyOiBhc3luYyAoeyBhIH0pID0+IHt9LAogIGczOiBhc3luYyAoeyBhIH0sIGIpID0+IHt9LAogIGc0OiBhc3luYyBmdW5jdGlvbiAoeyBhIH0pIHt9LAogIGc1OiBhc3luYyBmdW5jdGlvbiBnZyh7IGEgfSkge30sCiAgYXN5bmMgZzYoeyBhIH0pIHt9LAoKICBoMTogYXN5bmMgKCkgPT4ge30sCiAgLy8gY29tbWVudCBiZXR3ZWVuCiAgaDI6IGFzeW5jIChhKSA9PiB7fSwKfQ
345344 // __async(this, null, function*
···385384 }
386385387386 return props
387387+}
388388+389389+function filterOutComments(s: string): string {
390390+ const result: string[] = []
391391+ let commentState: 'none' | 'singleline' | 'multiline' = 'none'
392392+ for (let i = 0; i < s.length; ++i) {
393393+ if (commentState === 'singleline') {
394394+ if (s[i] === '\n') {
395395+ commentState = 'none'
396396+ }
397397+ }
398398+ else if (commentState === 'multiline') {
399399+ if (s[i - 1] === '*' && s[i] === '/') {
400400+ commentState = 'none'
401401+ }
402402+ }
403403+ else if (commentState === 'none') {
404404+ if (s[i] === '/' && s[i + 1] === '/') {
405405+ commentState = 'singleline'
406406+ }
407407+ else if (s[i] === '/' && s[i + 1] === '*') {
408408+ commentState = 'multiline'
409409+ i += 2
410410+ }
411411+ else {
412412+ result.push(s[i])
413413+ }
414414+ }
415415+ }
416416+ return result.join('')
388417}
389418390419function splitByComma(s: string) {
+1-1
packages/runner/src/hooks.ts
···99 TaskPopulated,
1010 TestContext,
1111} from './types/tasks'
1212-import { assertTypes } from '@vitest/utils'
1212+import { assertTypes } from '@vitest/utils/helpers'
1313import { abortContextSignal, abortIfTimeout, withTimeout } from './context'
1414import { withFixtures } from './fixture'
1515import { getCurrentSuite, getRunner } from './suite'
-2
packages/runner/src/index.ts
···1818} from './suite'
1919export { getCurrentTest } from './test-state'
2020export type * from './types'
2121-2222-export { processError } from '@vitest/utils/error'
+3-2
packages/runner/src/run.ts
···1717 TestContext,
1818 WriteableTestContext,
1919} from './types/tasks'
2020-import { getSafeTimers, shuffle } from '@vitest/utils'
2121-import { processError } from '@vitest/utils/error'
2020+import { processError } from '@vitest/utils/error' // TODO: load dynamically
2121+import { shuffle } from '@vitest/utils/helpers'
2222+import { getSafeTimers } from '@vitest/utils/timers'
2223import { collectTests } from './collect'
2324import { abortContextSignal, getFileContext } from './context'
2425import { PendingError, TestRunAbortError } from './errors'
+2-3
packages/runner/src/suite.ts
···1717 TestFunction,
1818 TestOptions,
1919} from './types/tasks'
2020+import { format, objDisplay } from '@vitest/utils/display'
2021import {
2121- format,
2222 isNegativeNaN,
2323 isObject,
2424- objDisplay,
2524 objectAttr,
2625 toArray,
2727-} from '@vitest/utils'
2626+} from '@vitest/utils/helpers'
2827import {
2928 abortIfTimeout,
3029 collectorContext,
+1-1
packages/runner/src/test-state.ts
···11-import type { Test } from './types/tasks.ts'
11+import type { Test } from './types/tasks'
2233let _test: Test | undefined
44
+1-1
packages/ui/node/index.ts
···22import type { Vitest } from 'vitest/node'
33import fs from 'node:fs'
44import { fileURLToPath } from 'node:url'
55-import { toArray } from '@vitest/utils'
55+import { toArray } from '@vitest/utils/helpers'
66import { basename, resolve } from 'pathe'
77import sirv from 'sirv'
88import c from 'tinyrainbow'
-1
packages/utils/src/display.ts
···33 format as prettyFormat,
44 plugins as prettyFormatPlugins,
55} from '@vitest/pretty-format'
66-// since this is already part of Vitest via Chai, we can just reuse it without increasing the size of bundle
76import * as loupe from 'loupe'
8798type Inspect = (value: unknown, options: Options) => string
+2-150
packages/utils/src/error.ts
···11import type { DiffOptions } from './diff'
22import type { TestError } from './types'
33import { printDiffOrStringify } from './diff'
44-import { format, stringify } from './display'
55-66-// utils is bundled for any environment and might not support `Element`
77-declare class Element {
88- tagName: string
99-}
1010-1111-const IS_RECORD_SYMBOL = '@@__IMMUTABLE_RECORD__@@'
1212-const IS_COLLECTION_SYMBOL = '@@__IMMUTABLE_ITERABLE__@@'
1313-1414-function isImmutable(v: any) {
1515- return v && (v[IS_COLLECTION_SYMBOL] || v[IS_RECORD_SYMBOL])
1616-}
1717-1818-const OBJECT_PROTO = Object.getPrototypeOf({})
1919-2020-function getUnserializableMessage(err: unknown) {
2121- if (err instanceof Error) {
2222- return `<unserializable>: ${err.message}`
2323- }
2424- if (typeof err === 'string') {
2525- return `<unserializable>: ${err}`
2626- }
2727- return '<unserializable>'
2828-}
2929-3030-// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
3131-export function serializeValue(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
3232- if (!val || typeof val === 'string') {
3333- return val
3434- }
3535- if (val instanceof Error && 'toJSON' in val && typeof val.toJSON === 'function') {
3636- const jsonValue = val.toJSON()
3737-3838- if (jsonValue && jsonValue !== val && typeof jsonValue === 'object') {
3939- if (typeof val.message === 'string') {
4040- safe(() => jsonValue.message ??= val.message)
4141- }
4242- if (typeof val.stack === 'string') {
4343- safe(() => jsonValue.stack ??= val.stack)
4444- }
4545- if (typeof val.name === 'string') {
4646- safe(() => jsonValue.name ??= val.name)
4747- }
4848- if (val.cause != null) {
4949- safe(() => jsonValue.cause ??= serializeValue(val.cause, seen))
5050- }
5151- }
5252- return serializeValue(jsonValue, seen)
5353- }
5454- if (typeof val === 'function') {
5555- return `Function<${val.name || 'anonymous'}>`
5656- }
5757- if (typeof val === 'symbol') {
5858- return val.toString()
5959- }
6060- if (typeof val !== 'object') {
6161- return val
6262- }
6363- if (typeof Buffer !== 'undefined' && val instanceof Buffer) {
6464- return `<Buffer(${val.length}) ...>`
6565- }
6666- if (typeof Uint8Array !== 'undefined' && val instanceof Uint8Array) {
6767- return `<Uint8Array(${val.length}) ...>`
6868- }
6969- // cannot serialize immutables as immutables
7070- if (isImmutable(val)) {
7171- return serializeValue(val.toJSON(), seen)
7272- }
7373- if (
7474- val instanceof Promise
7575- || (val.constructor && val.constructor.prototype === 'AsyncFunction')
7676- ) {
7777- return 'Promise'
7878- }
7979- if (typeof Element !== 'undefined' && val instanceof Element) {
8080- return val.tagName
8181- }
8282- if (typeof val.asymmetricMatch === 'function') {
8383- return `${val.toString()} ${format(val.sample)}`
8484- }
8585- if (typeof val.toJSON === 'function') {
8686- return serializeValue(val.toJSON(), seen)
8787- }
8888-8989- if (seen.has(val)) {
9090- return seen.get(val)
9191- }
9292-9393- if (Array.isArray(val)) {
9494- // eslint-disable-next-line unicorn/no-new-array -- we need to keep sparse arrays ([1,,3])
9595- const clone: any[] = new Array(val.length)
9696- seen.set(val, clone)
9797- val.forEach((e, i) => {
9898- try {
9999- clone[i] = serializeValue(e, seen)
100100- }
101101- catch (err) {
102102- clone[i] = getUnserializableMessage(err)
103103- }
104104- })
105105- return clone
106106- }
107107- else {
108108- // Objects with `Error` constructors appear to cause problems during worker communication
109109- // using `MessagePort`, so the serialized error object is being recreated as plain object.
110110- const clone = Object.create(null)
111111- seen.set(val, clone)
112112-113113- let obj = val
114114- while (obj && obj !== OBJECT_PROTO) {
115115- Object.getOwnPropertyNames(obj).forEach((key) => {
116116- if (key in clone) {
117117- return
118118- }
119119- try {
120120- clone[key] = serializeValue(val[key], seen)
121121- }
122122- catch (err) {
123123- // delete in case it has a setter from prototype that might throw
124124- delete clone[key]
125125- clone[key] = getUnserializableMessage(err)
126126- }
127127- })
128128- obj = Object.getPrototypeOf(obj)
129129- }
130130- return clone
131131- }
132132-}
133133-134134-function safe(fn: () => void) {
135135- try {
136136- return fn()
137137- }
138138- catch {
139139- // ignore
140140- }
141141-}
44+import { stringify } from './display'
55+import { serializeValue } from './serialize'
14261437export { serializeValue as serializeError }
144144-145145-function normalizeErrorMessage(message: string) {
146146- return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, '')
147147-}
14881499export function processError(
15010 _err: any,
···17434 if ('actual' in err && typeof err.actual !== 'string') {
17535 err.actual = stringify(err.actual, 10)
17636 }
177177-178178- // some Error implementations don't allow rewriting message
179179- try {
180180- if (typeof err.message === 'string') {
181181- err.message = normalizeErrorMessage(err.message)
182182- }
183183- }
184184- catch {}
1853718638 // some Error implementations may not allow rewriting cause
18739 // in most cases, the assignment will lead to "err.cause = err.cause"
+3-21
packages/utils/src/helpers.ts
···1010 stackTraceLimit?: number
1111}
12121313+export { nanoid } from './nanoid'
1414+export { shuffle } from './random'
1515+1316/**
1417 * Get original stacktrace without source map support the most performant way.
1518 * - Create only 1 stack frame.
···969997100export function isBareImport(id: string): boolean {
98101 return bareImportRE.test(id)
9999-}
100100-101101-// convert RegExp.toString to RegExp
102102-export function parseRegexp(input: string): RegExp {
103103- // Parse input
104104- // eslint-disable-next-line regexp/no-misleading-capturing-group
105105- const m = input.match(/(\/?)(.+)\1([a-z]*)/i)
106106-107107- // match nothing
108108- if (!m) {
109109- return /$^/
110110- }
111111-112112- // Invalid flags
113113- // eslint-disable-next-line regexp/optimal-quantifier-concatenation
114114- if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
115115- return new RegExp(input)
116116- }
117117-118118- // Create the regular expression
119119- return new RegExp(m[2], m[3])
120102}
121103122104export function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
-52
packages/utils/src/index.ts
···11-export {
22- CSS_LANGS_RE,
33- KNOWN_ASSET_RE,
44- KNOWN_ASSET_TYPES,
55- NULL_BYTE_PLACEHOLDER,
66- VALID_ID_PREFIX,
77-} from './constants'
88-export {
99- format,
1010- inspect,
1111- objDisplay,
1212- stringify,
1313-} from './display'
141export type { LoupeOptions, StringifyOptions } from './display'
1515-1616-export {
1717- assertTypes,
1818- cleanUrl,
1919- clone,
2020- createDefer,
2121- createSimpleStackTrace,
2222- deepClone,
2323- deepMerge,
2424- getCallLastIndex,
2525- getOwnProperties,
2626- getType,
2727- isBareImport,
2828- isExternalUrl,
2929- isNegativeNaN,
3030- isObject,
3131- isPrimitive,
3232- noop,
3333- notNullish,
3434- objectAttr,
3535- parseRegexp,
3636- slash,
3737- toArray,
3838- unwrapId,
3939- withTrailingSlash,
4040- wrapId,
4141-} from './helpers'
422export type { DeferPromise } from './helpers'
4343-4444-export { highlight } from './highlight'
4545-export { nanoid } from './nanoid'
4646-export {
4747- lineSplitRE,
4848- offsetToLineNumber,
4949- positionToOffset,
5050-} from './offset'
5151-export { shuffle } from './random'
5252-export { getSafeTimers, setSafeTimers } from './timers'
5353-543export type { SafeTimers } from './timers'
5555-564export type {
575 ArgumentsType,
586 Arrayable,
+140
packages/utils/src/serialize.ts
···11+// utils is bundled for any environment and might not support `Element`
22+declare class Element {
33+ tagName: string
44+}
55+66+const IS_RECORD_SYMBOL = '@@__IMMUTABLE_RECORD__@@'
77+const IS_COLLECTION_SYMBOL = '@@__IMMUTABLE_ITERABLE__@@'
88+99+function isImmutable(v: any) {
1010+ return v && (v[IS_COLLECTION_SYMBOL] || v[IS_RECORD_SYMBOL])
1111+}
1212+1313+const OBJECT_PROTO = Object.getPrototypeOf({})
1414+1515+function getUnserializableMessage(err: unknown) {
1616+ if (err instanceof Error) {
1717+ return `<unserializable>: ${err.message}`
1818+ }
1919+ if (typeof err === 'string') {
2020+ return `<unserializable>: ${err}`
2121+ }
2222+ return '<unserializable>'
2323+}
2424+2525+// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
2626+export function serializeValue(val: any, seen: WeakMap<WeakKey, any> = new WeakMap()): any {
2727+ if (!val || typeof val === 'string') {
2828+ return val
2929+ }
3030+ if (val instanceof Error && 'toJSON' in val && typeof val.toJSON === 'function') {
3131+ const jsonValue = val.toJSON()
3232+3333+ if (jsonValue && jsonValue !== val && typeof jsonValue === 'object') {
3434+ if (typeof val.message === 'string') {
3535+ safe(() => jsonValue.message ??= normalizeErrorMessage(val.message))
3636+ }
3737+ if (typeof val.stack === 'string') {
3838+ safe(() => jsonValue.stack ??= val.stack)
3939+ }
4040+ if (typeof val.name === 'string') {
4141+ safe(() => jsonValue.name ??= val.name)
4242+ }
4343+ if (val.cause != null) {
4444+ safe(() => jsonValue.cause ??= serializeValue(val.cause, seen))
4545+ }
4646+ }
4747+ return serializeValue(jsonValue, seen)
4848+ }
4949+ if (typeof val === 'function') {
5050+ return `Function<${val.name || 'anonymous'}>`
5151+ }
5252+ if (typeof val === 'symbol') {
5353+ return val.toString()
5454+ }
5555+ if (typeof val !== 'object') {
5656+ return val
5757+ }
5858+ if (typeof Buffer !== 'undefined' && val instanceof Buffer) {
5959+ return `<Buffer(${val.length}) ...>`
6060+ }
6161+ if (typeof Uint8Array !== 'undefined' && val instanceof Uint8Array) {
6262+ return `<Uint8Array(${val.length}) ...>`
6363+ }
6464+ // cannot serialize immutables as immutables
6565+ if (isImmutable(val)) {
6666+ return serializeValue(val.toJSON(), seen)
6767+ }
6868+ if (
6969+ val instanceof Promise
7070+ || (val.constructor && val.constructor.prototype === 'AsyncFunction')
7171+ ) {
7272+ return 'Promise'
7373+ }
7474+ if (typeof Element !== 'undefined' && val instanceof Element) {
7575+ return val.tagName
7676+ }
7777+ if (typeof val.toJSON === 'function') {
7878+ return serializeValue(val.toJSON(), seen)
7979+ }
8080+8181+ if (seen.has(val)) {
8282+ return seen.get(val)
8383+ }
8484+8585+ if (Array.isArray(val)) {
8686+ // eslint-disable-next-line unicorn/no-new-array -- we need to keep sparse arrays ([1,,3])
8787+ const clone: any[] = new Array(val.length)
8888+ seen.set(val, clone)
8989+ val.forEach((e, i) => {
9090+ try {
9191+ clone[i] = serializeValue(e, seen)
9292+ }
9393+ catch (err) {
9494+ clone[i] = getUnserializableMessage(err)
9595+ }
9696+ })
9797+ return clone
9898+ }
9999+ else {
100100+ // Objects with `Error` constructors appear to cause problems during worker communication
101101+ // using `MessagePort`, so the serialized error object is being recreated as plain object.
102102+ const clone = Object.create(null)
103103+ seen.set(val, clone)
104104+105105+ let obj = val
106106+ while (obj && obj !== OBJECT_PROTO) {
107107+ Object.getOwnPropertyNames(obj).forEach((key) => {
108108+ if (key in clone) {
109109+ return
110110+ }
111111+ try {
112112+ clone[key] = serializeValue(val[key], seen)
113113+ }
114114+ catch (err) {
115115+ // delete in case it has a setter from prototype that might throw
116116+ delete clone[key]
117117+ clone[key] = getUnserializableMessage(err)
118118+ }
119119+ })
120120+ obj = Object.getPrototypeOf(obj)
121121+ }
122122+ if (val instanceof Error) {
123123+ safe(() => val.message = normalizeErrorMessage(val.message))
124124+ }
125125+ return clone
126126+ }
127127+}
128128+129129+function safe(fn: () => void) {
130130+ try {
131131+ return fn()
132132+ }
133133+ catch {
134134+ // ignore
135135+ }
136136+}
137137+138138+function normalizeErrorMessage(message: string) {
139139+ return message.replace(/__(vite_ssr_import|vi_import)_\d+__\./g, '')
140140+}
+76-27
packages/utils/src/source-map.ts
···11-import type { SourceMapInput } from '@jridgewell/trace-mapping'
11+import type { OriginalMapping } from '@jridgewell/trace-mapping'
22import type { ParsedStack, TestError } from './types'
33-import { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping'
33+import { originalPositionFor } from '@jridgewell/trace-mapping'
44import { resolve } from 'pathe'
55import { isPrimitive, notNullish } from './helpers'
66-77-export {
88- eachMapping,
99- type EachMapping,
1010- generatedPositionFor,
1111- originalPositionFor,
1212- TraceMap,
1313-} from '@jridgewell/trace-mapping'
1414-export type { SourceMapInput } from '@jridgewell/trace-mapping'
156167export interface StackTraceParserOptions {
178 ignoreStackEntries?: (RegExp | string)[]
···237228 }
238229239230 const map = options.getSourceMap?.(stack.file) as
240240- | SourceMapInput
231231+ | SourceMapLike
241232 | null
242233 | undefined
243234 if (!map || typeof map !== 'object' || !map.version) {
244235 return shouldFilter(ignoreStackEntries, stack.file) ? null : stack
245236 }
246237247247- const traceMap = new TraceMap(map)
248248- const { line, column, source, name } = originalPositionFor(traceMap, stack)
238238+ const traceMap = new DecodedMap(map, stack.file)
239239+ const position = getOriginalPosition(traceMap, stack)
240240+ if (!position) {
241241+ return stack
242242+ }
249243250250- let file: string = stack.file
251251- if (source) {
252252- const fileUrl = stack.file.startsWith('file://')
253253- ? stack.file
254254- : `file://${stack.file}`
255255- const sourceRootUrl = map.sourceRoot
256256- ? new URL(map.sourceRoot, fileUrl)
257257- : fileUrl
258258- file = new URL(source, sourceRootUrl).pathname
259259- // if the file path is on windows, we need to remove the leading slash
260260- if (file.match(/\/\w:\//)) {
261261- file = file.slice(1)
262262- }
244244+ const { line, column, source, name } = position
245245+ let file = source || stack.file
246246+ if (file.match(/\/\w:\//)) {
247247+ file = file.slice(1)
263248 }
264249265250 if (shouldFilter(ignoreStackEntries, file)) {
···333318334319 ;(e as TestError).stacks = stackFrames
335320 return stackFrames
321321+}
322322+323323+interface SourceMapLike {
324324+ version: number
325325+ mappings?: string
326326+ names?: string[]
327327+ sources?: string[]
328328+ sourcesContent?: string[]
329329+ sourceRoot?: string
330330+}
331331+332332+interface Needle {
333333+ line: number
334334+ column: number
335335+}
336336+337337+export class DecodedMap {
338338+ _encoded: string
339339+ _decoded: undefined | number[][][]
340340+ _decodedMemo: Stats
341341+ url: string
342342+ version: number
343343+ names: string[] = []
344344+ resolvedSources: string[]
345345+346346+ constructor(
347347+ public map: SourceMapLike,
348348+ from: string,
349349+ ) {
350350+ const { mappings, names, sources } = map
351351+ this.version = map.version
352352+ this.names = names || []
353353+ this._encoded = mappings || ''
354354+ this._decodedMemo = memoizedState()
355355+ this.url = from
356356+ this.resolvedSources = (sources || []).map(s =>
357357+ resolve(s || '', from),
358358+ )
359359+ }
360360+}
361361+362362+interface Stats {
363363+ lastKey: number
364364+ lastNeedle: number
365365+ lastIndex: number
366366+}
367367+368368+function memoizedState(): Stats {
369369+ return {
370370+ lastKey: -1,
371371+ lastNeedle: -1,
372372+ lastIndex: -1,
373373+ }
374374+}
375375+376376+export function getOriginalPosition(
377377+ map: DecodedMap,
378378+ needle: Needle,
379379+): OriginalMapping | null {
380380+ const result = originalPositionFor(map as any, needle)
381381+ if (result.column == null) {
382382+ return null
383383+ }
384384+ return result
336385}
+3-1
test/config/test/console-color.test.ts
···4141 GITHUB_ACTIONS: undefined,
42424343 // Overrides current process's value, since we are running Vitest in Vitest here
4444- FORCE_TTY: undefined,
4444+ // By default, tinyrainbow doesn't check isatty since version 3, but
4545+ // FORCE_TTY=false will make the check `false`
4646+ FORCE_TTY: 'false',
4547 },
4648 }, undefined, undefined, undefined, { preserveAnsi: true })
4749
+1-1
test/core/test/concurrent-suite.test.ts
···11-import { createDefer } from '@vitest/utils'
11+import { createDefer } from '@vitest/utils/helpers'
22import { afterAll, describe, expect, test } from 'vitest'
3344describe('basic', () => {
+1-1
test/core/test/diff.test.ts
···11import type { DiffOptions } from '@vitest/utils/diff'
22import { stripVTControlCharacters } from 'node:util'
33-import { processError } from '@vitest/runner'
43import { diff, diffStringsUnified, printDiffOrStringify } from '@vitest/utils/diff'
44+import { processError } from '@vitest/utils/error'
55import { expect, test } from 'vitest'
6677function wrapDiff(diff?: string) {
···11// @vitest-environment jsdom
2233-import { serializeValue } from '@vitest/utils/error'
33+import { serializeValue } from '@vitest/utils/serialize'
44import { describe, expect, it } from 'vitest'
5566describe('error serialize', () => {
+1-1
test/core/test/utils-display.spec.ts
···11import util from 'node:util'
22-import { format } from '@vitest/utils'
22+import { format } from '@vitest/utils/display'
33import { describe, expect, test } from 'vitest'
4455describe('format', () => {
+2-1
test/core/test/utils.spec.ts
···11-import { assertTypes, deepClone, deepMerge, isNegativeNaN, objDisplay, objectAttr, toArray } from '@vitest/utils'
11+import { objDisplay } from '@vitest/utils/display'
22+import { assertTypes, deepClone, deepMerge, isNegativeNaN, objectAttr, toArray } from '@vitest/utils/helpers'
23import { parseSingleFFOrSafariStack } from '@vitest/utils/source-map'
34import { EvaluatedModules } from 'vite/module-runner'
45import { beforeAll, describe, expect, test } from 'vitest'
+1-2
packages/browser/src/node/plugin.ts
···66import { createReadStream, lstatSync, readFileSync } from 'node:fs'
77import { createRequire } from 'node:module'
88import { dynamicImportPlugin } from '@vitest/mocker/node'
99-import { toArray } from '@vitest/utils'
99+import { toArray } from '@vitest/utils/helpers'
1010import MagicString from 'magic-string'
1111import { basename, dirname, extname, resolve } from 'pathe'
1212import sirv from 'sirv'
···281281 const include = [
282282 'vitest > expect-type',
283283 'vitest > @vitest/snapshot > magic-string',
284284- 'vitest > @vitest/runner > strip-literal',
285284 'vitest > @vitest/expect > chai',
286285 'vitest > @vitest/expect > chai > loupe',
287286 'vitest > @vitest/utils > loupe',
+2-2
packages/browser/src/node/pool.ts
···11-import type { DeferPromise } from '@vitest/utils'
11+import type { DeferPromise } from '@vitest/utils/helpers'
22import type {
33 BrowserProvider,
44 ProcessPool,
···99import crypto from 'node:crypto'
1010import * as nodeos from 'node:os'
1111import { performance } from 'node:perf_hooks'
1212-import { createDefer } from '@vitest/utils'
1212+import { createDefer } from '@vitest/utils/helpers'
1313import { stringify } from 'flatted'
1414import { createDebugger } from 'vitest/node'
1515
+4-3
packages/browser/src/node/projectParent.ts
···7575 return result?.map
7676 },
7777 getUrlId: (id) => {
7878- const mod = this.vite.moduleGraph.getModuleById(id)
7878+ const moduleGraph = this.vite.environments.client.moduleGraph
7979+ const mod = moduleGraph.getModuleById(id)
7980 if (mod) {
8081 return id
8182 }
8283 const resolvedPath = resolve(this.vite.config.root, id.slice(1))
8383- const modUrl = this.vite.moduleGraph.getModuleById(resolvedPath)
8484+ const modUrl = moduleGraph.getModuleById(resolvedPath)
8485 if (modUrl) {
8586 return resolvedPath
8687 }
8788 // some browsers (looking at you, safari) don't report queries in stack traces
8889 // the next best thing is to try the first id that this file resolves to
8989- const files = this.vite.moduleGraph.getModulesByFile(resolvedPath)
9090+ const files = moduleGraph.getModulesByFile(resolvedPath)
9091 if (files && files.size) {
9192 return files.values().next().value!.id!
9293 }
+1-1
packages/mocker/src/browser/hints.ts
···11import type { MaybeMockedDeep } from '@vitest/spy'
22import type { ModuleMockFactoryWithHelper, ModuleMockOptions } from '../types'
33import type { ModuleMocker } from './mocker'
44-import { createSimpleStackTrace } from '@vitest/utils'
44+import { createSimpleStackTrace } from '@vitest/utils/helpers'
55import { parseSingleStack } from '@vitest/utils/source-map'
6677export interface CompilerHintsOptions {
+1-1
packages/runner/src/utils/tasks.ts
···11import type { Arrayable } from '@vitest/utils'
22import type { Suite, Task, Test } from '../types/tasks'
33-import { toArray } from '@vitest/utils'
33+import { toArray } from '@vitest/utils/helpers'
4455export function isTestCase(s: Task): s is Test {
66 return s.type === 'test'
+2-2
packages/snapshot/src/port/inlineSnapshot.ts
···11import type MagicString from 'magic-string'
22import type { SnapshotEnvironment } from '../types'
33+import { getCallLastIndex } from '../../../utils/src/helpers'
34import {
44- getCallLastIndex,
55 lineSplitRE,
66 offsetToLineNumber,
77 positionToOffset,
88-} from '../../../utils/src/index'
88+} from '../../../utils/src/offset'
991010export interface InlineSnapshot {
1111 snapshot: string
+1-1
packages/snapshot/src/port/utils.ts
···1010import type { SnapshotEnvironment } from '../types/environment'
1111import { format as prettyFormat } from '@vitest/pretty-format'
1212import naturalCompare from 'natural-compare'
1313-import { isObject } from '../../../utils/src/index'
1313+import { isObject } from '../../../utils/src/helpers'
1414import { getSerializers } from './plugins'
15151616// TODO: rewrite and clean up
+1-1
packages/vitest/src/api/setup.ts
···1515 WebSocketRPC,
1616} from './types'
1717import { existsSync, promises as fs } from 'node:fs'
1818-import { noop } from '@vitest/utils'
1818+import { noop } from '@vitest/utils/helpers'
1919import { createBirpc } from 'birpc'
2020import { parse, stringify } from 'flatted'
2121import { WebSocketServer } from 'ws'
+1-1
packages/vitest/src/integrations/vi.ts
···1010import type { VitestMocker } from '../runtime/moduleRunner/moduleMocker'
1111import type { MockFactoryWithHelper, MockOptions } from '../types/mocker'
1212import { clearAllMocks, fn, isMockFunction, resetAllMocks, restoreAllMocks, spyOn } from '@vitest/spy'
1313-import { assertTypes, createSimpleStackTrace } from '@vitest/utils'
1313+import { assertTypes, createSimpleStackTrace } from '@vitest/utils/helpers'
1414import { getWorkerState, isChildProcess, resetModules, waitForImportsToResolve } from '../runtime/utils'
1515import { parseSingleStack } from '../utils/source-map'
1616import { FakeTimers } from './mock/timers'
+1-1
packages/vitest/src/integrations/wait.ts
···11-import { getSafeTimers } from '@vitest/utils'
11+import { getSafeTimers } from '@vitest/utils/timers'
22import { vi } from './vi'
3344// The waitFor function was inspired by https://github.com/testing-library/web-testing-library/pull/2
+1-1
packages/vitest/src/node/ast-collect.ts
···11import type { File, Suite, Task, Test } from '@vitest/runner'
22import type { TestError } from '../types/general'
33import type { TestProject } from './project'
44+import { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping'
45import {
56 calculateSuiteHash,
67 generateHash,
78 interpretTaskModes,
89 someTasksAreOnly,
910} from '@vitest/runner/utils'
1010-import { originalPositionFor, TraceMap } from '@vitest/utils/source-map'
1111import { ancestor as walkAst } from 'acorn-walk'
1212import { relative } from 'pathe'
1313import { parseAst } from 'vite'
+1-1
packages/vitest/src/node/core.ts
···1616import os from 'node:os'
1717import { getTasks, hasFailed, limitConcurrency } from '@vitest/runner/utils'
1818import { SnapshotManager } from '@vitest/snapshot/manager'
1919-import { deepClone, deepMerge, noop, toArray } from '@vitest/utils'
1919+import { deepClone, deepMerge, noop, toArray } from '@vitest/utils/helpers'
2020import { normalize, relative } from 'pathe'
2121import { version } from '../../package.json' with { type: 'json' }
2222import { WebSocketReporter } from '../api/setup'
+1-1
packages/vitest/src/node/coverage.ts
···66import type { AfterSuiteRunMeta } from '../types/general'
77import { existsSync, promises as fs, readdirSync, writeFileSync } from 'node:fs'
88import path from 'node:path'
99-import { cleanUrl, slash } from '@vitest/utils'
99+import { cleanUrl, slash } from '@vitest/utils/helpers'
1010import { relative, resolve } from 'pathe'
1111import pm from 'picomatch'
1212import { glob } from 'tinyglobby'
+1-1
packages/vitest/src/node/create.ts
···66import type { VitestOptions } from './core'
77import type { VitestRunMode } from './types/config'
88import { resolve } from 'node:path'
99-import { deepClone, slash } from '@vitest/utils'
99+import { deepClone, slash } from '@vitest/utils/helpers'
1010import { findUp } from 'find-up'
1111import { mergeConfig } from 'vite'
1212import { configFiles } from '../constants'
+1-1
packages/vitest/src/node/globalSetup.ts
···11import type { ModuleRunner } from 'vite/module-runner'
22import type { TestProject } from './project'
33-import { toArray } from '@vitest/utils'
33+import { toArray } from '@vitest/utils/helpers'
4455export interface GlobalSetupFile {
66 file: string
+1-1
packages/vitest/src/node/logger.ts
···44import type { Vitest } from './core'
55import type { TestProject } from './project'
66import { Console } from 'node:console'
77-import { toArray } from '@vitest/utils'
77+import { toArray } from '@vitest/utils/helpers'
88import c from 'tinyrainbow'
99import { highlightCode } from '../utils/colors'
1010import { printError } from './printError'
+2-1
packages/vitest/src/node/printError.ts
···77import { existsSync, readFileSync } from 'node:fs'
88import { Writable } from 'node:stream'
99import { stripVTControlCharacters } from 'node:util'
1010-import { inspect, isPrimitive } from '@vitest/utils'
1010+import { inspect } from '@vitest/utils/display'
1111+import { isPrimitive } from '@vitest/utils/helpers'
1112import { normalize, relative } from 'pathe'
1213import c from 'tinyrainbow'
1314import { TypeCheckError } from '../typecheck/typechecker'
+1-1
packages/vitest/src/node/project.ts
···1717import { rm } from 'node:fs/promises'
1818import { tmpdir } from 'node:os'
1919import path from 'node:path'
2020-import { deepMerge, nanoid, slash } from '@vitest/utils'
2020+import { deepMerge, nanoid, slash } from '@vitest/utils/helpers'
2121import { isAbsolute, join, relative } from 'pathe'
2222import pm from 'picomatch'
2323import { glob } from 'tinyglobby'
+1-1
packages/vitest/src/node/resolver.ts
···22import { existsSync, promises as fsp } from 'node:fs'
33import { isBuiltin } from 'node:module'
44import { pathToFileURL } from 'node:url'
55-import { KNOWN_ASSET_RE } from '@vitest/utils'
55+import { KNOWN_ASSET_RE } from '@vitest/utils/constants'
66import { findNearestPackageData } from '@vitest/utils/resolver'
77import * as esModuleLexer from 'es-module-lexer'
88import { dirname, extname, join, resolve } from 'pathe'
+3-3
packages/vitest/src/node/test-run.ts
···1717import assert from 'node:assert'
1818import { createHash } from 'node:crypto'
1919import { copyFile, mkdir } from 'node:fs/promises'
2020-import { isPrimitive } from '@vitest/utils'
2121-import { serializeError } from '@vitest/utils/error'
2020+import { isPrimitive } from '@vitest/utils/helpers'
2121+import { serializeValue } from '@vitest/utils/serialize'
2222import { parseErrorStacktrace } from '@vitest/utils/source-map'
2323import mime from 'mime/lite'
2424import { basename, dirname, extname, resolve } from 'pathe'
···75757676 for (const [id, event, data] of events) {
7777 await this.reportEvent(id, event, data).catch((error) => {
7878- this.vitest.state.catchError(serializeError(error), 'Unhandled Reporter Error')
7878+ this.vitest.state.catchError(serializeValue(error), 'Unhandled Reporter Error')
7979 })
8080 }
8181
+1-1
packages/vitest/src/node/watch-filter.ts
···11import type { Writable } from 'node:stream'
22import readline from 'node:readline'
33import { stripVTControlCharacters } from 'node:util'
44-import { createDefer } from '@vitest/utils'
44+import { createDefer } from '@vitest/utils/helpers'
55import c from 'tinyrainbow'
66import { stdout as getStdout } from '../utils/base'
77
+1-1
packages/vitest/src/node/watcher.ts
···11import type { Vitest } from './core'
22import type { TestProject } from './project'
33import { readFileSync } from 'node:fs'
44-import { noop, slash } from '@vitest/utils'
44+import { noop, slash } from '@vitest/utils/helpers'
55import { resolve } from 'pathe'
66import pm from 'picomatch'
77
+11-10
packages/vitest/src/public/browser.ts
···99 loadSnapshotSerializers,
1010 setupCommonEnv,
1111} from '../runtime/setup-common'
1212-export { collectTests, processError, startTests } from '@vitest/runner'
1212+export { collectTests, startTests } from '@vitest/runner'
1313export * as SpyModule from '@vitest/spy'
1414-export {
1515- format,
1616- getSafeTimers,
1717- getType,
1818- inspect,
1919- stringify,
2020-} from '@vitest/utils'
2114export type { LoupeOptions, ParsedStack, StringifyOptions } from '@vitest/utils'
2215export {
2323- originalPositionFor,
2424- TraceMap,
1616+ format,
1717+ inspect,
1818+ stringify,
1919+} from '@vitest/utils/display'
2020+export { processError } from '@vitest/utils/error'
2121+export { getType } from '@vitest/utils/helpers'
2222+export {
2323+ DecodedMap,
2424+ getOriginalPosition,
2525} from '@vitest/utils/source-map'
2626+export { getSafeTimers, setSafeTimers } from '@vitest/utils/timers'
-10
packages/vitest/src/public/workers.ts
···11-export { provideWorkerState } from '../runtime/utils'
22-export { collect as collectVitestWorkerTests, run as runVitestWorker } from '../runtime/worker'
33-export { runBaseTests } from '../runtime/workers/base'
44-export type { VitestWorker, WorkerRpcOptions } from '../runtime/workers/types'
55-export {
66- createForksRpcOptions,
77- createThreadsRpcOptions,
88- unwrapSerializableConfig,
99-} from '../runtime/workers/utils'
1010-export { runVmTests } from '../runtime/workers/vm'
+1-1
packages/vitest/src/runtime/benchmark.ts
···22import type { BenchFunction, BenchmarkAPI, BenchOptions } from './types/benchmark'
33import { getCurrentSuite } from '@vitest/runner'
44import { createChainable } from '@vitest/runner/utils'
55-import { noop } from '@vitest/utils'
55+import { noop } from '@vitest/utils/helpers'
66import { getWorkerState } from './utils'
7788const benchFns = new WeakMap<Test, BenchFunction>()
+1-1
packages/vitest/src/runtime/console.ts
···22import { Console } from 'node:console'
33import { relative } from 'node:path'
44import { Writable } from 'node:stream'
55-import { getSafeTimers } from '@vitest/utils'
55+import { getSafeTimers } from '@vitest/utils/timers'
66import c from 'tinyrainbow'
77import { RealDate } from '../integrations/mock/date'
88import { getWorkerState } from './utils'
+1-1
packages/vitest/src/runtime/external-executor.ts
···55import fs from 'node:fs'
66import { isBuiltin } from 'node:module'
77import { fileURLToPath, pathToFileURL } from 'node:url'
88-import { isBareImport } from '@vitest/utils'
88+import { isBareImport } from '@vitest/utils/helpers'
99import { findNearestPackageData } from '@vitest/utils/resolver'
1010import { extname, normalize } from 'pathe'
1111import { CommonjsExecutor } from './vm/commonjs-executor'
+1-1
packages/vitest/src/runtime/rpc.ts
···22import type { BirpcOptions, BirpcReturn } from 'birpc'
33import type { RunnerRPC, RuntimeRPC } from '../types/rpc'
44import type { WorkerRPC } from '../types/worker'
55-import { getSafeTimers } from '@vitest/utils'
55+import { getSafeTimers } from '@vitest/utils/timers'
66import { createBirpc } from 'birpc'
77import { getWorkerState } from './utils'
88
+1-1
packages/vitest/src/runtime/runVmTests.ts
···77import timersPromises from 'node:timers/promises'
88import util from 'node:util'
99import { collectTests, startTests } from '@vitest/runner'
1010-import { KNOWN_ASSET_TYPES } from '@vitest/utils'
1010+import { KNOWN_ASSET_TYPES } from '@vitest/utils/constants'
1111import { setupChaiConfig } from '../integrations/chai/config'
1212import {
1313 startCoverageInsideWorker,
+1-1
packages/vitest/src/runtime/setup-common.ts
···44import type { SerializedConfig } from './config'
55import type { VitestModuleRunner } from './moduleRunner/moduleRunner'
66import { addSerializer } from '@vitest/snapshot'
77-import { setSafeTimers } from '@vitest/utils'
77+import { setSafeTimers } from '@vitest/utils/timers'
88import { getWorkerState } from './utils'
991010let globalSetup = false
+2-1
packages/vitest/src/runtime/setup-node.ts
···55import timers from 'node:timers'
66import timersPromises from 'node:timers/promises'
77import util from 'node:util'
88-import { getSafeTimers, KNOWN_ASSET_TYPES } from '@vitest/utils'
88+import { KNOWN_ASSET_TYPES } from '@vitest/utils/constants'
99+import { getSafeTimers } from '@vitest/utils/timers'
910import { expect } from '../integrations/chai'
1011import { resolveSnapshotEnvironment } from '../integrations/snapshot/environments/resolveSnapshotEnvironment'
1112import * as VitestIndex from '../public/index'
+1-1
packages/vitest/src/runtime/utils.ts
···11import type { EvaluatedModules } from 'vite/module-runner'
22import type { WorkerGlobalState } from '../types/worker'
33-import { getSafeTimers } from '@vitest/utils'
33+import { getSafeTimers } from '@vitest/utils/timers'
4455const NAME_WORKER_STATE = '__vitest_worker__'
66
+16
packages/vitest/src/runtime/worker-base.ts
···11+import type { ContextRPC } from '../types/worker'
22+import * as worker from './worker'
33+import forks from './workers/forks'
44+import threads from './workers/threads'
55+66+export async function run(ctx: ContextRPC): Promise<void> {
77+ await worker.execute('run', ctx, ctx.pool === 'forks' ? forks : threads)
88+}
99+1010+export async function collect(ctx: ContextRPC): Promise<void> {
1111+ await worker.execute('collect', ctx, ctx.pool === 'forks' ? forks : threads)
1212+}
1313+1414+export async function teardown(): Promise<void> {
1515+ await worker.teardown()
1616+}
+16
packages/vitest/src/runtime/worker-vm.ts
···11+import type { ContextRPC } from '../types/worker'
22+import * as worker from './worker'
33+import vmForks from './workers/vmForks'
44+import vmThreads from './workers/vmThreads'
55+66+export async function run(ctx: ContextRPC): Promise<void> {
77+ await worker.execute('run', ctx, ctx.pool === 'vmForks' ? vmForks : vmThreads)
88+}
99+1010+export async function collect(ctx: ContextRPC): Promise<void> {
1111+ await worker.execute('collect', ctx, ctx.pool === 'vmForks' ? vmForks : vmThreads)
1212+}
1313+1414+export async function teardown(): Promise<void> {
1515+ await worker.teardown()
1616+}
+5-35
packages/vitest/src/runtime/worker.ts
···11import type { ModuleRunner } from 'vite/module-runner'
22import type { ContextRPC, WorkerGlobalState } from '../types/worker'
33import type { VitestWorker } from './workers/types'
44-import { pathToFileURL } from 'node:url'
54import { createStackString, parseStacktrace } from '@vitest/utils/source-map'
65import { EvaluatedModules } from 'vite/module-runner'
76import { loadEnvironment } from '../integrations/env/loader'
88-import { addCleanupListener, cleanup as cleanupWorker } from './cleanup'
97import { setupInspect } from './inspector'
108import { createRuntimeRpc, rpcDone } from './rpc'
119import { isChildProcess } from './utils'
···2927}
30283129const resolvingModules = new Set<string>()
3030+const globalListeners = new Set<() => unknown>()
32313332// this is what every pool executes when running tests
3434-async function execute(method: 'run' | 'collect', ctx: ContextRPC) {
3333+export async function execute(method: 'run' | 'collect', ctx: ContextRPC, worker: VitestWorker): Promise<void> {
3534 disposeInternalListeners()
36353736 const prepareStart = performance.now()
···4544 let environmentLoader: ModuleRunner | undefined
46454746 try {
4848- // worker is a filepath or URL to a file that exposes a default export with "getRpcOptions" and "runTests" methods
4949- if (ctx.worker[0] === '.') {
5050- throw new Error(
5151- `Path to the test runner cannot be relative, received "${ctx.worker}"`,
5252- )
5353- }
5454-5555- const file = ctx.worker.startsWith('file:')
5656- ? ctx.worker
5757- : pathToFileURL(ctx.worker).toString()
5858- const testRunnerModule = await import(file)
5959-6060- if (
6161- !testRunnerModule.default
6262- || typeof testRunnerModule.default !== 'object'
6363- ) {
6464- throw new TypeError(
6565- `Test worker object should be exposed as a default export. Received "${typeof testRunnerModule.default}"`,
6666- )
6767- }
6868-6969- const worker = testRunnerModule.default as VitestWorker
7047 if (!worker.getRpcOptions || typeof worker.getRpcOptions !== 'function') {
7148 throw new TypeError(
7249 `Test worker should expose "getRpcOptions" method. Received "${typeof worker.getRpcOptions}".`,
···10178 prepare: prepareStart,
10279 },
10380 rpc,
104104- onCleanup: listener => addCleanupListener(listener),
8181+ onCleanup: listener => globalListeners.add(listener),
10582 providedContext: ctx.providedContext,
10683 onFilterStackTrace(stack) {
10784 return createStackString(parseStacktrace(stack))
···127104 }
128105}
129106130130-export function run(ctx: ContextRPC): Promise<void> {
131131- return execute('run', ctx)
132132-}
133133-134134-export function collect(ctx: ContextRPC): Promise<void> {
135135- return execute('collect', ctx)
136136-}
137137-138107export async function teardown(): Promise<void> {
139139- return cleanupWorker()
108108+ const promises = [...globalListeners].map(l => l())
109109+ await Promise.all(promises)
140110}
141111142112function createImportMetaEnvProxy(): WorkerGlobalState['metaEnv'] {
+2-2
packages/vitest/src/typecheck/typechecker.ts
···11+import type { EachMapping } from '@jridgewell/trace-mapping'
12import type { File, Task, TaskEventPack, TaskResultPack, TaskState } from '@vitest/runner'
23import type { ParsedStack, TestError } from '@vitest/utils'
33-import type { EachMapping } from '@vitest/utils/source-map'
44import type { ChildProcess } from 'node:child_process'
55import type { Result } from 'tinyexec'
66import type { Vitest } from '../node/core'
···1010import type { TscErrorInfo } from './types'
1111import os from 'node:os'
1212import { performance } from 'node:perf_hooks'
1313-import { eachMapping, generatedPositionFor, TraceMap } from '@vitest/utils/source-map'
1313+import { eachMapping, generatedPositionFor, TraceMap } from '@jridgewell/trace-mapping'
1414import { basename, join, resolve } from 'pathe'
1515import { x } from 'tinyexec'
1616import { distDir } from '../paths'
···11-export { getCallLastIndex, nanoid, notNullish } from '@vitest/utils'
11+export { getCallLastIndex, nanoid, notNullish } from '@vitest/utils/helpers'
2233export function groupBy<T, K extends string | number | symbol>(
44 collection: T[],
+1-1
packages/vitest/src/utils/colors.ts
···11import type { Colors } from 'tinyrainbow'
22-import { highlight } from '@vitest/utils'
22+import { highlight } from '@vitest/utils/highlight'
33import { extname } from 'pathe'
44import c from 'tinyrainbow'
55
+1-1
packages/vitest/src/utils/source-map.ts
···22 lineSplitRE,
33 offsetToLineNumber,
44 positionToOffset,
55-} from '@vitest/utils'
55+} from '@vitest/utils/offset'
66export {
77 defaultStackIgnorePatterns,
88 parseErrorStacktrace,
+1-1
packages/vitest/src/utils/tasks.ts
···11import type { File, Suite, Task, TaskEventPack, TaskResultPack } from '@vitest/runner'
22import type { Arrayable } from '../types/general'
33import { getTests } from '@vitest/runner/utils'
44-import { toArray } from '@vitest/utils'
44+import { toArray } from '@vitest/utils/helpers'
5566export function hasBenchmark(suite: Arrayable<Suite>): boolean {
77 return toArray(suite).some(s =>
+1-1
packages/vitest/src/utils/timers.ts
···11-export { getSafeTimers } from '@vitest/utils'
11+export { getSafeTimers } from '@vitest/utils/timers'
···11import { describe, expect, test, vi } from 'vitest'
22-import { createDefer } from '@vitest/utils'
22+import { createDefer } from '@vitest/utils/helpers'
3344// 3 tests depend on each other,
55// so they will deadlock when maxConcurrency < 3
+11-19
packages/browser/src/client/tester/runner.ts
···44import { globalChannel, onCancel } from '@vitest/browser/client'
55import { page, userEvent } from '@vitest/browser/context'
66import {
77+ DecodedMap,
88+ getOriginalPosition,
79 loadDiffConfig,
810 loadSnapshotSerializers,
99- originalPositionFor,
1011 takeCoverageInsideWorker,
1111- TraceMap,
1212} from 'vitest/internal/browser'
1313import { NodeBenchmarkRunner, VitestTestRunner } from 'vitest/runners'
1414import { createStackString, parseStacktrace } from '../../../../utils/src/source-map'
···154154 return rpc().onTaskAnnotate(test.id, annotation)
155155 }
156156157157- const traceMap = new TraceMap(map as any)
158158- const { line, column, source } = originalPositionFor(traceMap, annotation.location)
159159- if (line != null && column != null && source != null) {
160160- let file: string = annotation.location.file
161161- if (source) {
162162- const fileUrl = annotation.location.file.startsWith('file://')
163163- ? annotation.location.file
164164- : `file://${annotation.location.file}`
165165- const sourceRootUrl = map.sourceRoot
166166- ? new URL(map.sourceRoot, fileUrl)
167167- : fileUrl
168168- file = new URL(source, sourceRootUrl).pathname
169169- }
170170-157157+ const traceMap = new DecodedMap(map as any, annotation.location.file)
158158+ const position = getOriginalPosition(traceMap, annotation.location)
159159+ if (position) {
160160+ const { source, column, line } = position
161161+ const file = source || annotation.location.file
171162 annotation.location = {
172163 line,
173164 column: column + 1,
···261252 if (!result) {
262253 return null
263254 }
264264- return new TraceMap(result as any)
255255+ return new DecodedMap(result as any, file)
265256}
266257267258async function updateTestFilesLocations(files: File[], sourceMaps: Map<string, any>) {
···272263 }
273264 const updateLocation = (task: Task) => {
274265 if (task.location) {
275275- const { line, column } = originalPositionFor(traceMap, task.location)
276276- if (line != null && column != null) {
266266+ const position = getOriginalPosition(traceMap, task.location)
267267+ if (position) {
268268+ const { line, column } = position
277269 task.location = { line, column: task.each ? column : column + 1 }
278270 }
279271 }
+6-6
packages/browser/src/client/tester/snapshot.ts
···11import type { VitestBrowserClient } from '@vitest/browser/client'
22import type { ParsedStack } from 'vitest/internal/browser'
33import type { SnapshotEnvironment } from 'vitest/snapshot'
44-import { originalPositionFor, TraceMap } from 'vitest/internal/browser'
44+import { DecodedMap, getOriginalPosition } from 'vitest/internal/browser'
5566export class VitestBrowserSnapshotEnvironment implements SnapshotEnvironment {
77 private sourceMaps = new Map<string, any>()
88- private traceMaps = new Map<string, TraceMap>()
88+ private traceMaps = new Map<string, DecodedMap>()
991010 public addSourceMap(filepath: string, map: any): void {
1111 this.sourceMaps.set(filepath, map)
···4646 }
4747 let traceMap = this.traceMaps.get(stack.file)
4848 if (!traceMap) {
4949- traceMap = new TraceMap(map)
4949+ traceMap = new DecodedMap(map, stack.file)
5050 this.traceMaps.set(stack.file, traceMap)
5151 }
5252- const { line, column } = originalPositionFor(traceMap, stack)
5353- if (line != null && column != null) {
5454- return { ...stack, line, column }
5252+ const position = getOriginalPosition(traceMap, stack)
5353+ if (position) {
5454+ return { ...stack, line: position.line, column: position.column }
5555 }
5656 return stack
5757 }
···22import type { Arrayable } from '@vitest/utils'
33import type { CollectFilteredTests, CollectorInfo, Filter, FilteredTests } from '~/composables/explorer/types'
44import { isTestCase } from '@vitest/runner/utils'
55-import { toArray } from '@vitest/utils'
55+import { toArray } from '@vitest/utils/helpers'
66import { client, findById } from '~/composables/client'
77import { testRunState } from '~/composables/client/state'
88import { expandNodesOnEndRun } from '~/composables/explorer/expand'
+1-1
packages/vitest/src/integrations/chai/poll.ts
···11import type { Assertion, ExpectStatic } from '@vitest/expect'
22import type { Test } from '@vitest/runner'
33import { chai } from '@vitest/expect'
44-import { getSafeTimers } from '@vitest/utils'
44+import { getSafeTimers } from '@vitest/utils/timers'
55import { getWorkerState } from '../../runtime/utils'
6677// these matchers are not supported because they don't make sense with poll
+1-1
packages/vitest/src/integrations/env/node.ts
···1111 'Uint8Array',
1212])
13131414-const nodeGlobals = new Map()
1414+const nodeGlobals = new Map<string, PropertyDescriptor>()
15151616function populateNodeGlobals() {
1717 if (nodeGlobals.size !== 0) {
+1-1
packages/vitest/src/node/browser/sessions.ts
···11import type { TestProject } from '../project'
22import type { BrowserServerStateSession } from '../types/browser'
33-import { createDefer } from '@vitest/utils'
33+import { createDefer } from '@vitest/utils/helpers'
4455export class BrowserSessions {
66 private sessions = new Map<string, BrowserServerStateSession>()
+1-1
packages/vitest/src/node/cache/index.ts
···11import type { SuiteResultCache } from './results'
22-import { slash } from '@vitest/utils'
22+import { slash } from '@vitest/utils/helpers'
33import { resolve } from 'pathe'
44import { hash } from '../hash'
55import { FilesStatsCache } from './files'
+1-1
packages/vitest/src/node/cli/cac.ts
···22import type { VitestRunMode } from '../types/config'
33import type { CliOptions } from './cli-api'
44import type { CLIOption, CLIOptions as CLIOptionsConfig } from './cli-config'
55-import { toArray } from '@vitest/utils'
55+import { toArray } from '@vitest/utils/helpers'
66import cac from 'cac'
77import { normalize } from 'pathe'
88import c from 'tinyrainbow'
+1-1
packages/vitest/src/node/config/resolveConfig.ts
···1010import type { BaseCoverageOptions, CoverageReporterWithOptions } from '../types/coverage'
1111import type { BuiltinPool, ForksOptions, PoolOptions, ThreadsOptions } from '../types/pool-options'
1212import crypto from 'node:crypto'
1313-import { slash, toArray } from '@vitest/utils'
1313+import { slash, toArray } from '@vitest/utils/helpers'
1414import { resolveModule } from 'local-pkg'
1515import { normalize, relative, resolve } from 'pathe'
1616import c from 'tinyrainbow'
···11import type { DevEnvironment } from 'vite'
22import { existsSync } from 'node:fs'
33import path from 'node:path'
44-import { cleanUrl, withTrailingSlash, wrapId } from '@vitest/utils'
44+import { cleanUrl, withTrailingSlash, wrapId } from '@vitest/utils/helpers'
5566// this is copy pasted from vite
77export function normalizeResolvedIdToUrl(
+1-1
packages/vitest/src/node/plugins/cssEnabler.ts
···11import type { Plugin as VitePlugin } from 'vite'
22import type { CSSModuleScopeStrategy, ResolvedConfig } from '../types/config'
33-import { toArray } from '@vitest/utils'
33+import { toArray } from '@vitest/utils/helpers'
44import { relative } from 'pathe'
55import { generateCssFilenameHash } from '../../integrations/css/css-modules'
66
+1-5
packages/vitest/src/node/plugins/index.ts
···11import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite'
22import type { ResolvedConfig, UserConfig } from '../types/config'
33-import {
44- deepClone,
55- deepMerge,
66- notNullish,
77-} from '@vitest/utils'
33+import { deepClone, deepMerge, notNullish } from '@vitest/utils/helpers'
84import { relative } from 'pathe'
95import * as vite from 'vite'
106import { defaultPort } from '../../constants'
···11import type { Plugin } from 'vite'
22-import { cleanUrl } from '@vitest/utils'
22+import { cleanUrl } from '@vitest/utils/helpers'
33import MagicString from 'magic-string'
44import { stripLiteral } from 'strip-literal'
55
+1-1
packages/vitest/src/node/plugins/publicConfig.ts
···33 UserConfig as ViteUserConfig,
44} from 'vite'
55import type { ResolvedConfig, UserConfig } from '../types/config'
66-import { deepClone, slash } from '@vitest/utils'
66+import { deepClone, slash } from '@vitest/utils/helpers'
77import { findUp } from 'find-up'
88import { resolve } from 'pathe'
99import { mergeConfig, resolveConfig as resolveViteConfig } from 'vite'
+1-1
packages/vitest/src/node/plugins/workspace.ts
···22import type { TestProject } from '../project'
33import type { BrowserConfigOptions, ResolvedConfig, TestProjectInlineConfiguration } from '../types/config'
44import { existsSync, readFileSync } from 'node:fs'
55-import { deepMerge } from '@vitest/utils'
55+import { deepMerge } from '@vitest/utils/helpers'
66import { basename, dirname, relative, resolve } from 'pathe'
77import * as vite from 'vite'
88import { configDefaults } from '../../defaults'
···66import type { TestSpecification } from '../spec'
77import type { TestRunEndReason } from '../types/reporter'
88import { hasFailed } from '@vitest/runner/utils'
99-import { createDefer } from '@vitest/utils'
99+import { createDefer } from '@vitest/utils/helpers'
1010import { Typechecker } from '../../typecheck/typechecker'
1111import { groupBy } from '../../utils/base'
1212
···11import type { Vitest } from '../core'
22import type { TestSpecification } from '../spec'
33import type { TestSequencer } from './types'
44-import { slash } from '@vitest/utils'
44+import { slash } from '@vitest/utils/helpers'
55import { relative, resolve } from 'pathe'
66import { hash } from '../hash'
77
···66import vm from 'node:vm'
77import { AutomockedModule, MockerRegistry, mockObject, RedirectedModule } from '@vitest/mocker'
88import { findMockRedirect } from '@vitest/mocker/redirect'
99-import { highlight } from '@vitest/utils'
109import { distDir } from '../../paths'
11101211const spyModulePath = resolve(distDir, 'spy.js')
···239238 `[vitest] No "${String(prop)}" export is defined on the "${mock.raw}" mock. `
240239 + 'Did you forget to return it from "vi.mock"?'
241240 + '\nIf you need to partially mock a module, you can use "importOriginal" helper inside:\n',
242242- highlight(`vi.mock(import("${mock.raw}"), async (importOriginal) => {
241241+ `vi.mock(import("${mock.raw}"), async (importOriginal) => {
243242 const actual = await importOriginal()
244243 return {
245244 ...actual,
246245 // your mocked methods
247246 }
248248-})`),
247247+})`,
249248 )
250249 }
251250
···55import type { CreateImportMeta } from './moduleRunner'
66import fs from 'node:fs'
77import { isBuiltin } from 'node:module'
88-import { isBareImport } from '@vitest/utils'
88+import { isBareImport } from '@vitest/utils/helpers'
99import { getCachedVitestImport } from './cachedResolver'
1010import { listenForErrors } from './errorCatcher'
1111import { unwrapId, VitestModuleEvaluator } from './moduleEvaluator'
+2-1
packages/vitest/src/runtime/runners/benchmark.ts
···1414 BenchTask,
1515} from '../types/benchmark'
1616import { updateTask as updateRunnerTask } from '@vitest/runner'
1717-import { createDefer, getSafeTimers } from '@vitest/utils'
1717+import { createDefer } from '@vitest/utils/helpers'
1818+import { getSafeTimers } from '@vitest/utils/timers'
1819import { getBenchFn, getBenchOptions } from '../benchmark'
1920import { getWorkerState } from '../utils'
2021
-1
packages/vitest/src/runtime/runners/test.ts
···1212} from '@vitest/runner'
1313import type { ModuleRunner } from 'vite/module-runner'
1414import type { SerializedConfig } from '../config'
1515-// import type { VitestExecutor } from '../execute'
1615import { getState, GLOBAL_EXPECT, setState } from '@vitest/expect'
1716import { getNames, getTestName, getTests } from '@vitest/runner/utils'
1817import { processError } from '@vitest/utils/error'
+2-1
packages/vitest/src/runtime/vm/vite-executor.ts
···44import type { EsmExecutor } from './esm-executor'
55import type { VMModule } from './types'
66import { pathToFileURL } from 'node:url'
77-import { CSS_LANGS_RE, KNOWN_ASSET_RE, toArray } from '@vitest/utils'
77+import { CSS_LANGS_RE, KNOWN_ASSET_RE } from '@vitest/utils/constants'
88+import { toArray } from '@vitest/utils/helpers'
89import { SyntheticModule } from './utils'
9101011interface ViteExecutorOptions {
+1-2
packages/vitest/src/runtime/workers/base.ts
···3737 modules.forEach((module) => {
3838 state.evaluatedModules.invalidateModule(module)
3939 })
4040- // evaluatedModules.delete(fsPath)
4141- // evaluatedModules.delete(`mock:${fsPath}`)
4240 })
4341 }
4442 ctx.files.forEach((i) => {
···6058 ? { filepath: f, testLocations: undefined }
6159 : f,
6260 )
6161+ // we could load @vite/env, but it would take ~8ms, while this takes ~0,02ms
6362 if (ctx.config.serializedDefines) {
6463 try {
6564 runInThisContext(`(() =>{\n${ctx.config.serializedDefines}})()`, {
+20-1
packages/vitest/src/runtime/workers/utils.ts
···22import type { ResolvedConfig, SerializedConfig } from '../../node/types/config'
33import type { WorkerContext } from '../../node/types/worker'
44import type { WorkerRpcOptions } from './types'
55-import { parseRegexp } from '@vitest/utils'
6576const REGEXP_WRAP_PREFIX = '$$vitest:'
87···9089 }
91909291 return config
9292+}
9393+9494+function parseRegexp(input: string): RegExp {
9595+ // Parse input
9696+ // eslint-disable-next-line regexp/no-misleading-capturing-group
9797+ const m = input.match(/(\/?)(.+)\1([a-z]*)/i)
9898+9999+ // match nothing
100100+ if (!m) {
101101+ return /$^/
102102+ }
103103+104104+ // Invalid flags
105105+ // eslint-disable-next-line regexp/optimal-quantifier-concatenation
106106+ if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
107107+ return new RegExp(input)
108108+ }
109109+110110+ // Create the regular expression
111111+ return new RegExp(m[2], m[3])
93112}
···33import type { FormattedBenchmarkResult } from './json-formatter'
44import { stripVTControlCharacters } from 'node:util'
55import { getTests } from '@vitest/runner/utils'
66-import { notNullish } from '@vitest/utils'
66+import { notNullish } from '@vitest/utils/helpers'
77import c from 'tinyrainbow'
88import { F_RIGHT } from '../renderers/figures'
99import { getStateSymbol, truncateString } from '../renderers/utils'
···33import type { Formatter } from 'tinyrainbow'
44import type { TestProject } from '../../project'
55import { stripVTControlCharacters } from 'node:util'
66-import { slash } from '@vitest/utils'
66+import { slash } from '@vitest/utils/helpers'
77import { basename, dirname, isAbsolute, relative } from 'pathe'
88import c from 'tinyrainbow'
99import {