diff --git a/packages/runner/src/utils/index.ts b/packages/runner/src/utils/index.ts index 1e1cf3ae9a89..b1982f10b389 100644 --- a/packages/runner/src/utils/index.ts +++ b/packages/runner/src/utils/index.ts @@ -14,6 +14,8 @@ export { hasTests, hasFailed, getNames, + getFullName, + getTestName, } from './tasks' export { createChainable, type ChainableFunction } from './chain' export { limitConcurrency } from './limit-concurrency' diff --git a/packages/runner/src/utils/tasks.ts b/packages/runner/src/utils/tasks.ts index 3212de13c6b0..226777cad39b 100644 --- a/packages/runner/src/utils/tasks.ts +++ b/packages/runner/src/utils/tasks.ts @@ -71,3 +71,11 @@ export function getNames(task: Task): string[] { return names } + +export function getFullName(task: Task, separator = ' > '): string { + return getNames(task).join(separator) +} + +export function getTestName(task: Task, separator = ' > '): string { + return getNames(task).slice(1).join(separator) +} diff --git a/packages/utils/src/helpers.ts b/packages/utils/src/helpers.ts index b2d053801275..82d3c606db2e 100644 --- a/packages/utils/src/helpers.ts +++ b/packages/utils/src/helpers.ts @@ -290,3 +290,57 @@ export function isNegativeNaN(val: number): boolean { return isNegative } + +function toString(v: any) { + return Object.prototype.toString.call(v) +} + +function isPlainObject(val: any): val is object { + return ( + toString(val) === '[object Object]' + && (!val.constructor || val.constructor.name === 'Object') + ) +} + +function isMergeableObject(item: any): item is object { + return isPlainObject(item) && !Array.isArray(item) +} + +/** + * Deep merge :P + * + * Will merge objects only if they are plain + * + * Do not merge types - it is very expensive and usually it's better to case a type here + */ +export function deepMerge( + target: T, + ...sources: any[] +): T { + if (!sources.length) { + return target as any + } + + const source = sources.shift() + if (source === undefined) { + return target as any + } + + if (isMergeableObject(target) && isMergeableObject(source)) { + (Object.keys(source) as (keyof T)[]).forEach((key) => { + const _source = source as T + if (isMergeableObject(_source[key])) { + if (!target[key]) { + target[key] = {} as any + } + + deepMerge(target[key] as any, _source[key]) + } + else { + target[key] = _source[key] as any + } + }) + } + + return deepMerge(target, ...sources) +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 7793578000dc..285a0d7f00e5 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -16,6 +16,7 @@ export { isNegativeNaN, createSimpleStackTrace, toArray, + deepMerge, } from './helpers' export type { DeferPromise } from './helpers' diff --git a/packages/vitest/src/api/setup.ts b/packages/vitest/src/api/setup.ts index 5cf47139a272..061843e4e6ae 100644 --- a/packages/vitest/src/api/setup.ts +++ b/packages/vitest/src/api/setup.ts @@ -6,11 +6,13 @@ import type { WebSocket } from 'ws' import { WebSocketServer } from 'ws' import type { ViteDevServer } from 'vite' import type { File, TaskResultPack } from '@vitest/runner' +import { isPrimitive, noop } from '@vitest/utils' import { API_PATH } from '../constants' import type { Vitest } from '../node/core' import type { Awaitable, ModuleGraphData, UserConsoleLog } from '../types/general' import type { Reporter } from '../node/types/reporter' -import { getModuleGraph, isPrimitive, noop, stringifyReplace } from '../utils' +import { getModuleGraph } from '../utils/graph' +import { stringifyReplace } from '../utils/serialization' import { parseErrorStacktrace } from '../utils/source-map' import type { SerializedTestSpecification } from '../runtime/types/utils' import type { diff --git a/packages/vitest/src/integrations/chai/index.ts b/packages/vitest/src/integrations/chai/index.ts index 2b2cfcbe912e..48fe08bd3733 100644 --- a/packages/vitest/src/integrations/chai/index.ts +++ b/packages/vitest/src/integrations/chai/index.ts @@ -12,7 +12,7 @@ import { setState, } from '@vitest/expect' import type { Assertion, ExpectStatic, MatcherState } from '@vitest/expect' -import { getTestName } from '../../utils/tasks' +import { getTestName } from '@vitest/runner/utils' import { getCurrentEnvironment, getWorkerState } from '../../runtime/utils' import { createExpectPoll } from './poll' diff --git a/packages/vitest/src/integrations/chai/poll.ts b/packages/vitest/src/integrations/chai/poll.ts index f734ebd3d0b2..dde46da0438d 100644 --- a/packages/vitest/src/integrations/chai/poll.ts +++ b/packages/vitest/src/integrations/chai/poll.ts @@ -1,7 +1,7 @@ import * as chai from 'chai' import type { Assertion, ExpectStatic } from '@vitest/expect' import { getSafeTimers } from '@vitest/utils' -import { getWorkerState } from '../../utils' +import { getWorkerState } from '../../runtime/utils' // these matchers are not supported because they don't make sense with poll const unsupported = [ diff --git a/packages/vitest/src/integrations/mock/timers.ts b/packages/vitest/src/integrations/mock/timers.ts index d985d049a7a1..857f8a5451b1 100644 --- a/packages/vitest/src/integrations/mock/timers.ts +++ b/packages/vitest/src/integrations/mock/timers.ts @@ -11,7 +11,7 @@ import type { InstalledClock, } from '@sinonjs/fake-timers' import { withGlobal } from '@sinonjs/fake-timers' -import { isChildProcess } from '../../utils/base' +import { isChildProcess } from '../../runtime/utils' import { RealDate, mockDate, resetDate } from './date' export class FakeTimers { diff --git a/packages/vitest/src/integrations/snapshot/environments/node.ts b/packages/vitest/src/integrations/snapshot/environments/node.ts index 938a85836ac2..51af0414c4c7 100644 --- a/packages/vitest/src/integrations/snapshot/environments/node.ts +++ b/packages/vitest/src/integrations/snapshot/environments/node.ts @@ -1,5 +1,5 @@ import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment' -import { getWorkerState } from '../../../utils' +import { getWorkerState } from '../../../runtime/utils' export class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment { getHeader(): string { diff --git a/packages/vitest/src/integrations/vi.ts b/packages/vitest/src/integrations/vi.ts index ef8ffbe63535..0b7acaef1221 100644 --- a/packages/vitest/src/integrations/vi.ts +++ b/packages/vitest/src/integrations/vi.ts @@ -4,9 +4,7 @@ import { parseSingleStack } from '../utils/source-map' import type { VitestMocker } from '../runtime/mocker' import type { RuntimeOptions, SerializedConfig } from '../runtime/config' import type { MockFactoryWithHelper, MockOptions } from '../types/mocker' -import { getWorkerState } from '../runtime/utils' -import { resetModules, waitForImportsToResolve } from '../utils/modules' -import { isChildProcess } from '../utils/base' +import { getWorkerState, isChildProcess, resetModules, waitForImportsToResolve } from '../runtime/utils' import { FakeTimers } from './mock/timers' import type { MaybeMocked, diff --git a/packages/vitest/src/node/cache/index.ts b/packages/vitest/src/node/cache/index.ts index d6483db41bfa..5798d31fd1f1 100644 --- a/packages/vitest/src/node/cache/index.ts +++ b/packages/vitest/src/node/cache/index.ts @@ -1,5 +1,5 @@ import { resolve } from 'pathe' -import { slash } from '../../utils' +import { slash } from '@vitest/utils' import { hash } from '../hash' import { FilesStatsCache } from './files' import { ResultsCache } from './results' diff --git a/packages/vitest/src/node/cli/cac.ts b/packages/vitest/src/node/cli/cac.ts index 4a025df52766..5a0fbfb75f0e 100644 --- a/packages/vitest/src/node/cli/cac.ts +++ b/packages/vitest/src/node/cli/cac.ts @@ -1,8 +1,8 @@ import { normalize } from 'pathe' import cac, { type CAC, type Command } from 'cac' import c from 'tinyrainbow' +import { toArray } from '@vitest/utils' import { version } from '../../../package.json' with { type: 'json' } -import { toArray } from '../../utils/base' import type { VitestRunMode } from '../types/config' import type { CliOptions } from './cli-api' import type { CLIOption, CLIOptions as CLIOptionsConfig } from './cli-config' diff --git a/packages/vitest/src/node/cli/cli-api.ts b/packages/vitest/src/node/cli/cli-api.ts index 0735906d71e5..a69cb91e4016 100644 --- a/packages/vitest/src/node/cli/cli-api.ts +++ b/packages/vitest/src/node/cli/cli-api.ts @@ -4,13 +4,13 @@ import { mkdirSync, writeFileSync } from 'node:fs' import { dirname, relative, resolve } from 'pathe' import type { UserConfig as ViteUserConfig } from 'vite' import type { File, Suite, Task } from '@vitest/runner' +import { getNames, getTests } from '@vitest/runner/utils' import { CoverageProviderMap } from '../../integrations/coverage' import type { environments } from '../../integrations/env' import { createVitest } from '../create' import { registerConsoleShortcuts } from '../stdin' import type { Vitest, VitestOptions } from '../core' import { FilesNotFoundError, GitNotFoundError } from '../errors' -import { getNames, getTests } from '../../utils' import type { UserConfig, VitestEnvironment, VitestRunMode } from '../types/config' import type { WorkspaceSpec } from '../pool' diff --git a/packages/vitest/src/node/config/resolveConfig.ts b/packages/vitest/src/node/config/resolveConfig.ts index 2a567c8703a8..8d622a7df2a5 100644 --- a/packages/vitest/src/node/config/resolveConfig.ts +++ b/packages/vitest/src/node/config/resolveConfig.ts @@ -2,6 +2,8 @@ import { resolveModule } from 'local-pkg' import { normalize, relative, resolve } from 'pathe' import c from 'tinyrainbow' import type { ResolvedConfig as ResolvedViteConfig } from 'vite' +import { toArray } from '@vitest/utils' +import { isCI, stdProvider } from '../../utils/env' import type { ApiConfig, ResolvedConfig, @@ -15,7 +17,6 @@ import { extraInlineDeps, } from '../../constants' import { benchmarkConfigDefaults, configDefaults } from '../../defaults' -import { isCI, stdProvider, toArray } from '../../utils' import type { BuiltinPool, ForksOptions, PoolOptions, ThreadsOptions } from '../types/pool-options' import { getWorkersCountByPercentage } from '../../utils/workers' import { VitestCache } from '../cache' diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 93d0c885e5ce..efa2f74db554 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -8,14 +8,16 @@ import { SnapshotManager } from '@vitest/snapshot/manager' import type { CancelReason, File, TaskResultPack } from '@vitest/runner' import { ViteNodeServer } from 'vite-node/server' import type { defineWorkspace } from 'vitest/config' +import { noop, slash, toArray } from '@vitest/utils' +import { getTasks, hasFailed } from '@vitest/runner/utils' import { version } from '../../package.json' with { type: 'json' } -import { getTasks, hasFailed, noop, slash, toArray, wildcardPatternToRegExp } from '../utils' import { getCoverageProvider } from '../integrations/coverage' import { workspacesFiles as workspaceFiles } from '../constants' import { WebSocketReporter } from '../api/setup' import type { SerializedCoverageConfig } from '../runtime/config' import type { ArgumentsType, OnServerRestartHandler, ProvidedContext, UserConsoleLog } from '../types/general' import { distDir } from '../paths' +import { wildcardPatternToRegExp } from '../utils/base' import type { ProcessPool, WorkspaceSpec } from './pool' import { createPool, getFilePoolName } from './pool' import { createBenchmarkReporters, createReporters } from './reporters/utils' diff --git a/packages/vitest/src/node/error.ts b/packages/vitest/src/node/error.ts index 80e978e5555e..936281e5f806 100644 --- a/packages/vitest/src/node/error.ts +++ b/packages/vitest/src/node/error.ts @@ -6,19 +6,18 @@ import { normalize, relative } from 'pathe' import c from 'tinyrainbow' import cliTruncate from 'cli-truncate' import type { ErrorWithDiff, ParsedStack } from '@vitest/utils' -import { inspect } from '@vitest/utils' +import { inspect, isPrimitive } from '@vitest/utils' import { lineSplitRE, positionToOffset, } from '../utils/source-map' -import { F_POINTER } from '../utils/figures' import { TypeCheckError } from '../typecheck/typechecker' -import { isPrimitive } from '../utils' import type { Vitest } from './core' import { divider } from './reporters/renderers/utils' import type { ErrorOptions } from './logger' import { Logger } from './logger' import type { WorkspaceProject } from './workspace' +import { F_POINTER } from './reporters/renderers/figures' interface PrintErrorOptions { type?: string diff --git a/packages/vitest/src/node/logger.ts b/packages/vitest/src/node/logger.ts index 74109cd42ed4..08649e4448bd 100644 --- a/packages/vitest/src/node/logger.ts +++ b/packages/vitest/src/node/logger.ts @@ -5,8 +5,8 @@ import c from 'tinyrainbow' import { parseErrorStacktrace } from '@vitest/utils/source-map' import type { Task } from '@vitest/runner' import type { ErrorWithDiff } from '@vitest/utils' +import { toArray } from '@vitest/utils' import type { TypeCheckError } from '../typecheck/typechecker' -import { toArray } from '../utils' import { highlightCode } from '../utils/colors' import { divider } from './reporters/renderers/utils' import { RandomSequencer } from './sequencers/RandomSequencer' diff --git a/packages/vitest/src/node/plugins/cssEnabler.ts b/packages/vitest/src/node/plugins/cssEnabler.ts index dc324c8344fc..62026bd175fa 100644 --- a/packages/vitest/src/node/plugins/cssEnabler.ts +++ b/packages/vitest/src/node/plugins/cssEnabler.ts @@ -1,8 +1,8 @@ import { relative } from 'pathe' import type { Plugin as VitePlugin } from 'vite' +import { toArray } from '@vitest/utils' import { generateCssFilenameHash } from '../../integrations/css/css-modules' import type { CSSModuleScopeStrategy, ResolvedConfig } from '../types/config' -import { toArray } from '../../utils' const cssLangs = '\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss)(?:$|\\?)' const cssLangRE = new RegExp(cssLangs) diff --git a/packages/vitest/src/node/plugins/index.ts b/packages/vitest/src/node/plugins/index.ts index 8de003325712..f9bae896b898 100644 --- a/packages/vitest/src/node/plugins/index.ts +++ b/packages/vitest/src/node/plugins/index.ts @@ -1,13 +1,12 @@ import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite' import { relative } from 'pathe' -import { configDefaults, coverageConfigDefaults } from '../../defaults' -import type { ResolvedConfig, UserConfig } from '../types/config' import { deepMerge, notNullish, - removeUndefinedValues, toArray, -} from '../../utils' +} from '@vitest/utils' +import { configDefaults, coverageConfigDefaults } from '../../defaults' +import type { ResolvedConfig, UserConfig } from '../types/config' import { resolveApiServerConfig } from '../config/resolveConfig' import { Vitest } from '../core' import { generateScopedClassName } from '../../integrations/css/css-modules' @@ -266,3 +265,13 @@ export async function VitestPlugin( NormalizeURLPlugin(), ].filter(notNullish) } +function removeUndefinedValues>( + obj: T, +): T { + for (const key in Object.keys(obj)) { + if (obj[key] === undefined) { + delete obj[key] + } + } + return obj +} diff --git a/packages/vitest/src/node/plugins/workspace.ts b/packages/vitest/src/node/plugins/workspace.ts index 2e1ac385765f..92afa6dfb87d 100644 --- a/packages/vitest/src/node/plugins/workspace.ts +++ b/packages/vitest/src/node/plugins/workspace.ts @@ -1,9 +1,9 @@ import { existsSync, readFileSync } from 'node:fs' import { basename, dirname, relative, resolve } from 'pathe' import type { UserConfig as ViteConfig, Plugin as VitePlugin } from 'vite' +import { deepMerge } from '@vitest/utils' import { configDefaults } from '../../defaults' import { generateScopedClassName } from '../../integrations/css/css-modules' -import { deepMerge } from '../../utils/base' import type { WorkspaceProject } from '../workspace' import type { ResolvedConfig, UserWorkspaceConfig } from '../types/config' import { CoverageTransform } from './coverageTransform' diff --git a/packages/vitest/src/node/pools/forks.ts b/packages/vitest/src/node/pools/forks.ts index 37c832970901..8d3b9a30cb54 100644 --- a/packages/vitest/src/node/pools/forks.ts +++ b/packages/vitest/src/node/pools/forks.ts @@ -4,11 +4,12 @@ import EventEmitter from 'node:events' import { Tinypool } from 'tinypool' import type { TinypoolChannel, Options as TinypoolOptions } from 'tinypool' import { createBirpc } from 'birpc' +import { resolve } from 'pathe' import type { PoolProcessOptions, ProcessPool, RunWithFiles } from '../pool' import type { WorkspaceProject } from '../workspace' import { envsOrder, groupFilesByEnv } from '../../utils/test-helpers' import { wrapSerializableConfig } from '../../utils/config-helpers' -import { groupBy, resolve } from '../../utils' +import { groupBy } from '../../utils/base' import type { SerializedConfig } from '../types/config' import type { RunnerRPC, RuntimeRPC } from '../../types/rpc' import type { Vitest } from '../core' diff --git a/packages/vitest/src/node/pools/threads.ts b/packages/vitest/src/node/pools/threads.ts index 5c7dd5024d32..9d51ef9d6e05 100644 --- a/packages/vitest/src/node/pools/threads.ts +++ b/packages/vitest/src/node/pools/threads.ts @@ -6,7 +6,7 @@ import Tinypool from 'tinypool' import { resolve } from 'pathe' import type { PoolProcessOptions, ProcessPool, RunWithFiles } from '../pool' import { envsOrder, groupFilesByEnv } from '../../utils/test-helpers' -import { AggregateError, groupBy } from '../../utils/base' +import { groupBy } from '../../utils/base' import type { WorkspaceProject } from '../workspace' import type { SerializedConfig } from '../types/config' import type { RunnerRPC, RuntimeRPC } from '../../types/rpc' diff --git a/packages/vitest/src/node/pools/typecheck.ts b/packages/vitest/src/node/pools/typecheck.ts index 5e0e4bdf45df..4bba2cf4ac9b 100644 --- a/packages/vitest/src/node/pools/typecheck.ts +++ b/packages/vitest/src/node/pools/typecheck.ts @@ -1,9 +1,9 @@ import type { DeferPromise } from '@vitest/utils' import { createDefer } from '@vitest/utils' +import { hasFailed } from '@vitest/runner/utils' import type { TypecheckResults } from '../../typecheck/typechecker' import { Typechecker } from '../../typecheck/typechecker' import { groupBy } from '../../utils/base' -import { hasFailed } from '../../utils/tasks' import type { Vitest } from '../core' import type { ProcessPool, WorkspaceSpec } from '../pool' import type { WorkspaceProject } from '../workspace' diff --git a/packages/vitest/src/node/pools/vmForks.ts b/packages/vitest/src/node/pools/vmForks.ts index 249da53e503c..d0023880fcb7 100644 --- a/packages/vitest/src/node/pools/vmForks.ts +++ b/packages/vitest/src/node/pools/vmForks.ts @@ -8,7 +8,6 @@ import Tinypool from 'tinypool' import { rootDir } from '../../paths' import type { PoolProcessOptions, ProcessPool, RunWithFiles } from '../pool' import { groupFilesByEnv } from '../../utils/test-helpers' -import { AggregateError } from '../../utils/base' import type { WorkspaceProject } from '../workspace' import { getWorkerMemoryLimit, stringToBytes } from '../../utils/memory-limit' import { wrapSerializableConfig } from '../../utils/config-helpers' diff --git a/packages/vitest/src/node/pools/vmThreads.ts b/packages/vitest/src/node/pools/vmThreads.ts index 700eab6c0a60..c0ff594220b1 100644 --- a/packages/vitest/src/node/pools/vmThreads.ts +++ b/packages/vitest/src/node/pools/vmThreads.ts @@ -7,7 +7,6 @@ import Tinypool from 'tinypool' import { rootDir } from '../../paths' import type { PoolProcessOptions, ProcessPool, RunWithFiles } from '../pool' import { groupFilesByEnv } from '../../utils/test-helpers' -import { AggregateError } from '../../utils/base' import type { WorkspaceProject } from '../workspace' import { getWorkerMemoryLimit, stringToBytes } from '../../utils/memory-limit' import type { ResolvedConfig, SerializedConfig } from '../types/config' diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index b4c60674ac8e..d355b966e8d4 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -3,23 +3,14 @@ import c from 'tinyrainbow' import { parseStacktrace } from '@vitest/utils/source-map' import { relative } from 'pathe' import type { File, Task, TaskResultPack } from '@vitest/runner' -import { - getFullName, - getSuites, - getTestName, - getTests, - hasFailed, - hasFailedSnapshot, - isCI, - isDeno, - isNode, - relativePath, - toArray, -} from '../../utils' +import { toArray } from '@vitest/utils' +import { getFullName, getSuites, getTestName, getTests, hasFailed } from '@vitest/runner/utils' +import { isCI, isDeno, isNode } from '../../utils/env' import type { Vitest } from '../core' -import { F_POINTER, F_RIGHT } from '../../utils/figures' import type { Reporter } from '../types/reporter' import type { ErrorWithDiff, UserConsoleLog } from '../../types/general' +import { hasFailedSnapshot } from '../../utils/tasks' +import { F_POINTER, F_RIGHT } from './renderers/figures' import { countTestErrors, divider, @@ -89,7 +80,7 @@ export abstract class BaseReporter implements Reporter { } relative(path: string) { - return relativePath(this.ctx.config.root, path) + return relative(this.ctx.config.root, path) } onFinished( diff --git a/packages/vitest/src/node/reporters/benchmark/table/index.ts b/packages/vitest/src/node/reporters/benchmark/table/index.ts index 866a5a1d9019..9e8ca47fe2fd 100644 --- a/packages/vitest/src/node/reporters/benchmark/table/index.ts +++ b/packages/vitest/src/node/reporters/benchmark/table/index.ts @@ -2,9 +2,9 @@ import fs from 'node:fs' import c from 'tinyrainbow' import * as pathe from 'pathe' import type { File, TaskResultPack } from '@vitest/runner' +import { getFullName, getTasks } from '@vitest/runner/utils' import type { UserConsoleLog } from '../../../../types/general' import { BaseReporter } from '../../base' -import { getFullName, getTasks } from '../../../../utils' import { getStateSymbol } from '../../renderers/utils' import type { BenchmarkResult } from '../../../../runtime/types/benchmark' import { diff --git a/packages/vitest/src/node/reporters/benchmark/table/tableRender.ts b/packages/vitest/src/node/reporters/benchmark/table/tableRender.ts index 0d1545a36f55..4534a89d8e54 100644 --- a/packages/vitest/src/node/reporters/benchmark/table/tableRender.ts +++ b/packages/vitest/src/node/reporters/benchmark/table/tableRender.ts @@ -2,11 +2,12 @@ import { stripVTControlCharacters } from 'node:util' import c from 'tinyrainbow' import cliTruncate from 'cli-truncate' import type { Task } from '@vitest/runner' -import { getTests, notNullish } from '../../../../utils' -import { F_RIGHT } from '../../../../utils/figures' +import { notNullish } from '@vitest/utils' +import { getTests } from '@vitest/runner/utils' import type { Logger } from '../../../logger' import { getCols, getStateSymbol } from '../../renderers/utils' import type { BenchmarkResult } from '../../../../runtime/types/benchmark' +import { F_RIGHT } from '../../renderers/figures' import type { FlatBenchmarkReport } from '.' export interface TableRendererOptions { diff --git a/packages/vitest/src/node/reporters/github-actions.ts b/packages/vitest/src/node/reporters/github-actions.ts index f83017f2f75d..e0114d26fc9e 100644 --- a/packages/vitest/src/node/reporters/github-actions.ts +++ b/packages/vitest/src/node/reporters/github-actions.ts @@ -1,7 +1,6 @@ import { stripVTControlCharacters } from 'node:util' -import { getTasks } from '@vitest/runner/utils' +import { getFullName, getTasks } from '@vitest/runner/utils' import type { File } from '@vitest/runner' -import { getFullName } from '../../utils' import { capturePrintError } from '../error' import type { WorkspaceProject } from '../workspace' import type { Reporter } from '../types/reporter' diff --git a/packages/vitest/src/node/reporters/json.ts b/packages/vitest/src/node/reporters/json.ts index b9b335f7ebe5..ca74e9ce1a28 100644 --- a/packages/vitest/src/node/reporters/json.ts +++ b/packages/vitest/src/node/reporters/json.ts @@ -2,7 +2,7 @@ import { existsSync, promises as fs } from 'node:fs' import { dirname, resolve } from 'pathe' import type { File, Suite, TaskMeta, TaskState } from '@vitest/runner' import type { SnapshotSummary } from '@vitest/snapshot' -import { getSuites, getTests } from '../../utils' +import { getSuites, getTests } from '@vitest/runner/utils' import { getOutputFile } from '../../utils/config-helpers' import type { Reporter } from '../types/reporter' import type { Vitest } from '../core' diff --git a/packages/vitest/src/node/reporters/renderers/dotRenderer.ts b/packages/vitest/src/node/reporters/renderers/dotRenderer.ts index 2de99b01a081..c4a02f223aa7 100644 --- a/packages/vitest/src/node/reporters/renderers/dotRenderer.ts +++ b/packages/vitest/src/node/reporters/renderers/dotRenderer.ts @@ -1,6 +1,6 @@ import c from 'tinyrainbow' import type { Task } from '@vitest/runner' -import { getTests } from '../../../utils' +import { getTests } from '@vitest/runner/utils' import type { Logger } from '../../logger' export interface DotRendererOptions { diff --git a/packages/vitest/src/utils/figures.ts b/packages/vitest/src/node/reporters/renderers/figures.ts similarity index 100% rename from packages/vitest/src/utils/figures.ts rename to packages/vitest/src/node/reporters/renderers/figures.ts diff --git a/packages/vitest/src/node/reporters/renderers/listRenderer.ts b/packages/vitest/src/node/reporters/renderers/listRenderer.ts index c08f9a85949a..f70cdb5b7d15 100644 --- a/packages/vitest/src/node/reporters/renderers/listRenderer.ts +++ b/packages/vitest/src/node/reporters/renderers/listRenderer.ts @@ -2,11 +2,12 @@ import { stripVTControlCharacters } from 'node:util' import c from 'tinyrainbow' import cliTruncate from 'cli-truncate' import type { SuiteHooks, Task } from '@vitest/runner' -import { getTests, notNullish } from '../../../utils' -import { F_RIGHT } from '../../../utils/figures' +import { getTests } from '@vitest/runner/utils' +import { notNullish } from '@vitest/utils' import type { Logger } from '../../logger' import type { VitestRunMode } from '../../types/config' import type { Benchmark, BenchmarkResult } from '../../../runtime/types/benchmark' +import { F_RIGHT } from './figures' import { formatProjectName, getCols, diff --git a/packages/vitest/src/node/reporters/renderers/utils.ts b/packages/vitest/src/node/reporters/renderers/utils.ts index 2842dd9f5723..23511d2eb263 100644 --- a/packages/vitest/src/node/reporters/renderers/utils.ts +++ b/packages/vitest/src/node/reporters/renderers/utils.ts @@ -3,7 +3,7 @@ import { basename, dirname, isAbsolute, relative } from 'pathe' import c from 'tinyrainbow' import type { SuiteHooks, Task } from '@vitest/runner' import type { SnapshotSummary } from '@vitest/snapshot' -import { slash } from '../../../utils/base' +import { slash } from '@vitest/utils' import { F_CHECK, F_CROSS, @@ -12,7 +12,7 @@ import { F_DOWN_RIGHT, F_LONG_DASH, F_POINTER, -} from '../../../utils/figures' +} from './figures' export const spinnerMap = new WeakMap string>() export const hookSpinnerMap = new WeakMap string>>() diff --git a/packages/vitest/src/node/reporters/verbose.ts b/packages/vitest/src/node/reporters/verbose.ts index 9f97221c4241..34a1d72a2590 100644 --- a/packages/vitest/src/node/reporters/verbose.ts +++ b/packages/vitest/src/node/reporters/verbose.ts @@ -1,7 +1,7 @@ import c from 'tinyrainbow' import type { TaskResultPack } from '@vitest/runner' -import { getFullName } from '../../utils' -import { F_RIGHT } from '../../utils/figures' +import { getFullName } from '@vitest/runner/utils' +import { F_RIGHT } from './renderers/figures' import { DefaultReporter } from './default' import { formatProjectName, getStateSymbol } from './renderers/utils' diff --git a/packages/vitest/src/node/state.ts b/packages/vitest/src/node/state.ts index eb9963ff51dd..6dbab4da28fe 100644 --- a/packages/vitest/src/node/state.ts +++ b/packages/vitest/src/node/state.ts @@ -1,11 +1,10 @@ import type { File, Task, TaskResultPack } from '@vitest/runner' import { createFileTask } from '@vitest/runner/utils' -import type { AggregateError as AggregateErrorPonyfill } from '../utils/base' import type { UserConsoleLog } from '../types/general' import type { WorkspaceProject } from './workspace' import { TestCase, TestModule, TestSuite } from './reporters/reported-tasks' -export function isAggregateError(err: unknown): err is AggregateErrorPonyfill { +function isAggregateError(err: unknown): err is AggregateError { if (typeof AggregateError !== 'undefined' && err instanceof AggregateError) { return true } diff --git a/packages/vitest/src/node/stdin.ts b/packages/vitest/src/node/stdin.ts index a8604c20a2a3..7d17fd5ca6c4 100644 --- a/packages/vitest/src/node/stdin.ts +++ b/packages/vitest/src/node/stdin.ts @@ -3,8 +3,10 @@ import type { Writable } from 'node:stream' import c from 'tinyrainbow' import prompt from 'prompts' import { relative, resolve } from 'pathe' -import { getTests, isWindows, stdout } from '../utils' -import { toArray } from '../utils/base' +import { toArray } from '@vitest/utils' +import { getTests } from '@vitest/runner/utils' +import { isWindows } from '../utils/env' +import { stdout } from '../utils/base' import type { Vitest } from './core' import { WatchFilter } from './watch-filter' diff --git a/packages/vitest/src/node/watch-filter.ts b/packages/vitest/src/node/watch-filter.ts index 2478a46c8108..df7b215a4091 100644 --- a/packages/vitest/src/node/watch-filter.ts +++ b/packages/vitest/src/node/watch-filter.ts @@ -3,7 +3,7 @@ import type { Writable } from 'node:stream' import { stripVTControlCharacters } from 'node:util' import c from 'tinyrainbow' import { createDefer } from '@vitest/utils' -import { stdout as getStdout } from '../utils' +import { stdout as getStdout } from '../utils/base' const MAX_RESULT_COUNT = 10 const SELECTION_MAX_INDEX = 7 diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index 4139ec194e29..3186b9d46189 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -18,8 +18,8 @@ import type { import { ViteNodeRunner } from 'vite-node/client' import { ViteNodeServer } from 'vite-node/server' import fg from 'fast-glob' +import { deepMerge, nanoid } from '@vitest/utils' import type { Typechecker } from '../typecheck/typechecker' -import { deepMerge, nanoid } from '../utils/base' import { setup } from '../api/setup' import type { ProvidedContext } from '../types/general' import type { diff --git a/packages/vitest/src/runtime/benchmark.ts b/packages/vitest/src/runtime/benchmark.ts index b9bc0f1c22ce..8ecec6e24112 100644 --- a/packages/vitest/src/runtime/benchmark.ts +++ b/packages/vitest/src/runtime/benchmark.ts @@ -2,8 +2,8 @@ import type { Custom } from '@vitest/runner' import { getCurrentSuite } from '@vitest/runner' import { createChainable } from '@vitest/runner/utils' import { noop } from '@vitest/utils' -import { isRunningInBenchmark } from '../utils' import type { BenchFunction, BenchOptions, BenchmarkAPI } from './types/benchmark' +import { getWorkerState } from './utils' const benchFns = new WeakMap() const benchOptsMap = new WeakMap() @@ -21,7 +21,7 @@ export const bench = createBenchmark(function ( fn: BenchFunction = noop, options: BenchOptions = {}, ) { - if (!isRunningInBenchmark()) { + if (getWorkerState().config.mode !== 'benchmark') { throw new Error('`bench()` is only available in benchmark mode.') } diff --git a/packages/vitest/src/runtime/console.ts b/packages/vitest/src/runtime/console.ts index 21794b845b68..d3fe4714a920 100644 --- a/packages/vitest/src/runtime/console.ts +++ b/packages/vitest/src/runtime/console.ts @@ -4,8 +4,8 @@ import { relative } from 'node:path' import { getSafeTimers } from '@vitest/utils' import c from 'tinyrainbow' import { RealDate } from '../integrations/mock/date' -import { getWorkerState } from '../utils' import type { WorkerGlobalState } from '../types/worker' +import { getWorkerState } from './utils' export const UNKNOWN_TEST_ID = '__vitest__unknown_test__' diff --git a/packages/vitest/src/runtime/runBaseTests.ts b/packages/vitest/src/runtime/runBaseTests.ts index 223090f5a25f..7215914e86e7 100644 --- a/packages/vitest/src/runtime/runBaseTests.ts +++ b/packages/vitest/src/runtime/runBaseTests.ts @@ -1,6 +1,5 @@ import { performance } from 'node:perf_hooks' import { collectTests, startTests } from '@vitest/runner' -import { getWorkerState, resetModules } from '../utils' import { vi } from '../integrations/vi' import { startCoverageInsideWorker, @@ -13,6 +12,7 @@ import { setupGlobalEnv, withEnv } from './setup-node' import type { VitestExecutor } from './execute' import { resolveTestRunner } from './runners' import { closeInspector } from './inspector' +import { getWorkerState, resetModules } from './utils' // browser shouldn't call this! export async function run( diff --git a/packages/vitest/src/runtime/runners/benchmark.ts b/packages/vitest/src/runtime/runners/benchmark.ts index 9dad217ed277..1bf002f19466 100644 --- a/packages/vitest/src/runtime/runners/benchmark.ts +++ b/packages/vitest/src/runtime/runners/benchmark.ts @@ -7,7 +7,7 @@ import type { import { updateTask as updateRunnerTask } from '@vitest/runner' import { createDefer, getSafeTimers } from '@vitest/utils' import { getBenchFn, getBenchOptions } from '../benchmark' -import { getWorkerState } from '../../utils' +import { getWorkerState } from '../utils' import type { BenchTask, Benchmark, diff --git a/packages/vitest/src/runtime/runners/test.ts b/packages/vitest/src/runtime/runners/test.ts index 40d739dea011..a89a58837d8f 100644 --- a/packages/vitest/src/runtime/runners/test.ts +++ b/packages/vitest/src/runtime/runners/test.ts @@ -12,13 +12,14 @@ import type { } from '@vitest/runner' import type { ExpectStatic } from '@vitest/expect' import { GLOBAL_EXPECT, getState, setState } from '@vitest/expect' +import { getNames, getTestName, getTests } from '@vitest/runner/utils' import { getSnapshotClient } from '../../integrations/snapshot/chai' import { vi } from '../../integrations/vi' -import { getNames, getTestName, getTests, getWorkerState } from '../../utils' import { createExpect } from '../../integrations/chai/index' import type { SerializedConfig } from '../config' import type { VitestExecutor } from '../execute' import { rpc } from '../rpc' +import { getWorkerState } from '../utils' export class VitestTestRunner implements VitestRunner { private snapshotClient = getSnapshotClient() diff --git a/packages/vitest/src/runtime/setup-node.ts b/packages/vitest/src/runtime/setup-node.ts index b4bd65acaeee..d5ae1d091ea8 100644 --- a/packages/vitest/src/runtime/setup-node.ts +++ b/packages/vitest/src/runtime/setup-node.ts @@ -3,11 +3,12 @@ import util from 'node:util' import timers from 'node:timers' import { installSourcemapsSupport } from 'vite-node/source-map' import { KNOWN_ASSET_TYPES } from 'vite-node/constants' -import { getSafeTimers, getWorkerState } from '../utils' +import { getSafeTimers } from '@vitest/utils' import * as VitestIndex from '../public/index' import { expect } from '../integrations/chai' import { resolveSnapshotEnvironment } from '../integrations/snapshot/environments/resolveSnapshotEnvironment' import type { ResolvedTestEnvironment } from '../types/environment' +import { getWorkerState } from './utils' import { setupCommonEnv } from './setup-common' import type { VitestExecutor } from './execute' import type { SerializedConfig } from './config' diff --git a/packages/vitest/src/runtime/utils.ts b/packages/vitest/src/runtime/utils.ts index fd94dd4cbb05..ca75e7e1208a 100644 --- a/packages/vitest/src/runtime/utils.ts +++ b/packages/vitest/src/runtime/utils.ts @@ -1,8 +1,13 @@ +import type { ModuleCacheMap } from 'vite-node/client' + +import { getSafeTimers } from '@vitest/utils' import type { WorkerGlobalState } from '../types/worker' +const NAME_WORKER_STATE = '__vitest_worker__' + export function getWorkerState(): WorkerGlobalState { // @ts-expect-error untyped global - const workerState = globalThis.__vitest_worker__ + const workerState = globalThis[NAME_WORKER_STATE] if (!workerState) { const errorMsg = 'Vitest failed to access its internal state.' @@ -16,7 +21,7 @@ export function getWorkerState(): WorkerGlobalState { } export function provideWorkerState(context: any, state: WorkerGlobalState) { - Object.defineProperty(context, '__vitest_worker__', { + Object.defineProperty(context, NAME_WORKER_STATE, { value: state, configurable: true, writable: true, @@ -30,3 +35,59 @@ export function getCurrentEnvironment(): string { const state = getWorkerState() return state?.environment.name } + +export function isChildProcess(): boolean { + return typeof process !== 'undefined' && !!process.send +} + +export function setProcessTitle(title: string) { + try { + process.title = `node (${title})` + } + catch {} +} + +export function resetModules(modules: ModuleCacheMap, resetMocks = false) { + const skipPaths = [ + // Vitest + /\/vitest\/dist\//, + /\/vite-node\/dist\//, + // yarn's .store folder + /vitest-virtual-\w+\/dist/, + // cnpm + /@vitest\/dist/, + // don't clear mocks + ...(!resetMocks ? [/^mock:/] : []), + ] + modules.forEach((mod, path) => { + if (skipPaths.some(re => re.test(path))) { + return + } + modules.invalidateModule(mod) + }) +} + +function waitNextTick() { + const { setTimeout } = getSafeTimers() + return new Promise(resolve => setTimeout(resolve, 0)) +} + +export async function waitForImportsToResolve() { + await waitNextTick() + const state = getWorkerState() + const promises: Promise[] = [] + let resolvingCount = 0 + for (const mod of state.moduleCache.values()) { + if (mod.promise && !mod.evaluated) { + promises.push(mod.promise) + } + if (mod.resolving) { + resolvingCount++ + } + } + if (!promises.length && !resolvingCount) { + return + } + await Promise.allSettled(promises) + await waitForImportsToResolve() +} diff --git a/packages/vitest/src/runtime/worker.ts b/packages/vitest/src/runtime/worker.ts index aae84c8c747c..46d4ec6f0f8c 100644 --- a/packages/vitest/src/runtime/worker.ts +++ b/packages/vitest/src/runtime/worker.ts @@ -2,8 +2,8 @@ import { pathToFileURL } from 'node:url' import { workerId as poolId } from 'tinypool' import { ModuleCacheMap } from 'vite-node/client' import { loadEnvironment } from '../integrations/env/loader' -import { isChildProcess, setProcessTitle } from '../utils/base' import type { ContextRPC, WorkerGlobalState } from '../types/worker' +import { isChildProcess, setProcessTitle } from './utils' import { setupInspect } from './inspector' import { createRuntimeRpc, rpcDone } from './rpc' import type { VitestWorker } from './workers/types' diff --git a/packages/vitest/src/runtime/workers/vm.ts b/packages/vitest/src/runtime/workers/vm.ts index 3bf9ff9f59e6..46f6c7b23205 100644 --- a/packages/vitest/src/runtime/workers/vm.ts +++ b/packages/vitest/src/runtime/workers/vm.ts @@ -8,7 +8,7 @@ import { getDefaultRequestStubs, startVitestExecutor } from '../execute' import { distDir } from '../../paths' import { ExternalModulesExecutor } from '../external-executor' import { FileMap } from '../vm/file-map' -import { provideWorkerState } from '../../utils' +import { provideWorkerState } from '../utils' const entryFile = pathToFileURL(resolve(distDir, 'workers/runVmTests.js')).href diff --git a/packages/vitest/src/typecheck/assertType.ts b/packages/vitest/src/typecheck/assertType.ts index 09300e51b581..04f0440ccc77 100644 --- a/packages/vitest/src/typecheck/assertType.ts +++ b/packages/vitest/src/typecheck/assertType.ts @@ -1,7 +1,5 @@ -function noop() {} - export interface AssertType { (value: T): void } -export const assertType: AssertType = noop +export const assertType: AssertType = function assertType() {} diff --git a/packages/vitest/src/typecheck/typechecker.ts b/packages/vitest/src/typecheck/typechecker.ts index 29bfa30ca8a3..a7066a21b77d 100644 --- a/packages/vitest/src/typecheck/typechecker.ts +++ b/packages/vitest/src/typecheck/typechecker.ts @@ -7,7 +7,7 @@ import type { RawSourceMap } from '@ampproject/remapping' import type { ParsedStack } from '@vitest/utils' import type { File, Task, TaskResultPack, TaskState } from '@vitest/runner' import { x } from 'tinyexec' -import { getTasks } from '../utils' +import { getTasks } from '@vitest/runner/utils' import type { WorkspaceProject } from '../node/workspace' import type { Awaitable } from '../types/general' import type { Vitest } from '../node/core' diff --git a/packages/vitest/src/utils.ts b/packages/vitest/src/utils.ts deleted file mode 100644 index 776f5efcc096..000000000000 --- a/packages/vitest/src/utils.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './utils/index' diff --git a/packages/vitest/src/utils/base.ts b/packages/vitest/src/utils/base.ts index 8ed0c97ef5c6..a4eb03b73054 100644 --- a/packages/vitest/src/utils/base.ts +++ b/packages/vitest/src/utils/base.ts @@ -1,27 +1,5 @@ -import type { Arrayable, Nullable } from '../types/general' - export { notNullish, getCallLastIndex, nanoid } from '@vitest/utils' -export interface GlobalConstructors { - Object: ObjectConstructor - Function: FunctionConstructor - RegExp: RegExpConstructor - Array: ArrayConstructor - Map: MapConstructor -} - -function collectOwnProperties( - obj: any, - collector: Set | ((key: string | symbol) => void), -) { - const collect - = typeof collector === 'function' - ? collector - : (key: string | symbol) => collector.add(key) - Object.getOwnPropertyNames(obj).forEach(collect) - Object.getOwnPropertySymbols(obj).forEach(collect) -} - export function groupBy( collection: T[], iteratee: (item: T) => K, @@ -34,164 +12,12 @@ export function groupBy( }, {} as Record) } -export function isPrimitive(value: unknown) { - return ( - value === null || (typeof value !== 'function' && typeof value !== 'object') - ) -} - -export function getAllMockableProperties( - obj: any, - isModule: boolean, - constructors: GlobalConstructors, -) { - const { Map, Object, Function, RegExp, Array } = constructors - - const allProps = new Map< - string | symbol, - { key: string | symbol; descriptor: PropertyDescriptor } - >() - let curr = obj - do { - // we don't need properties from these - if ( - curr === Object.prototype - || curr === Function.prototype - || curr === RegExp.prototype - ) { - break - } - - collectOwnProperties(curr, (key) => { - const descriptor = Object.getOwnPropertyDescriptor(curr, key) - if (descriptor) { - allProps.set(key, { key, descriptor }) - } - }) - // eslint-disable-next-line no-cond-assign - } while ((curr = Object.getPrototypeOf(curr))) - // default is not specified in ownKeys, if module is interoped - if (isModule && !allProps.has('default') && 'default' in obj) { - const descriptor = Object.getOwnPropertyDescriptor(obj, 'default') - if (descriptor) { - allProps.set('default', { key: 'default', descriptor }) - } - } - return Array.from(allProps.values()) -} - -export function slash(str: string) { - return str.replace(/\\/g, '/') -} - -export function noop() {} - -export function getType(value: unknown): string { - return Object.prototype.toString.apply(value).slice(8, -1) -} - -/** - * Convert `Arrayable` to `Array` - * - * @category Array - */ - -export function toArray(array?: Nullable>): Array { - if (array === null || array === undefined) { - array = [] - } - - if (Array.isArray(array)) { - return array - } - - return [array] -} - -export function toString(v: any) { - return Object.prototype.toString.call(v) -} -export function isPlainObject(val: any): val is object { - return ( - toString(val) === '[object Object]' - && (!val.constructor || val.constructor.name === 'Object') - ) -} - -export function isObject(item: unknown): boolean { - return item != null && typeof item === 'object' && !Array.isArray(item) -} - -/** - * Deep merge :P - * - * Will merge objects only if they are plain - * - * Do not merge types - it is very expensive and usually it's better to case a type here - */ -export function deepMerge( - target: T, - ...sources: any[] -): T { - if (!sources.length) { - return target as any - } - - const source = sources.shift() - if (source === undefined) { - return target as any - } - - if (isMergeableObject(target) && isMergeableObject(source)) { - (Object.keys(source) as (keyof T)[]).forEach((key) => { - const _source = source as T - if (isMergeableObject(_source[key])) { - if (!target[key]) { - target[key] = {} as any - } - - deepMerge(target[key] as any, _source[key]) - } - else { - target[key] = _source[key] as any - } - }) - } - - return deepMerge(target, ...sources) -} - -function isMergeableObject(item: any): item is object { - return isPlainObject(item) && !Array.isArray(item) -} - export function stdout(): NodeJS.WriteStream { // @ts-expect-error Node.js maps process.stdout to console._stdout // eslint-disable-next-line no-console return console._stdout || process.stdout } -// AggregateError is supported in Node.js 15.0.0+ -class AggregateErrorPonyfill extends Error { - errors: unknown[] - constructor(errors: Iterable, message = '') { - super(message) - this.errors = [...errors] - } -} -export { AggregateErrorPonyfill as AggregateError } - -export function isChildProcess(): boolean { - return typeof process !== 'undefined' && !!process.send -} - -export function setProcessTitle(title: string) { - try { - process.title = `node (${title})` - } - catch {} -} - export function escapeRegExp(s: string) { // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string diff --git a/packages/vitest/src/utils/index.ts b/packages/vitest/src/utils/index.ts deleted file mode 100644 index 39e9cc847ba8..000000000000 --- a/packages/vitest/src/utils/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { relative } from 'pathe' -import { getWorkerState } from '../utils' - -export * from './graph' -export * from './tasks' -export * from './base' -export * from '../runtime/utils' -export * from './timers' -export * from './env' -export * from './modules' -export * from './serialization' -export { isWindows } from './env' - -export function getRunMode() { - return getWorkerState().config.mode -} -export function isRunningInTest() { - return getRunMode() === 'test' -} -export function isRunningInBenchmark() { - return getRunMode() === 'benchmark' -} - -export const relativePath = relative -export { resolve } from 'pathe' - -export function removeUndefinedValues>( - obj: T, -): T { - for (const key in Object.keys(obj)) { - if (obj[key] === undefined) { - delete obj[key] - } - } - return obj -} - -/** - * @deprecated import from `@vitest/utils` instead - */ -export function objectAttr( - source: any, - path: string, - defaultValue = undefined, -) { - // a[3].b -> a.3.b - const paths = path.replace(/\[(\d+)\]/g, '.$1').split('.') - let result = source - for (const p of paths) { - result = (new Object(result) as any)[p] - if (result === undefined) { - return defaultValue - } - } - return result -} diff --git a/packages/vitest/src/utils/modules.ts b/packages/vitest/src/utils/modules.ts deleted file mode 100644 index fc8e39017325..000000000000 --- a/packages/vitest/src/utils/modules.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { ModuleCacheMap } from 'vite-node/client' - -import { getWorkerState } from '../runtime/utils' -import { getSafeTimers } from './timers' - -export function resetModules(modules: ModuleCacheMap, resetMocks = false) { - const skipPaths = [ - // Vitest - /\/vitest\/dist\//, - /\/vite-node\/dist\//, - // yarn's .store folder - /vitest-virtual-\w+\/dist/, - // cnpm - /@vitest\/dist/, - // don't clear mocks - ...(!resetMocks ? [/^mock:/] : []), - ] - modules.forEach((mod, path) => { - if (skipPaths.some(re => re.test(path))) { - return - } - modules.invalidateModule(mod) - }) -} - -function waitNextTick() { - const { setTimeout } = getSafeTimers() - return new Promise(resolve => setTimeout(resolve, 0)) -} - -export async function waitForImportsToResolve() { - await waitNextTick() - const state = getWorkerState() - const promises: Promise[] = [] - let resolvingCount = 0 - for (const mod of state.moduleCache.values()) { - if (mod.promise && !mod.evaluated) { - promises.push(mod.promise) - } - if (mod.resolving) { - resolvingCount++ - } - } - if (!promises.length && !resolvingCount) { - return - } - await Promise.allSettled(promises) - await waitForImportsToResolve() -} diff --git a/packages/vitest/src/utils/tasks.ts b/packages/vitest/src/utils/tasks.ts index 54e7d81c64ea..7b06ef52e161 100644 --- a/packages/vitest/src/utils/tasks.ts +++ b/packages/vitest/src/utils/tasks.ts @@ -1,16 +1,7 @@ -import { getNames, getTests } from '@vitest/runner/utils' +import { getTests } from '@vitest/runner/utils' import type { Suite, Task } from '@vitest/runner' +import { toArray } from '@vitest/utils' import type { Arrayable } from '../types/general' -import { toArray } from './base' - -export { - getTasks, - getTests, - getSuites, - hasTests, - hasFailed, - getNames, -} from '@vitest/runner/utils' export function hasBenchmark(suite: Arrayable): boolean { return toArray(suite).some(s => @@ -27,11 +18,3 @@ export function hasFailedSnapshot(suite: Arrayable): boolean { ) }) } - -export function getFullName(task: Task, separator = ' > ') { - return getNames(task).join(separator) -} - -export function getTestName(task: Task, separator = ' > ') { - return getNames(task).slice(1).join(separator) -} diff --git a/packages/ws-client/src/index.ts b/packages/ws-client/src/index.ts index ecd65739426e..34ddf887458e 100644 --- a/packages/ws-client/src/index.ts +++ b/packages/ws-client/src/index.ts @@ -6,6 +6,7 @@ import { parse, stringify } from 'flatted' import type { WebSocketEvents, WebSocketHandlers } from 'vitest' import { StateManager } from './state' +export * from '@vitest/runner/utils' export * from '../../vitest/src/utils/tasks' export interface VitestClientOptions { diff --git a/test/core/test/utils.spec.ts b/test/core/test/utils.spec.ts index c7d7c4067fd6..780b6462c18e 100644 --- a/test/core/test/utils.spec.ts +++ b/test/core/test/utils.spec.ts @@ -1,6 +1,6 @@ import { beforeAll, describe, expect, test } from 'vitest' -import { assertTypes, deepClone, isNegativeNaN, objDisplay, objectAttr, toArray } from '@vitest/utils' -import { deepMerge, resetModules } from '../../../packages/vitest/src/utils' +import { assertTypes, deepClone, deepMerge, isNegativeNaN, objDisplay, objectAttr, toArray } from '@vitest/utils' +import { resetModules } from '../../../packages/vitest/src/runtime/utils' import { deepMergeSnapshot } from '../../../packages/snapshot/src/port/utils' import type { EncodedSourceMap } from '../../../packages/vite-node/src/types' import { ModuleCacheMap } from '../../../packages/vite-node/src/client' diff --git a/test/core/test/vi.spec.ts b/test/core/test/vi.spec.ts index 45a0b632ea85..70d124eff06e 100644 --- a/test/core/test/vi.spec.ts +++ b/test/core/test/vi.spec.ts @@ -4,7 +4,7 @@ import type { Mock, MockInstance, MockedFunction, MockedObject } from 'vitest' import { describe, expect, expectTypeOf, test, vi } from 'vitest' -import { getWorkerState } from '../../../packages/vitest/src/utils' +import { getWorkerState } from '../../../packages/vitest/src/runtime/utils' function expectType(obj: T) { return obj