diff --git a/docs/api/advanced/runner.md b/docs/api/advanced/runner.md index fa41cbc8ac91..1c514acbdc5c 100644 --- a/docs/api/advanced/runner.md +++ b/docs/api/advanced/runner.md @@ -95,7 +95,7 @@ export interface VitestRunner { /** * Publicly available configuration. */ - config: VitestRunnerConfig + config: SerializedConfig /** * The name of the current pool. Can affect how stack trace is inferred on the server side. */ diff --git a/docs/api/advanced/vitest.md b/docs/api/advanced/vitest.md index 8ae0e43dccfb..5d2be64697bf 100644 --- a/docs/api/advanced/vitest.md +++ b/docs/api/advanced/vitest.md @@ -27,7 +27,7 @@ This is a global [`ViteDevServer`](https://vite.dev/guide/api-javascript#vitedev Public `state` is an experimental API (except `vitest.state.getReportedEntity`). Breaking changes might not follow SemVer, please pin Vitest's version when using it. ::: -Global state stores information about the current tests. It uses the same API from `@vitest/runner` by default, but we recommend using the [Reported Tasks API](/api/advanced/reporters#reported-tasks) instead by calling `state.getReportedEntity()` on the `@vitest/runner` API: +Global state stores information about the current tests. It uses internal serializable Task API by default, but we recommend using the [Reported Tasks API](/api/advanced/reporters#reported-tasks) instead by calling `state.getReportedEntity()`: ```ts const task = vitest.state.idMap.get(taskId) // old API diff --git a/packages/browser/package.json b/packages/browser/package.json index d61fcdebbc60..c662b56fe3b3 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -92,7 +92,6 @@ "@types/node": "catalog:", "@types/pngjs": "^6.0.5", "@types/ws": "catalog:", - "@vitest/runner": "workspace:*", "birpc": "catalog:", "flatted": "catalog:", "ivya": "^1.8.2", diff --git a/packages/browser/src/client/channel.ts b/packages/browser/src/client/channel.ts index 687346eaca04..9829a42b39d4 100644 --- a/packages/browser/src/client/channel.ts +++ b/packages/browser/src/client/channel.ts @@ -1,4 +1,5 @@ -import type { CancelReason, FileSpecification } from '@vitest/runner' +import type { CancelReason } from 'vitest' +import type { FileSpecification } from 'vitest/internal/browser' import type { OTELCarrier } from 'vitest/internal/traces' import { getBrowserState } from './utils' diff --git a/packages/browser/src/client/client.ts b/packages/browser/src/client/client.ts index e6830a046439..269bf2cbd2c1 100644 --- a/packages/browser/src/client/client.ts +++ b/packages/browser/src/client/client.ts @@ -1,6 +1,6 @@ import type { ModuleMocker } from '@vitest/mocker/browser' -import type { CancelReason } from '@vitest/runner' import type { BirpcReturn } from 'birpc' +import type { CancelReason } from 'vitest' import type { MarkOptions } from 'vitest/browser' import type { WebSocketBrowserEvents, WebSocketBrowserHandlers } from '../types' import type { IframeOrchestrator } from './orchestrator' diff --git a/packages/browser/src/client/orchestrator.ts b/packages/browser/src/client/orchestrator.ts index 81cf5a354116..73449c10890a 100644 --- a/packages/browser/src/client/orchestrator.ts +++ b/packages/browser/src/client/orchestrator.ts @@ -1,10 +1,12 @@ import type { Context as OTELContext } from '@opentelemetry/api' import type { GlobalChannelIncomingEvent, IframeChannelIncomingEvent, IframeChannelOutgoingEvent, IframeViewportDoneEvent, IframeViewportFailEvent } from '@vitest/browser/client' -import type { FileSpecification } from '@vitest/runner' import type { BrowserTesterOptions, SerializedConfig } from 'vitest' +import type { FileSpecification } from 'vitest/internal/browser' import { channel, client, globalChannel } from '@vitest/browser/client' import { relative } from 'pathe' import { Traces } from 'vitest/internal/traces' +// This needs to be tree shaken properly to not include the whole runner by accident +import { generateFileHash } from '../../../vitest/src/utils/tasks.js' import { getUiAPI } from './ui' import { getBrowserState, getConfig } from './utils' @@ -481,39 +483,6 @@ function generateFileId(file: string) { ) } -// TODO: copied from packages/runner/src/utils/collect.ts -interface HashMeta { - typecheck?: boolean - __vitest_label__?: string -} - -function generateFileHash( - file: string, - projectName: string | undefined, - meta?: HashMeta, -): string { - const seed = [ - file, - projectName || '', - meta?.typecheck ? '__typecheck__' : '', - meta?.__vitest_label__ || '', - ].join('\0') - return generateHash(seed) -} - -function generateHash(str: string): string { - let hash = 0 - if (str.length === 0) { - return `${hash}` - } - for (let i = 0; i < str.length; i++) { - const char = str.charCodeAt(i) - hash = (hash << 5) - hash + char - hash = hash & hash // Convert to 32bit integer - } - return `${hash}` -} - async function setIframeViewport( width: number, height: number, diff --git a/packages/browser/src/client/tester/expect/toMatchScreenshot.ts b/packages/browser/src/client/tester/expect/toMatchScreenshot.ts index b74557a0b416..c714b9e7bf85 100644 --- a/packages/browser/src/client/tester/expect/toMatchScreenshot.ts +++ b/packages/browser/src/client/tester/expect/toMatchScreenshot.ts @@ -1,5 +1,4 @@ -import type { VisualRegressionArtifact } from '@vitest/runner' -import type { AsyncMatcherResult, MatcherState } from 'vitest' +import type { AsyncMatcherResult, MatcherState, VisualRegressionArtifact } from 'vitest' import type { BrowserPage, ScreenshotMatcherOptions } from '../../../../context' import type { ScreenshotMatcherArguments, ScreenshotMatcherOutput } from '../../../shared/screenshotMatcher/types' import type { Locator } from '../locators' diff --git a/packages/browser/src/client/tester/runner.ts b/packages/browser/src/client/tester/runner.ts index c3f08d1c6858..843f10851bd0 100644 --- a/packages/browser/src/client/tester/runner.ts +++ b/packages/browser/src/client/tester/runner.ts @@ -1,21 +1,22 @@ import type { CancelReason, - File, - Suite, - Task, - TaskEventPack, - TaskResultPack, - Test, + RunnerTestFile as File, + SerializedConfig, + RunnerTestSuite as Suite, + RunnerTask as Task, + RunnerTaskEventPack as TaskEventPack, + RunnerTaskResultPack as TaskResultPack, + RunnerTestCase as Test, TestAnnotation, TestArtifact, + TestExecutionMethod, TestTryOptions, - VitestRunner, -} from '@vitest/runner' -import type { SerializedConfig, TestExecutionMethod, WorkerGlobalState } from 'vitest' + VitestTestRunner as VitestRunner, + WorkerGlobalState, +} from 'vitest' import type { VitestBrowserClientMocker } from './mocker' import type { CommandsManager } from './tester-utils' import { globalChannel, onCancel } from '@vitest/browser/client' -import { getTestName } from '@vitest/runner/utils' import { recordArtifact, TestRunner } from 'vitest' import { page, userEvent } from 'vitest/browser' import { @@ -26,6 +27,7 @@ import { takeCoverageInsideWorker, } from 'vitest/internal/browser' import { createStackString, parseStacktrace } from '../../../../utils/src/source-map' +import { getTestName } from '../../../../vitest/src/utils/tasks' import { getBrowserState, getWorkerState, moduleRunner, now } from '../utils' import { rpc } from './rpc' import { VitestBrowserSnapshotEnvironment } from './snapshot' diff --git a/packages/browser/src/client/tester/tester.ts b/packages/browser/src/client/tester/tester.ts index b75d5395cb4f..1bb118591083 100644 --- a/packages/browser/src/client/tester/tester.ts +++ b/packages/browser/src/client/tester/tester.ts @@ -1,5 +1,5 @@ import type { BrowserRPC, IframeChannelEvent } from '@vitest/browser/client' -import type { FileSpecification } from '@vitest/runner' +import type { FileSpecification } from 'vitest/internal/browser' import { channel, client, onCancel, registerPageMarkHandler } from '@vitest/browser/client' import { parse } from 'flatted' import { page, server, userEvent } from 'vitest/browser' diff --git a/packages/browser/src/client/tester/trace.ts b/packages/browser/src/client/tester/trace.ts index 07bf5de28445..853ce0823e40 100644 --- a/packages/browser/src/client/tester/trace.ts +++ b/packages/browser/src/client/tester/trace.ts @@ -1,4 +1,4 @@ -import type { Task } from '@vitest/runner' +import type { RunnerTask as Task } from 'vitest' import type { BrowserTraceEntryKind } from 'vitest/browser' import type { BrowserRPC } from '../client' import type { SerializedLocator } from './locators' diff --git a/packages/browser/src/client/utils.ts b/packages/browser/src/client/utils.ts index 1425fa89b245..bf6c57a1a624 100644 --- a/packages/browser/src/client/utils.ts +++ b/packages/browser/src/client/utils.ts @@ -1,6 +1,5 @@ -import type { VitestRunner } from '@vitest/runner' import type { Ivya } from 'ivya' -import type { SerializedConfig, WorkerGlobalState } from 'vitest' +import type { SerializedConfig, VitestTestRunner, WorkerGlobalState } from 'vitest' import type { OTELCarrier, Traces } from 'vitest/internal/traces' import type { IframeOrchestrator } from './orchestrator' import type { CommandsManager } from './tester/tester-utils' @@ -80,7 +79,7 @@ export interface BrowserRunnerState { runningFiles: string[] config: SerializedConfig provider: string - runner: VitestRunner + runner: VitestTestRunner viteConfig: { root: string } diff --git a/packages/browser/src/node/plugin.ts b/packages/browser/src/node/plugin.ts index b675e16be270..ec7b4dbda0e1 100644 --- a/packages/browser/src/node/plugin.ts +++ b/packages/browser/src/node/plugin.ts @@ -219,7 +219,6 @@ export default (parentServer: ParentBrowserProject, base = '/'): Plugin[] => { '@vitest/browser/client', '@vitest/utils', '@vitest/utils/source-map', - '@vitest/runner', '@vitest/spy', '@vitest/utils/error', 'std-env', diff --git a/packages/browser/src/types.ts b/packages/browser/src/types.ts index 28ccbbd2c2a9..2bfa0e239692 100644 --- a/packages/browser/src/types.ts +++ b/packages/browser/src/types.ts @@ -1,13 +1,16 @@ import type { MockedModuleSerialized, ServerIdResolution, ServerMockResolution } from '@vitest/mocker' -import type { BaselineData, TaskEventPack, TaskResultPack, TestArtifact } from '@vitest/runner' import type { BirpcReturn } from 'birpc' import type { AfterSuiteRunMeta, + BaselineData, BrowserTesterOptions, CancelReason, RunnerTestFile, SerializedTestSpecification, SnapshotResult, + RunnerTaskEventPack as TaskEventPack, + RunnerTaskResultPack as TaskResultPack, + TestArtifact, TestBenchmark, TestExecutionMethod, UserConsoleLog, diff --git a/packages/expect/README.md b/packages/expect/README.md index d3c72567dfa1..9a2c2e05174e 100644 --- a/packages/expect/README.md +++ b/packages/expect/README.md @@ -1,6 +1,6 @@ # @vitest/expect -[![NPM version](https://img.shields.io/npm/v/@vitest/runner?color=a1b858&label=)](https://npmx.dev/package/@vitest/runner) +[![NPM version](https://img.shields.io/npm/v/@vitest/expect?color=a1b858&label=)](https://npmx.dev/package/@vitest/expect) Jest's expect matchers as a Chai plugin. diff --git a/packages/expect/package.json b/packages/expect/package.json index 801d4e834d82..9bdbc4722391 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -46,8 +46,5 @@ "@vitest/utils": "workspace:*", "chai": "catalog:", "tinyrainbow": "catalog:" - }, - "devDependencies": { - "@vitest/runner": "workspace:*" } } diff --git a/packages/expect/src/jest-expect.ts b/packages/expect/src/jest-expect.ts index 1482b413f541..efa993af9ffc 100644 --- a/packages/expect/src/jest-expect.ts +++ b/packages/expect/src/jest-expect.ts @@ -1,6 +1,6 @@ -import type { Test } from '@vitest/runner' import type { MockInstance, MockResult, MockSettledResult } from '@vitest/spy' import type { Constructable } from '@vitest/utils' +import type { Test } from '../../vitest/src/runtime/runner/types' import type { AsymmetricMatcher } from './jest-asymmetric-matchers' import type { Assertion, ChaiPlugin } from './types' import { isMockFunction } from '@vitest/spy' diff --git a/packages/expect/src/jest-extend.ts b/packages/expect/src/jest-extend.ts index 805eb191fec5..6ee2fb53f40b 100644 --- a/packages/expect/src/jest-extend.ts +++ b/packages/expect/src/jest-extend.ts @@ -1,4 +1,4 @@ -import type { Test } from '@vitest/runner' +import type { Test } from '../../vitest/src/runtime/runner/types' import type { ChaiPlugin, ExpectStatic, diff --git a/packages/expect/src/utils.ts b/packages/expect/src/utils.ts index 49138dab7c2e..30e0ad00153a 100644 --- a/packages/expect/src/utils.ts +++ b/packages/expect/src/utils.ts @@ -1,4 +1,4 @@ -import type { Test } from '@vitest/runner/types' +import type { Test } from '../../vitest/src/runtime/runner/types' import type { Assertion } from './types' import { processError } from '@vitest/utils/error' import { noop } from '@vitest/utils/helpers' diff --git a/packages/runner/README.md b/packages/runner/README.md deleted file mode 100644 index 2f6884dd57c1..000000000000 --- a/packages/runner/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# @vitest/runner - -[![NPM version](https://img.shields.io/npm/v/@vitest/runner?color=a1b858&label=)](https://npmx.dev/package/@vitest/runner) - -Vitest mechanism to collect and run tests. - -[GitHub](https://github.com/vitest-dev/vitest/tree/main/packages/runner) | [Documentation](https://vitest.dev/api/advanced/runner) diff --git a/packages/runner/package.json b/packages/runner/package.json deleted file mode 100644 index c3cb24d42617..000000000000 --- a/packages/runner/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@vitest/runner", - "type": "module", - "version": "5.0.0-beta.4", - "description": "Vitest test runner", - "license": "MIT", - "funding": "https://opencollective.com/vitest", - "homepage": "https://vitest.dev/api/advanced/runner", - "repository": { - "type": "git", - "url": "git+https://github.com/vitest-dev/vitest.git", - "directory": "packages/runner" - }, - "bugs": { - "url": "https://github.com/vitest-dev/vitest/issues" - }, - "keywords": [ - "vitest", - "test", - "test-runner" - ], - "sideEffects": true, - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - }, - "./utils": { - "types": "./dist/utils.d.ts", - "default": "./dist/utils.js" - }, - "./types": { - "types": "./dist/types.d.ts", - "default": "./dist/types.js" - }, - "./*": "./*" - }, - "main": "./dist/index.js", - "module": "./dist/index.js", - "types": "./dist/index.d.ts", - "files": [ - "*.d.ts", - "dist" - ], - "scripts": { - "build": "premove dist && rollup -c", - "dev": "rollup -c --watch" - }, - "dependencies": { - "@vitest/utils": "workspace:*", - "pathe": "catalog:", - "tinybench": "catalog:" - } -} diff --git a/packages/runner/rollup.config.js b/packages/runner/rollup.config.js deleted file mode 100644 index b3e2ec683bde..000000000000 --- a/packages/runner/rollup.config.js +++ /dev/null @@ -1,65 +0,0 @@ -import { builtinModules, createRequire } from 'node:module' -import json from '@rollup/plugin-json' -import { defineConfig } from 'rollup' -import oxc from 'unplugin-oxc/rollup' -import { createDtsUtils } from '../../scripts/build-utils.js' - -const require = createRequire(import.meta.url) -const pkg = require('./package.json') - -const external = [ - ...builtinModules, - ...Object.keys(pkg.dependencies || {}), - ...Object.keys(pkg.peerDependencies || {}), - /^@?vitest(\/|$)/, -] - -const entries = { - index: 'src/index.ts', - utils: 'src/utils/index.ts', - types: 'src/types.ts', -} - -const dtsUtils = createDtsUtils() - -const plugins = [ - ...dtsUtils.isolatedDecl(), - oxc({ - transform: { target: 'node20' }, - }), - json(), -] - -export default defineConfig([ - { - input: entries, - output: { - dir: 'dist', - format: 'esm', - entryFileNames: '[name].js', - chunkFileNames: 'chunk-[name].js', - }, - external, - plugins, - onwarn, - }, - { - input: dtsUtils.dtsInput(entries), - output: { - dir: 'dist', - entryFileNames: '[name].d.ts', - format: 'esm', - }, - watch: false, - external, - plugins: dtsUtils.dts(), - onwarn, - }, -]) - -function onwarn(message) { - if (['EMPTY_BUNDLE', 'CIRCULAR_DEPENDENCY'].includes(message.code)) { - return - } - console.error(message) -} diff --git a/packages/runner/src/index.ts b/packages/runner/src/index.ts deleted file mode 100644 index 5d65dde547d2..000000000000 --- a/packages/runner/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -export { recordArtifact } from './artifact' -export { TestSyntaxError } from './errors' -export { - afterAll, - afterEach, - aroundAll, - aroundEach, - beforeAll, - beforeEach, - onTestFailed, - onTestFinished, -} from './hooks' -export { getFn, getHooks, setFn, setHooks } from './map' -export { collectTests, startTests, updateTask } from './run' -export { - createTaskCollector, - describe, - getCurrentSuite, - it, - suite, - test, -} from './suite' -export { getCurrentTest } from './test-state' -export type * from './types' diff --git a/packages/runner/src/types.ts b/packages/runner/src/types.ts deleted file mode 100644 index 4708cbc49344..000000000000 --- a/packages/runner/src/types.ts +++ /dev/null @@ -1,72 +0,0 @@ -export type { - CancelReason, - FileSpecification, - TestTagDefinition, - TestTryOptions, - VitestRunner, - VitestRunnerConfig, - VitestRunnerConstructor, - VitestRunnerImportSource, -} from './types/runner' -export type { - AfterAllListener, - AfterEachListener, - AroundAllListener, - AroundEachListener, - BaselineData, - BeforeAllListener, - BeforeEachListener, - BrowserTraceArtifact, - FailureScreenshotArtifact, - File, - Fixture, - FixtureFn, - FixtureOptions, - Fixtures, - ImportDuration, - InferFixturesTypes, - OnTestFailedHandler, - OnTestFinishedHandler, - Retry, - RunMode, - RuntimeContext, - SequenceHooks, - SequenceSetupFiles, - SerializableRetry, - Suite, - SuiteAPI, - SuiteCollector, - SuiteFactory, - SuiteHooks, - SuiteOptions, - Task, - TaskBase, - TaskCustomOptions, - TaskEventData, - TaskEventPack, - TaskHook, - TaskMeta, - TaskPopulated, - TaskResult, - TaskResultPack, - TaskState, - TaskUpdateEvent, - Test, - TestAnnotation, - TestAnnotationArtifact, - TestAnnotationLocation, - TestAPI, - TestArtifact, - TestArtifactBase, - TestArtifactLocation, - TestArtifactRegistry, - TestAttachment, - TestBenchmark, - TestBenchmarkTask, - TestContext, - TestFunction, - TestOptions, - TestTags, - Use, - VisualRegressionArtifact, -} from './types/tasks' diff --git a/packages/runner/src/types/runner.ts b/packages/runner/src/types/runner.ts deleted file mode 100644 index 1c8ae8d13658..000000000000 --- a/packages/runner/src/types/runner.ts +++ /dev/null @@ -1,251 +0,0 @@ -import type { DiffOptions } from '@vitest/utils/diff' -import type { - File, - ImportDuration, - SequenceHooks, - SequenceSetupFiles, - SerializableRetry, - Suite, - TaskEventPack, - TaskResultPack, - Test, - TestAnnotation, - TestArtifact, - TestContext, - TestOptions, - TestTags, -} from './tasks' - -/** - * This is a subset of Vitest config that's required for the runner to work. - */ -export interface VitestRunnerConfig { - root: string - setupFiles: string[] - name: string | undefined - passWithNoTests: boolean - testNamePattern: RegExp | undefined - allowOnly: boolean - sequence: { - shuffle?: boolean - concurrent?: boolean - seed: number - hooks: SequenceHooks - setupFiles: SequenceSetupFiles - } - chaiConfig: { - truncateThreshold?: number - } | undefined - taskTitleValueFormatTruncate: number - maxConcurrency: number - testTimeout: number - hookTimeout: number - retry: SerializableRetry - includeTaskLocation: boolean | undefined - tags: TestTagDefinition[] - tagsFilter: string[] | undefined - strictTags: boolean - - /** - * @internal - */ - _diffOptions?: DiffOptions - mergeReportsLabel: string | undefined -} - -/** - * Possible options to run a single file in a test. - */ -export interface FileSpecification { - filepath: string - // file can be marked via a jsdoc comment to have tags, - // these are _not_ tags to filter tests by - fileTags?: string[] - testLocations?: number[] | undefined - testNamePattern?: RegExp | undefined - testTagsFilter?: string[] | undefined - testIds?: string[] | undefined -} - -export interface TestTagDefinition extends Omit { - /** - * The name of the tag. This is what you use in the `tags` array in tests. - */ - name: keyof TestTags extends never - ? string - : TestTags[keyof TestTags] - /** - * A description for the tag. This will be shown in the CLI help and UI. - */ - description?: string - /** - * Priority for merging options when multiple tags with the same options are applied to a test. - * - * Lower number means higher priority. E.g., priority 1 takes precedence over priority 3. - */ - priority?: number -} - -export type VitestRunnerImportSource = 'collect' | 'setup' - -export interface VitestRunnerConstructor { - new (config: VitestRunnerConfig): VitestRunner -} - -export type CancelReason - = | 'keyboard-input' - | 'test-failure' - | (string & Record) - -export interface TestTryOptions { - retry: number - repeats: number -} - -export interface VitestRunner { - /** - * First thing that's getting called before actually collecting and running tests. - */ - onBeforeCollect?: (paths: string[]) => unknown - /** - * Called after the file task was created but not collected yet. - */ - onCollectStart?: (file: File) => unknown - /** - * Called after collecting tests and before "onBeforeRun". - */ - onCollected?: (files: File[]) => unknown - - /** - * Called when test runner should cancel next test runs. - * Runner should listen for this method and mark tests and suites as skipped in - * "onBeforeRunSuite" and "onBeforeRunTask" when called. - */ - cancel?: (reason: CancelReason) => unknown - - /** - * Called before running a single test. Doesn't have "result" yet. - */ - onBeforeRunTask?: (test: Test) => unknown - /** - * Called before actually running the test function. Already has "result" with "state" and "startTime". - */ - onBeforeTryTask?: ( - test: Test, - options: TestTryOptions, - ) => unknown - /** - * When the task has finished running, but before cleanup hooks are called - */ - onTaskFinished?: (test: Test) => unknown - /** - * Called after result and state are set. - */ - onAfterRunTask?: (test: Test) => unknown - /** - * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws. - */ - onAfterTryTask?: ( - test: Test, - options: TestTryOptions, - ) => unknown - /** - * Called after the retry resolution happened. Unlike `onAfterTryTask`, the test now has a new state. - * All `after` hooks were also called by this point. - */ - onAfterRetryTask?: ( - test: Test, - options: TestTryOptions, - ) => unknown - - /** - * Called before running a single suite. Doesn't have "result" yet. - */ - onBeforeRunSuite?: (suite: Suite) => unknown - /** - * Called after running a single suite. Has state and result. - */ - onAfterRunSuite?: (suite: Suite) => unknown - - /** - * If defined, will be called instead of usual Vitest suite partition and handling. - * "before" and "after" hooks will not be ignored. - */ - runSuite?: (suite: Suite) => Promise - /** - * If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function. - * "before" and "after" hooks will not be ignored. - */ - runTask?: (test: Test) => Promise - - /** - * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests. - */ - onTaskUpdate?: (task: TaskResultPack[], events: TaskEventPack[]) => Promise - - /** - * Called when annotation is added via the `context.annotate` method. - */ - onTestAnnotate?: (test: Test, annotation: TestAnnotation) => Promise - - /** - * @experimental - * - * Called when artifacts are recorded on tests via the `recordArtifact` utility. - */ - onTestArtifactRecord?: (test: Test, artifact: Artifact) => Promise - - /** - * Called before running all tests in collected paths. - */ - onBeforeRunFiles?: (files: File[]) => unknown - /** - * Called right after running all tests in collected paths. - */ - onAfterRunFiles?: (files: File[]) => unknown - /** - * Called when new context for a test is defined. Useful if you want to add custom properties to the context. - * If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead. - * - * @see https://vitest.dev/advanced/runner#your-task-function - */ - extendTaskContext?: (context: TestContext) => TestContext - /** - * Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files. - */ - importFile: (filepath: string, source: VitestRunnerImportSource) => unknown - /** - * Function that is called when the runner attempts to get the value when `test.extend` is used with `{ injected: true }` - */ - injectValue?: (key: string) => unknown - /** - * Gets the time spent importing each individual non-externalized file that Vitest collected. - */ - getImportDurations?: () => Record - /** - * Publicly available configuration. - */ - config: VitestRunnerConfig - /** - * The name of the current pool. Can affect how stack trace is inferred on the server side. - */ - pool?: string - /** - * The current Vite environment that processes the files on the server. - */ - viteEnvironment?: string - - onCleanupWorkerContext?: (cleanup: () => unknown) => void - - // eslint-disable-next-line ts/method-signature-style - trace?(name: string, cb: () => T): T - // eslint-disable-next-line ts/method-signature-style - trace?(name: string, attributes: Record, cb: () => T): T - - /** @internal */ - _currentSpecification?: FileSpecification | undefined - /** @internal */ - _currentTaskStartTime?: number - /** @internal */ - _currentTaskTimeout?: number -} diff --git a/packages/runner/src/utils/collect.ts b/packages/runner/src/utils/collect.ts deleted file mode 100644 index 961503a3d6cb..000000000000 --- a/packages/runner/src/utils/collect.ts +++ /dev/null @@ -1,261 +0,0 @@ -import type { ParsedStack } from '@vitest/utils' -import type { File, Suite, TaskBase } from '../types/tasks' -import { processError } from '@vitest/utils/error' -import { parseSingleStack } from '@vitest/utils/source-map' -import { relative } from 'pathe' - -/** - * If any tasks been marked as `only`, mark all other tasks as `skip`. - */ -export function interpretTaskModes( - file: Suite, - namePattern?: string | RegExp, - testLocations?: number[] | undefined, - testIds?: string[] | undefined, - testTagsFilter?: ((testTags: string[]) => boolean) | undefined, - onlyMode?: boolean, - parentIsOnly?: boolean, - allowOnly?: boolean, -): void { - const matchedLocations: number[] = [] - const testLocationsSet = testLocations !== undefined && testLocations.length !== 0 - ? new Set(testLocations) - : undefined - const testIdsSet = testIds ? new Set(testIds) : undefined - - const traverseSuite = (suite: Suite, parentIsOnly?: boolean, parentMatchedWithLocation?: boolean) => { - const suiteIsOnly = parentIsOnly || suite.mode === 'only' - - // Check if any tasks in this suite have `.only` - if so, only those should run - const hasSomeTasksOnly = onlyMode && suite.tasks.some( - t => t.mode === 'only' || (t.type === 'suite' && someTasksAreOnly(t)), - ) - - suite.tasks.forEach((t) => { - // Check if either the parent suite or the task itself are marked as included - // If there are tasks with `.only` in this suite, only include those (not all tasks from describe.only) - const includeTask = hasSomeTasksOnly - ? (t.mode === 'only' || (t.type === 'suite' && someTasksAreOnly(t))) - : (suiteIsOnly || t.mode === 'only') - if (onlyMode) { - if (t.type === 'suite' && (includeTask || someTasksAreOnly(t))) { - // Don't skip this suite - if (t.mode === 'only') { - checkAllowOnly(t, allowOnly) - t.mode = 'run' - } - } - else if (t.mode === 'run' && !includeTask) { - t.mode = 'skip' - } - else if (t.mode === 'only') { - checkAllowOnly(t, allowOnly) - t.mode = 'run' - } - } - - let hasLocationMatch = parentMatchedWithLocation - // Match test location against provided locations, only run if present - // in `testLocations`. Note: if `includeTaskLocation` is not enabled, - // all test will be skipped. - if (testLocationsSet !== undefined) { - if (t.location && testLocationsSet.has(t.location.line)) { - t.mode = 'run' - matchedLocations.push(t.location.line) - hasLocationMatch = true - } - else if (parentMatchedWithLocation) { - t.mode = 'run' - } - else if (t.type === 'test') { - t.mode = 'skip' - } - } - - if (t.type === 'test') { - if (namePattern && !getTaskFullName(t).match(namePattern)) { - t.mode = 'skip' - } - if (testIdsSet && !testIdsSet.has(t.id)) { - t.mode = 'skip' - } - if (testTagsFilter && !testTagsFilter(t.tags || [])) { - t.mode = 'skip' - } - } - else if (t.type === 'suite') { - if (t.mode === 'skip') { - skipAllTasks(t) - } - else if (t.mode === 'todo') { - todoAllTasks(t) - } - else { - traverseSuite(t, includeTask, hasLocationMatch) - } - } - }) - - // if all subtasks are skipped, mark as skip - if (suite.mode === 'run' || suite.mode === 'queued') { - if (suite.tasks.length && suite.tasks.every(i => i.mode !== 'run' && i.mode !== 'queued')) { - suite.mode = 'skip' - } - } - } - - traverseSuite(file, parentIsOnly, false) - - const nonMatching = testLocations?.filter(loc => !matchedLocations.includes(loc)) - if (nonMatching && nonMatching.length !== 0) { - const message = nonMatching.length === 1 - ? `line ${nonMatching[0]}` - : `lines ${nonMatching.join(', ')}` - - if (file.result === undefined) { - file.result = { - state: 'fail', - errors: [], - } - } - if (file.result.errors === undefined) { - file.result.errors = [] - } - - file.result.errors.push( - processError(new Error(`No test found in ${file.name} in ${message}`)), - ) - } -} - -function getTaskFullName(task: TaskBase): string { - return `${task.suite ? `${getTaskFullName(task.suite)} ` : ''}${task.name}` -} - -export function someTasksAreOnly(suite: Suite): boolean { - return suite.tasks.some( - t => t.mode === 'only' || (t.type === 'suite' && someTasksAreOnly(t)), - ) -} - -function skipAllTasks(suite: Suite) { - suite.tasks.forEach((t) => { - if (t.mode === 'run' || t.mode === 'queued') { - t.mode = 'skip' - if (t.type === 'suite') { - skipAllTasks(t) - } - } - }) -} -function todoAllTasks(suite: Suite) { - suite.tasks.forEach((t) => { - if (t.mode === 'run' || t.mode === 'queued') { - t.mode = 'todo' - if (t.type === 'suite') { - todoAllTasks(t) - } - } - }) -} - -function checkAllowOnly(task: TaskBase, allowOnly?: boolean) { - if (allowOnly) { - return - } - const error = processError( - new Error( - '[Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error', - ), - ) - task.result = { - state: 'fail', - errors: [error], - } -} - -/* @__NO_SIDE_EFFECTS__ */ -export function generateHash(str: string): string { - let hash = 0 - if (str.length === 0) { - return `${hash}` - } - for (let i = 0; i < str.length; i++) { - const char = str.charCodeAt(i) - hash = (hash << 5) - hash + char - hash = hash & hash // Convert to 32bit integer - } - return `${hash}` -} - -export function calculateSuiteHash(parent: Suite): void { - parent.tasks.forEach((t, idx) => { - t.id = `${parent.id}_${idx}` - if (t.type === 'suite') { - calculateSuiteHash(t) - } - }) -} - -interface HashMeta { - typecheck?: boolean - __vitest_label__?: string -} - -export function createFileTask( - filepath: string, - root: string, - projectName: string | undefined, - pool?: string, - viteEnvironment?: string, - meta?: HashMeta, -): File { - const path = relative(root, filepath) - const file: File = { - id: generateFileHash(path, projectName, meta), - name: path, - fullName: path, - type: 'suite', - mode: 'queued', - filepath, - tasks: [], - meta: Object.assign(Object.create(null), meta), - projectName, - file: undefined!, - pool, - viteEnvironment, - } - file.file = file - return file -} - -/** - * Generate a unique ID for a file based on its path and project name - * @param file File relative to the root of the project to keep ID the same between different machines - * @param projectName The name of the test project - */ -/* @__NO_SIDE_EFFECTS__ */ -export function generateFileHash( - file: string, - projectName: string | undefined, - meta?: HashMeta, -): string { - const seed = [ - file, - projectName || '', - meta?.typecheck ? '__typecheck__' : '', - meta?.__vitest_label__ || '', - ].join('\0') - return generateHash(seed) -} - -export function findTestFileStackTrace(testFilePath: string, error: string): ParsedStack | undefined { - // first line is the error message - const lines = error.split('\n').slice(1) - for (const line of lines) { - const stack = parseSingleStack(line) - if (stack && stack.file === testFilePath) { - return stack - } - } -} diff --git a/packages/runner/src/utils/index.ts b/packages/runner/src/utils/index.ts deleted file mode 100644 index ea8e100a14c1..000000000000 --- a/packages/runner/src/utils/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export { type ChainableFunction, createChainable } from './chain' -export { - calculateSuiteHash, - createFileTask, - findTestFileStackTrace, - generateFileHash, - generateHash, - interpretTaskModes, - someTasksAreOnly, -} from './collect' -export { limitConcurrency } from './limit-concurrency' -export { partitionSuiteChildren } from './suite' -export { createTagsFilter, matchesTags, validateTags } from './tags' -export { - createTaskName, - getFullName, - getNames, - getSuites, - getTasks, - getTestName, - getTests, - hasFailed, - hasTests, - isTestCase, -} from './tasks' diff --git a/packages/runner/src/utils/tasks.ts b/packages/runner/src/utils/tasks.ts deleted file mode 100644 index e7a3b55529ea..000000000000 --- a/packages/runner/src/utils/tasks.ts +++ /dev/null @@ -1,86 +0,0 @@ -import type { Arrayable } from '@vitest/utils' -import type { Suite, Task, Test } from '../types/tasks' -import { toArray } from '@vitest/utils/helpers' - -export function isTestCase(s: Task): s is Test { - return s.type === 'test' -} - -export function getTests(suite: Arrayable): Test[] { - const tests: Test[] = [] - const arraySuites = toArray(suite) - for (const s of arraySuites) { - if (isTestCase(s)) { - tests.push(s) - } - else { - for (const task of s.tasks) { - if (isTestCase(task)) { - tests.push(task) - } - else { - const taskTests = getTests(task) - for (const test of taskTests) { - tests.push(test) - } - } - } - } - } - return tests -} - -export function getTasks(tasks: Arrayable = []): Task[] { - return toArray(tasks).flatMap(s => - isTestCase(s) ? [s] : [s, ...getTasks(s.tasks)], - ) -} - -export function getSuites(suite: Arrayable): Suite[] { - return toArray(suite).flatMap(s => - s.type === 'suite' ? [s, ...getSuites(s.tasks)] : [], - ) -} - -export function hasTests(suite: Arrayable): boolean { - return toArray(suite).some(s => - s.tasks.some(c => isTestCase(c) || hasTests(c)), - ) -} - -export function hasFailed(suite: Arrayable): boolean { - return toArray(suite).some( - s => - s.result?.state === 'fail' || (s.type === 'suite' && hasFailed(s.tasks)), - ) -} - -export function getNames(task: Task): string[] { - const names = [task.name] - let current: Task | undefined = task - - while (current?.suite) { - current = current.suite - if (current?.name) { - names.unshift(current.name) - } - } - - if (current !== task.file) { - names.unshift(task.file.name) - } - - 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) -} - -export function createTaskName(names: readonly (string | undefined)[], separator = ' > '): string { - return names.filter(name => name !== undefined).join(separator) -} diff --git a/packages/runner/tsconfig.json b/packages/runner/tsconfig.json deleted file mode 100644 index 83a275cdf5f8..000000000000 --- a/packages/runner/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "target": "ESNext", - "module": "ESNext", - "moduleResolution": "Bundler", - "types": ["node"], - "isolatedDeclarations": true - }, - "include": ["./src/**/*.ts"], - "exclude": ["./dist"] -} diff --git a/packages/runner/types.d.ts b/packages/runner/types.d.ts deleted file mode 100644 index 26a125423d41..000000000000 --- a/packages/runner/types.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/types.js' diff --git a/packages/runner/utils.d.ts b/packages/runner/utils.d.ts deleted file mode 100644 index e3f344e48a8d..000000000000 --- a/packages/runner/utils.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/utils.js' diff --git a/packages/ui/client/components/artifacts/visual-regression/VisualRegression.spec.ts b/packages/ui/client/components/artifacts/visual-regression/VisualRegression.spec.ts index f256ba49cb41..fe9c05fdadb4 100644 --- a/packages/ui/client/components/artifacts/visual-regression/VisualRegression.spec.ts +++ b/packages/ui/client/components/artifacts/visual-regression/VisualRegression.spec.ts @@ -1,4 +1,4 @@ -import type { VisualRegressionArtifact } from '@vitest/runner' +import type { VisualRegressionArtifact } from 'vitest' import { faker } from '@faker-js/faker' import { describe, expect, it } from 'vitest' import { userEvent } from 'vitest/browser' diff --git a/packages/ui/client/components/artifacts/visual-regression/VisualRegression.vue b/packages/ui/client/components/artifacts/visual-regression/VisualRegression.vue index 77cca7289eda..875bb373e84c 100644 --- a/packages/ui/client/components/artifacts/visual-regression/VisualRegression.vue +++ b/packages/ui/client/components/artifacts/visual-regression/VisualRegression.vue @@ -1,5 +1,5 @@