vitest 3.0.0-beta.1 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +12 -9
- package/dist/browser.js +2 -2
- package/dist/chunks/{base.CkcgFVQd.js → base.CUgXReRN.js} +1 -1
- package/dist/chunks/{cac.CWCZimpS.js → cac.Xzv7eNWw.js} +18 -13
- package/dist/chunks/{cli-api.BKUOv0Nc.js → cli-api.CETCDGgZ.js} +915 -531
- package/dist/chunks/{coverage.BoMDb1ip.js → coverage.BWeNbfBa.js} +4 -4
- package/dist/chunks/{environment.CT0jpO-1.d.ts → environment.d8YfPkTm.d.ts} +1 -3
- package/dist/chunks/{globals.DJTzb7B3.js → globals.BFncSRNA.js} +2 -2
- package/dist/chunks/{index.DKe7vK-G.js → index.9ZEBV_TJ.js} +635 -606
- package/dist/chunks/{index.BqHViJW9.js → index.CkWmZCXU.js} +1 -1
- package/dist/chunks/{index.CkOJwybT.js → index.DoV7W5gc.js} +2 -2
- package/dist/chunks/{reporters.BZbwTvrM.d.ts → reporters.DTtxC3KQ.d.ts} +447 -374
- package/dist/chunks/{resolveConfig.3rGGWga5.js → resolveConfig.BA-_OKEx.js} +5529 -5532
- package/dist/chunks/{runBaseTests.C6huCAng.js → runBaseTests.D0dWpzZV.js} +11 -10
- package/dist/chunks/{setup-common.B5ClyS48.js → setup-common.Cp_bu5q3.js} +1 -1
- package/dist/chunks/types.BOjykUpq.d.ts +27 -0
- package/dist/chunks/{vi.CZKezqeD.js → vi.S4Fq8wSo.js} +2 -1
- package/dist/chunks/{vite.DIfmneq0.d.ts → vite.CXaetSK3.d.ts} +1 -1
- package/dist/chunks/{worker.umPNbBNk.d.ts → worker.ClntunZp.d.ts} +1 -1
- package/dist/chunks/{worker.CmzGeuVD.d.ts → worker.o1PBoDdo.d.ts} +3 -3
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +6 -8
- package/dist/coverage.d.ts +4 -6
- package/dist/coverage.js +1 -1
- package/dist/environments.d.ts +2 -2
- package/dist/execute.d.ts +2 -2
- package/dist/index.d.ts +11 -14
- package/dist/index.js +2 -2
- package/dist/node.d.ts +22 -17
- package/dist/node.js +65 -31
- package/dist/reporters.d.ts +4 -6
- package/dist/reporters.js +1 -1
- package/dist/runners.d.ts +2 -2
- package/dist/runners.js +1 -1
- package/dist/suite.d.ts +1 -1
- package/dist/workers/forks.js +1 -1
- package/dist/workers/runVmTests.js +7 -7
- package/dist/workers/threads.js +1 -1
- package/dist/workers.d.ts +3 -3
- package/dist/workers.js +1 -1
- package/package.json +13 -13
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { existsSync, promises, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { createFileTask, limitConcurrency, getTasks, hasFailed, getTests, getNames } from '@vitest/runner/utils';
|
|
3
2
|
import { normalize, relative, dirname, resolve, join, basename, isAbsolute } from 'pathe';
|
|
4
|
-
import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.
|
|
3
|
+
import { g as getCoverageProvider, C as CoverageProviderMap } from './coverage.BWeNbfBa.js';
|
|
5
4
|
import a, { resolve as resolve$1 } from 'node:path';
|
|
6
5
|
import { noop, isPrimitive, toArray, deepMerge, nanoid, slash, notNullish, createDefer } from '@vitest/utils';
|
|
7
6
|
import { f as findUp, p as prompt } from './index.BJDntFik.js';
|
|
8
7
|
import { searchForWorkspaceRoot, version, createServer, mergeConfig } from 'vite';
|
|
9
8
|
import { A as API_PATH, c as configFiles, a as defaultBrowserPort, w as workspacesFiles, d as defaultPort } from './constants.fzPh7AOq.js';
|
|
9
|
+
import { createFileTask, limitConcurrency, getTasks, hasFailed, getTests } from '@vitest/runner/utils';
|
|
10
10
|
import { SnapshotManager } from '@vitest/snapshot/manager';
|
|
11
|
-
import { e as groupBy, i as isPackageExists, f as requireMicromatch, V as VitestCache, h as configDefaults, g as getFilePoolName, j as isBrowserEnabled, m as mm, b as resolveConfig, w as wildcardPatternToRegExp, k as createPool, a as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.3rGGWga5.js';
|
|
12
11
|
import { ViteNodeRunner } from 'vite-node/client';
|
|
13
12
|
import { ViteNodeServer } from 'vite-node/server';
|
|
14
|
-
import { v as version$1 } from './cac.
|
|
13
|
+
import { v as version$1 } from './cac.Xzv7eNWw.js';
|
|
15
14
|
import { c as createBirpc } from './index.68735LiX.js';
|
|
16
|
-
import { s as stringify, p as parse, i as generateCodeFrame, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, L as Logger, j as BlobReporter, r as readBlobs } from './index.
|
|
15
|
+
import { s as stringify, p as parse, i as generateCodeFrame, R as ReportersMap, h as BenchmarkReportsMap, f as TestModule, g as TestSuite, e as TestCase, L as Logger, j as BlobReporter, r as readBlobs } from './index.9ZEBV_TJ.js';
|
|
17
16
|
import require$$0$2 from 'stream';
|
|
18
17
|
import require$$0 from 'zlib';
|
|
19
18
|
import require$$0$1 from 'buffer';
|
|
@@ -27,6 +26,7 @@ import require$$7 from 'url';
|
|
|
27
26
|
import { g as getDefaultExportFromCjs, c as commonjsGlobal } from './_commonjsHelpers.BFTU3MAI.js';
|
|
28
27
|
import { parseErrorStacktrace } from '@vitest/utils/source-map';
|
|
29
28
|
import { distDir, rootDir } from '../path.js';
|
|
29
|
+
import { i as isPackageExists, e as requireMicromatch, V as VitestCache, f as configDefaults, g as getFilePoolName, h as isBrowserEnabled, m as mm, a as resolveConfig, j as groupBy, w as wildcardPatternToRegExp, k as createPool, b as resolveApiServerConfig, c as coverageConfigDefaults, s as stdout } from './resolveConfig.BA-_OKEx.js';
|
|
30
30
|
import { createRequire } from 'node:module';
|
|
31
31
|
import url from 'node:url';
|
|
32
32
|
import c from 'tinyrainbow';
|
|
@@ -4931,7 +4931,7 @@ function setup(ctx, _server) {
|
|
|
4931
4931
|
await ctx.rerunTask(id);
|
|
4932
4932
|
},
|
|
4933
4933
|
getConfig() {
|
|
4934
|
-
return ctx.
|
|
4934
|
+
return ctx.getRootProject().serializedConfig;
|
|
4935
4935
|
},
|
|
4936
4936
|
async getTransformResult(projectName, id, browser = false) {
|
|
4937
4937
|
const project = ctx.getProjectByName(projectName);
|
|
@@ -4957,7 +4957,7 @@ function setup(ctx, _server) {
|
|
|
4957
4957
|
return ctx.state.getUnhandledErrors();
|
|
4958
4958
|
},
|
|
4959
4959
|
async getTestFiles() {
|
|
4960
|
-
const spec = await ctx.
|
|
4960
|
+
const spec = await ctx.globTestSpecifications();
|
|
4961
4961
|
return spec.map((spec2) => [
|
|
4962
4962
|
{
|
|
4963
4963
|
name: spec2.project.config.name,
|
|
@@ -5019,15 +5019,18 @@ class WebSocketReporter {
|
|
|
5019
5019
|
return;
|
|
5020
5020
|
}
|
|
5021
5021
|
packs.forEach(([taskId, result]) => {
|
|
5022
|
-
const project = this.ctx.getProjectByTaskId(taskId);
|
|
5023
5022
|
const task = this.ctx.state.idMap.get(taskId);
|
|
5024
5023
|
const isBrowser = task && task.file.pool === "browser";
|
|
5025
5024
|
result?.errors?.forEach((error) => {
|
|
5026
5025
|
if (isPrimitive(error)) {
|
|
5027
5026
|
return;
|
|
5028
5027
|
}
|
|
5029
|
-
|
|
5030
|
-
|
|
5028
|
+
if (isBrowser) {
|
|
5029
|
+
const project = this.ctx.getProjectByName(task.file.projectName || "");
|
|
5030
|
+
error.stacks = project.browser?.parseErrorStacktrace(error);
|
|
5031
|
+
} else {
|
|
5032
|
+
error.stacks = parseErrorStacktrace(error);
|
|
5033
|
+
}
|
|
5031
5034
|
});
|
|
5032
5035
|
});
|
|
5033
5036
|
this.clients.forEach((client) => {
|
|
@@ -5088,41 +5091,6 @@ class RangeLocationFilterProvidedError extends Error {
|
|
|
5088
5091
|
}
|
|
5089
5092
|
}
|
|
5090
5093
|
|
|
5091
|
-
function parseFilter(filter) {
|
|
5092
|
-
const colonIndex = filter.lastIndexOf(":");
|
|
5093
|
-
if (colonIndex === -1) {
|
|
5094
|
-
return { filename: filter };
|
|
5095
|
-
}
|
|
5096
|
-
const [parsedFilename, lineNumber] = [
|
|
5097
|
-
filter.substring(0, colonIndex),
|
|
5098
|
-
filter.substring(colonIndex + 1)
|
|
5099
|
-
];
|
|
5100
|
-
if (lineNumber.match(/^\d+$/)) {
|
|
5101
|
-
return {
|
|
5102
|
-
filename: parsedFilename,
|
|
5103
|
-
lineNumber: Number.parseInt(lineNumber)
|
|
5104
|
-
};
|
|
5105
|
-
} else if (lineNumber.match(/^\d+-\d+$/)) {
|
|
5106
|
-
throw new RangeLocationFilterProvidedError(filter);
|
|
5107
|
-
} else {
|
|
5108
|
-
return { filename: filter };
|
|
5109
|
-
}
|
|
5110
|
-
}
|
|
5111
|
-
function groupFilters(filters) {
|
|
5112
|
-
const groupedFilters_ = groupBy(filters, (f) => f.filename);
|
|
5113
|
-
const groupedFilters = Object.fromEntries(
|
|
5114
|
-
Object.entries(groupedFilters_).map((entry) => {
|
|
5115
|
-
const [filename, filters2] = entry;
|
|
5116
|
-
const testLocations = filters2.map((f) => f.lineNumber);
|
|
5117
|
-
return [
|
|
5118
|
-
filename,
|
|
5119
|
-
testLocations.filter((l) => l !== void 0)
|
|
5120
|
-
];
|
|
5121
|
-
})
|
|
5122
|
-
);
|
|
5123
|
-
return groupedFilters;
|
|
5124
|
-
}
|
|
5125
|
-
|
|
5126
5094
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
5127
5095
|
class VitestPackageInstaller {
|
|
5128
5096
|
isPackageExists(name, options) {
|
|
@@ -9514,8 +9482,8 @@ function WorkspaceVitestPlugin(project, options) {
|
|
|
9514
9482
|
middlewareMode: true,
|
|
9515
9483
|
fs: {
|
|
9516
9484
|
allow: resolveFsAllow(
|
|
9517
|
-
project.
|
|
9518
|
-
project.
|
|
9485
|
+
project.vitest.config.root,
|
|
9486
|
+
project.vitest.server.config.configFile
|
|
9519
9487
|
)
|
|
9520
9488
|
}
|
|
9521
9489
|
},
|
|
@@ -9593,20 +9561,31 @@ class TestSpecification {
|
|
|
9593
9561
|
* @deprecated use `pool` instead
|
|
9594
9562
|
*/
|
|
9595
9563
|
2;
|
|
9564
|
+
/**
|
|
9565
|
+
* The test project that the module belongs to.
|
|
9566
|
+
*/
|
|
9596
9567
|
project;
|
|
9568
|
+
/**
|
|
9569
|
+
* The ID of the module in the Vite module graph. It is usually an absolute file path.
|
|
9570
|
+
*/
|
|
9597
9571
|
moduleId;
|
|
9572
|
+
/**
|
|
9573
|
+
* The current test pool. It's possible to have multiple pools in a single test project with `poolMatchGlob` and `typecheck.enabled`.
|
|
9574
|
+
* @experimental In Vitest 4, the project will only support a single pool and this property will be removed.
|
|
9575
|
+
*/
|
|
9598
9576
|
pool;
|
|
9599
|
-
/**
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9577
|
+
/**
|
|
9578
|
+
* Line numbers of the test locations to run.
|
|
9579
|
+
*/
|
|
9580
|
+
testLines;
|
|
9581
|
+
constructor(project, moduleId, pool, testLines) {
|
|
9603
9582
|
this[0] = project;
|
|
9604
9583
|
this[1] = moduleId;
|
|
9605
9584
|
this[2] = { pool };
|
|
9606
9585
|
this.project = project;
|
|
9607
9586
|
this.moduleId = moduleId;
|
|
9608
9587
|
this.pool = pool;
|
|
9609
|
-
this.
|
|
9588
|
+
this.testLines = testLines;
|
|
9610
9589
|
}
|
|
9611
9590
|
toJSON() {
|
|
9612
9591
|
return [
|
|
@@ -9615,7 +9594,7 @@ class TestSpecification {
|
|
|
9615
9594
|
root: this.project.config.root
|
|
9616
9595
|
},
|
|
9617
9596
|
this.moduleId,
|
|
9618
|
-
{ pool: this.pool }
|
|
9597
|
+
{ pool: this.pool, testLines: this.testLines }
|
|
9619
9598
|
];
|
|
9620
9599
|
}
|
|
9621
9600
|
/**
|
|
@@ -9669,9 +9648,11 @@ class TestProject {
|
|
|
9669
9648
|
* Temporary directory for the project. This is unique for each project. Vitest stores transformed content here.
|
|
9670
9649
|
*/
|
|
9671
9650
|
tmpDir = join(tmpdir(), nanoid());
|
|
9651
|
+
/** @internal */
|
|
9672
9652
|
vitenode;
|
|
9673
|
-
|
|
9653
|
+
/** @internal */
|
|
9674
9654
|
typechecker;
|
|
9655
|
+
runner;
|
|
9675
9656
|
closingPromise;
|
|
9676
9657
|
testFilesList = null;
|
|
9677
9658
|
typecheckFilesList = null;
|
|
@@ -9705,7 +9686,7 @@ class TestProject {
|
|
|
9705
9686
|
return this._provided;
|
|
9706
9687
|
}
|
|
9707
9688
|
return {
|
|
9708
|
-
...this.vitest.
|
|
9689
|
+
...this.vitest.getRootProject().getProvidedContext(),
|
|
9709
9690
|
...this._provided
|
|
9710
9691
|
};
|
|
9711
9692
|
}
|
|
@@ -9713,12 +9694,12 @@ class TestProject {
|
|
|
9713
9694
|
* Creates a new test specification. Specifications describe how to run tests.
|
|
9714
9695
|
* @param moduleId The file path
|
|
9715
9696
|
*/
|
|
9716
|
-
createSpecification(moduleId,
|
|
9697
|
+
createSpecification(moduleId, locations, pool) {
|
|
9717
9698
|
return new TestSpecification(
|
|
9718
9699
|
this,
|
|
9719
9700
|
moduleId,
|
|
9720
9701
|
pool || getFilePoolName(this, moduleId),
|
|
9721
|
-
|
|
9702
|
+
locations
|
|
9722
9703
|
);
|
|
9723
9704
|
}
|
|
9724
9705
|
toJSON() {
|
|
@@ -9766,7 +9747,7 @@ class TestProject {
|
|
|
9766
9747
|
* Check if this is the root project. The root project is the one that has the root config.
|
|
9767
9748
|
*/
|
|
9768
9749
|
isRootProject() {
|
|
9769
|
-
return this.vitest.
|
|
9750
|
+
return this.vitest.getRootProject() === this;
|
|
9770
9751
|
}
|
|
9771
9752
|
/** @deprecated use `isRootProject` instead */
|
|
9772
9753
|
isCore() {
|
|
@@ -9893,22 +9874,21 @@ class TestProject {
|
|
|
9893
9874
|
isBrowserEnabled() {
|
|
9894
9875
|
return isBrowserEnabled(this.config);
|
|
9895
9876
|
}
|
|
9896
|
-
|
|
9897
|
-
_markTestFile(testPath) {
|
|
9877
|
+
markTestFile(testPath) {
|
|
9898
9878
|
this.testFilesList?.push(testPath);
|
|
9899
9879
|
}
|
|
9900
9880
|
/**
|
|
9901
9881
|
* Returns if the file is a test file. Requires `.globTestFiles()` to be called first.
|
|
9902
9882
|
* @internal
|
|
9903
9883
|
*/
|
|
9904
|
-
|
|
9884
|
+
isCachedTestFile(testPath) {
|
|
9905
9885
|
return !!this.testFilesList && this.testFilesList.includes(testPath);
|
|
9906
9886
|
}
|
|
9907
9887
|
/**
|
|
9908
9888
|
* Returns if the file is a typecheck test file. Requires `.globTestFiles()` to be called first.
|
|
9909
9889
|
* @internal
|
|
9910
9890
|
*/
|
|
9911
|
-
|
|
9891
|
+
isCachedTypecheckFile(testPath) {
|
|
9912
9892
|
return !!this.typecheckFilesList && this.typecheckFilesList.includes(testPath);
|
|
9913
9893
|
}
|
|
9914
9894
|
/** @deprecated use `serializedConfig` instead */
|
|
@@ -9926,25 +9906,32 @@ class TestProject {
|
|
|
9926
9906
|
return files.map((file) => slash(a.resolve(cwd, file)));
|
|
9927
9907
|
}
|
|
9928
9908
|
/**
|
|
9929
|
-
* Test if a file matches the test globs. This does the actual glob matching unlike `
|
|
9909
|
+
* Test if a file matches the test globs. This does the actual glob matching if the test is not cached, unlike `isCachedTestFile`.
|
|
9930
9910
|
*/
|
|
9931
|
-
matchesTestGlob(
|
|
9932
|
-
|
|
9911
|
+
matchesTestGlob(moduleId, source) {
|
|
9912
|
+
if (this.isCachedTestFile(moduleId)) {
|
|
9913
|
+
return true;
|
|
9914
|
+
}
|
|
9915
|
+
const relativeId = relative(this.config.dir || this.config.root, moduleId);
|
|
9933
9916
|
if (mm.isMatch(relativeId, this.config.exclude)) {
|
|
9934
9917
|
return false;
|
|
9935
9918
|
}
|
|
9936
9919
|
if (mm.isMatch(relativeId, this.config.include)) {
|
|
9920
|
+
this.markTestFile(moduleId);
|
|
9937
9921
|
return true;
|
|
9938
9922
|
}
|
|
9939
9923
|
if (this.config.includeSource?.length && mm.isMatch(relativeId, this.config.includeSource)) {
|
|
9940
|
-
const code = source || readFileSync(
|
|
9941
|
-
|
|
9924
|
+
const code = source?.() || readFileSync(moduleId, "utf-8");
|
|
9925
|
+
if (this.isInSourceTestCode(code)) {
|
|
9926
|
+
this.markTestFile(moduleId);
|
|
9927
|
+
return true;
|
|
9928
|
+
}
|
|
9942
9929
|
}
|
|
9943
9930
|
return false;
|
|
9944
9931
|
}
|
|
9945
9932
|
/** @deprecated use `matchesTestGlob` instead */
|
|
9946
9933
|
async isTargetFile(id, source) {
|
|
9947
|
-
return this.matchesTestGlob(id, source);
|
|
9934
|
+
return this.matchesTestGlob(id, source ? () => source : void 0);
|
|
9948
9935
|
}
|
|
9949
9936
|
isInSourceTestCode(code) {
|
|
9950
9937
|
return code.includes("import.meta.vitest");
|
|
@@ -10014,6 +10001,13 @@ class TestProject {
|
|
|
10014
10001
|
}
|
|
10015
10002
|
return this.closingPromise;
|
|
10016
10003
|
}
|
|
10004
|
+
/**
|
|
10005
|
+
* Import a file using Vite module runner.
|
|
10006
|
+
* @param moduleId The ID of the module in Vite module graph
|
|
10007
|
+
*/
|
|
10008
|
+
import(moduleId) {
|
|
10009
|
+
return this.runner.executeId(moduleId);
|
|
10010
|
+
}
|
|
10017
10011
|
/** @deprecated use `name` instead */
|
|
10018
10012
|
getName() {
|
|
10019
10013
|
return this.config.name || "";
|
|
@@ -10192,6 +10186,192 @@ function createBenchmarkReporters(reporterReferences, runner) {
|
|
|
10192
10186
|
return Promise.all(promisedReporters);
|
|
10193
10187
|
}
|
|
10194
10188
|
|
|
10189
|
+
function parseFilter(filter) {
|
|
10190
|
+
const colonIndex = filter.lastIndexOf(":");
|
|
10191
|
+
if (colonIndex === -1) {
|
|
10192
|
+
return { filename: filter };
|
|
10193
|
+
}
|
|
10194
|
+
const [parsedFilename, lineNumber] = [
|
|
10195
|
+
filter.substring(0, colonIndex),
|
|
10196
|
+
filter.substring(colonIndex + 1)
|
|
10197
|
+
];
|
|
10198
|
+
if (lineNumber.match(/^\d+$/)) {
|
|
10199
|
+
return {
|
|
10200
|
+
filename: parsedFilename,
|
|
10201
|
+
lineNumber: Number.parseInt(lineNumber)
|
|
10202
|
+
};
|
|
10203
|
+
} else if (lineNumber.match(/^\d+-\d+$/)) {
|
|
10204
|
+
throw new RangeLocationFilterProvidedError(filter);
|
|
10205
|
+
} else {
|
|
10206
|
+
return { filename: filter };
|
|
10207
|
+
}
|
|
10208
|
+
}
|
|
10209
|
+
function groupFilters(filters) {
|
|
10210
|
+
const groupedFilters_ = groupBy(filters, (f) => f.filename);
|
|
10211
|
+
const groupedFilters = Object.fromEntries(
|
|
10212
|
+
Object.entries(groupedFilters_).map((entry) => {
|
|
10213
|
+
const [filename, filters2] = entry;
|
|
10214
|
+
const testLocations = filters2.map((f) => f.lineNumber);
|
|
10215
|
+
return [
|
|
10216
|
+
filename,
|
|
10217
|
+
testLocations.filter((l) => l !== void 0)
|
|
10218
|
+
];
|
|
10219
|
+
})
|
|
10220
|
+
);
|
|
10221
|
+
return groupedFilters;
|
|
10222
|
+
}
|
|
10223
|
+
|
|
10224
|
+
class VitestSpecifications {
|
|
10225
|
+
constructor(vitest) {
|
|
10226
|
+
this.vitest = vitest;
|
|
10227
|
+
}
|
|
10228
|
+
_cachedSpecs = /* @__PURE__ */ new Map();
|
|
10229
|
+
getModuleSpecifications(moduleId) {
|
|
10230
|
+
const _cached = this.getCachedSpecifications(moduleId);
|
|
10231
|
+
if (_cached) {
|
|
10232
|
+
return _cached;
|
|
10233
|
+
}
|
|
10234
|
+
const specs = [];
|
|
10235
|
+
for (const project of this.vitest.projects) {
|
|
10236
|
+
if (project.isCachedTestFile(moduleId)) {
|
|
10237
|
+
specs.push(project.createSpecification(moduleId));
|
|
10238
|
+
}
|
|
10239
|
+
if (project.isCachedTypecheckFile(moduleId)) {
|
|
10240
|
+
specs.push(project.createSpecification(moduleId, [], "typescript"));
|
|
10241
|
+
}
|
|
10242
|
+
}
|
|
10243
|
+
specs.forEach((spec) => this.ensureSpecificationCached(spec));
|
|
10244
|
+
return specs;
|
|
10245
|
+
}
|
|
10246
|
+
async getRelevantTestSpecifications(filters = []) {
|
|
10247
|
+
return this.filterTestsBySource(
|
|
10248
|
+
await this.globTestSpecifications(filters)
|
|
10249
|
+
);
|
|
10250
|
+
}
|
|
10251
|
+
async globTestSpecifications(filters = []) {
|
|
10252
|
+
const files = [];
|
|
10253
|
+
const dir = process.cwd();
|
|
10254
|
+
const parsedFilters = filters.map((f) => parseFilter(f));
|
|
10255
|
+
if (!this.vitest.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) {
|
|
10256
|
+
throw new IncludeTaskLocationDisabledError();
|
|
10257
|
+
}
|
|
10258
|
+
const testLines = groupFilters(parsedFilters.map(
|
|
10259
|
+
(f) => ({ ...f, filename: resolve(dir, f.filename) })
|
|
10260
|
+
));
|
|
10261
|
+
const testLocHasMatch = {};
|
|
10262
|
+
await Promise.all(this.vitest.projects.map(async (project) => {
|
|
10263
|
+
const { testFiles, typecheckTestFiles } = await project.globTestFiles(
|
|
10264
|
+
parsedFilters.map((f) => f.filename)
|
|
10265
|
+
);
|
|
10266
|
+
testFiles.forEach((file) => {
|
|
10267
|
+
const lines = testLines[file];
|
|
10268
|
+
testLocHasMatch[file] = true;
|
|
10269
|
+
const spec = project.createSpecification(file, lines);
|
|
10270
|
+
this.ensureSpecificationCached(spec);
|
|
10271
|
+
files.push(spec);
|
|
10272
|
+
});
|
|
10273
|
+
typecheckTestFiles.forEach((file) => {
|
|
10274
|
+
const lines = testLines[file];
|
|
10275
|
+
testLocHasMatch[file] = true;
|
|
10276
|
+
const spec = project.createSpecification(file, lines, "typescript");
|
|
10277
|
+
this.ensureSpecificationCached(spec);
|
|
10278
|
+
files.push(spec);
|
|
10279
|
+
});
|
|
10280
|
+
}));
|
|
10281
|
+
Object.entries(testLines).forEach(([filepath, loc]) => {
|
|
10282
|
+
if (loc.length !== 0 && !testLocHasMatch[filepath]) {
|
|
10283
|
+
throw new LocationFilterFileNotFoundError(
|
|
10284
|
+
relative(dir, filepath)
|
|
10285
|
+
);
|
|
10286
|
+
}
|
|
10287
|
+
});
|
|
10288
|
+
return files;
|
|
10289
|
+
}
|
|
10290
|
+
clearCache(moduleId) {
|
|
10291
|
+
if (moduleId) {
|
|
10292
|
+
this._cachedSpecs.delete(moduleId);
|
|
10293
|
+
} else {
|
|
10294
|
+
this._cachedSpecs.clear();
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10297
|
+
getCachedSpecifications(moduleId) {
|
|
10298
|
+
return this._cachedSpecs.get(moduleId);
|
|
10299
|
+
}
|
|
10300
|
+
ensureSpecificationCached(spec) {
|
|
10301
|
+
const file = spec.moduleId;
|
|
10302
|
+
const specs = this._cachedSpecs.get(file) || [];
|
|
10303
|
+
const index = specs.findIndex((_s) => _s.project === spec.project && _s.pool === spec.pool);
|
|
10304
|
+
if (index === -1) {
|
|
10305
|
+
specs.push(spec);
|
|
10306
|
+
this._cachedSpecs.set(file, specs);
|
|
10307
|
+
} else {
|
|
10308
|
+
specs.splice(index, 1, spec);
|
|
10309
|
+
}
|
|
10310
|
+
return specs;
|
|
10311
|
+
}
|
|
10312
|
+
async filterTestsBySource(specs) {
|
|
10313
|
+
if (this.vitest.config.changed && !this.vitest.config.related) {
|
|
10314
|
+
const { VitestGit } = await import('./git.B5SDxu-n.js');
|
|
10315
|
+
const vitestGit = new VitestGit(this.vitest.config.root);
|
|
10316
|
+
const related2 = await vitestGit.findChangedFiles({
|
|
10317
|
+
changedSince: this.vitest.config.changed
|
|
10318
|
+
});
|
|
10319
|
+
if (!related2) {
|
|
10320
|
+
process.exitCode = 1;
|
|
10321
|
+
throw new GitNotFoundError();
|
|
10322
|
+
}
|
|
10323
|
+
this.vitest.config.related = Array.from(new Set(related2));
|
|
10324
|
+
}
|
|
10325
|
+
const related = this.vitest.config.related;
|
|
10326
|
+
if (!related) {
|
|
10327
|
+
return specs;
|
|
10328
|
+
}
|
|
10329
|
+
const forceRerunTriggers = this.vitest.config.forceRerunTriggers;
|
|
10330
|
+
if (forceRerunTriggers.length && mm(related, forceRerunTriggers).length) {
|
|
10331
|
+
return specs;
|
|
10332
|
+
}
|
|
10333
|
+
if (!this.vitest.config.watch && !related.length) {
|
|
10334
|
+
return [];
|
|
10335
|
+
}
|
|
10336
|
+
const testGraphs = await Promise.all(
|
|
10337
|
+
specs.map(async (spec) => {
|
|
10338
|
+
const deps = await this.getTestDependencies(spec);
|
|
10339
|
+
return [spec, deps];
|
|
10340
|
+
})
|
|
10341
|
+
);
|
|
10342
|
+
const runningTests = [];
|
|
10343
|
+
for (const [specification, deps] of testGraphs) {
|
|
10344
|
+
if (related.some((path) => path === specification.moduleId || deps.has(path))) {
|
|
10345
|
+
runningTests.push(specification);
|
|
10346
|
+
}
|
|
10347
|
+
}
|
|
10348
|
+
return runningTests;
|
|
10349
|
+
}
|
|
10350
|
+
async getTestDependencies(spec, deps = /* @__PURE__ */ new Set()) {
|
|
10351
|
+
const addImports = async (project, filepath) => {
|
|
10352
|
+
if (deps.has(filepath)) {
|
|
10353
|
+
return;
|
|
10354
|
+
}
|
|
10355
|
+
deps.add(filepath);
|
|
10356
|
+
const mod = project.vite.moduleGraph.getModuleById(filepath);
|
|
10357
|
+
const transformed = mod?.ssrTransformResult || await project.vitenode.transformRequest(filepath);
|
|
10358
|
+
if (!transformed) {
|
|
10359
|
+
return;
|
|
10360
|
+
}
|
|
10361
|
+
const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
|
|
10362
|
+
await Promise.all(dependencies.map(async (dep) => {
|
|
10363
|
+
const fsPath = dep.startsWith("/@fs/") ? dep.slice(isWindows ? 5 : 4) : join(project.config.root, dep);
|
|
10364
|
+
if (!fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) {
|
|
10365
|
+
await addImports(project, fsPath);
|
|
10366
|
+
}
|
|
10367
|
+
}));
|
|
10368
|
+
};
|
|
10369
|
+
await addImports(spec.project, spec.moduleId);
|
|
10370
|
+
deps.delete(spec.moduleId);
|
|
10371
|
+
return deps;
|
|
10372
|
+
}
|
|
10373
|
+
}
|
|
10374
|
+
|
|
10195
10375
|
function isAggregateError(err) {
|
|
10196
10376
|
if (typeof AggregateError !== "undefined" && err instanceof AggregateError) {
|
|
10197
10377
|
return true;
|
|
@@ -10373,49 +10553,187 @@ class StateManager {
|
|
|
10373
10553
|
}
|
|
10374
10554
|
}
|
|
10375
10555
|
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\([^(]*\|[^|]*\)/;
|
|
10380
|
-
const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\([^(]*\)/;
|
|
10381
|
-
const BRACE_EXPANSION_SEPARATORS_RE = /,|\.\./;
|
|
10382
|
-
function isDynamicPattern(pattern, options = {}) {
|
|
10383
|
-
if (pattern === "") {
|
|
10384
|
-
return false;
|
|
10385
|
-
}
|
|
10386
|
-
if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) {
|
|
10387
|
-
return true;
|
|
10388
|
-
}
|
|
10389
|
-
if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) {
|
|
10390
|
-
return true;
|
|
10391
|
-
}
|
|
10392
|
-
if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) {
|
|
10393
|
-
return true;
|
|
10556
|
+
class VitestWatcher {
|
|
10557
|
+
constructor(vitest) {
|
|
10558
|
+
this.vitest = vitest;
|
|
10394
10559
|
}
|
|
10395
|
-
|
|
10396
|
-
|
|
10560
|
+
/**
|
|
10561
|
+
* Modules that will be invalidated on the next run.
|
|
10562
|
+
*/
|
|
10563
|
+
invalidates = /* @__PURE__ */ new Set();
|
|
10564
|
+
/**
|
|
10565
|
+
* Test files that have changed and need to be rerun.
|
|
10566
|
+
*/
|
|
10567
|
+
changedTests = /* @__PURE__ */ new Set();
|
|
10568
|
+
_onRerun = [];
|
|
10569
|
+
/**
|
|
10570
|
+
* Register a handler that will be called when test files need to be rerun.
|
|
10571
|
+
* The callback can receive several files in case the changed file is imported by several test files.
|
|
10572
|
+
* Several invocations of this method will add multiple handlers.
|
|
10573
|
+
* @internal
|
|
10574
|
+
*/
|
|
10575
|
+
onWatcherRerun(cb) {
|
|
10576
|
+
this._onRerun.push(cb);
|
|
10577
|
+
return this;
|
|
10397
10578
|
}
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10579
|
+
unregisterWatcher = noop;
|
|
10580
|
+
registerWatcher() {
|
|
10581
|
+
const watcher = this.vitest.vite.watcher;
|
|
10582
|
+
if (this.vitest.config.forceRerunTriggers.length) {
|
|
10583
|
+
watcher.add(this.vitest.config.forceRerunTriggers);
|
|
10584
|
+
}
|
|
10585
|
+
watcher.on("change", this.onChange);
|
|
10586
|
+
watcher.on("unlink", this.onUnlink);
|
|
10587
|
+
watcher.on("add", this.onAdd);
|
|
10588
|
+
this.unregisterWatcher = () => {
|
|
10589
|
+
watcher.off("change", this.onChange);
|
|
10590
|
+
watcher.off("unlink", this.onUnlink);
|
|
10591
|
+
watcher.off("add", this.onAdd);
|
|
10592
|
+
this.unregisterWatcher = noop;
|
|
10593
|
+
};
|
|
10594
|
+
return this;
|
|
10404
10595
|
}
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
return false;
|
|
10596
|
+
scheduleRerun(file) {
|
|
10597
|
+
this._onRerun.forEach((cb) => cb(file));
|
|
10408
10598
|
}
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
)
|
|
10599
|
+
onChange = (id) => {
|
|
10600
|
+
id = slash(id);
|
|
10601
|
+
this.vitest.logger.clearHighlightCache(id);
|
|
10602
|
+
this.vitest.invalidateFile(id);
|
|
10603
|
+
const needsRerun = this.handleFileChanged(id);
|
|
10604
|
+
if (needsRerun) {
|
|
10605
|
+
this.scheduleRerun(id);
|
|
10606
|
+
}
|
|
10607
|
+
};
|
|
10608
|
+
onUnlink = (id) => {
|
|
10609
|
+
id = slash(id);
|
|
10610
|
+
this.vitest.logger.clearHighlightCache(id);
|
|
10611
|
+
this.invalidates.add(id);
|
|
10612
|
+
if (this.vitest.state.filesMap.has(id)) {
|
|
10613
|
+
this.vitest.state.filesMap.delete(id);
|
|
10614
|
+
this.vitest.cache.results.removeFromCache(id);
|
|
10615
|
+
this.vitest.cache.stats.removeStats(id);
|
|
10616
|
+
this.changedTests.delete(id);
|
|
10617
|
+
this.vitest.report("onTestRemoved", id);
|
|
10618
|
+
}
|
|
10619
|
+
};
|
|
10620
|
+
onAdd = (id) => {
|
|
10621
|
+
id = slash(id);
|
|
10622
|
+
this.vitest.invalidateFile(id);
|
|
10623
|
+
let fileContent;
|
|
10624
|
+
const matchingProjects = [];
|
|
10625
|
+
this.vitest.projects.forEach((project) => {
|
|
10626
|
+
if (project.matchesTestGlob(id, () => fileContent ??= readFileSync(id, "utf-8"))) {
|
|
10627
|
+
matchingProjects.push(project);
|
|
10628
|
+
}
|
|
10629
|
+
});
|
|
10630
|
+
if (matchingProjects.length > 0) {
|
|
10631
|
+
this.changedTests.add(id);
|
|
10632
|
+
this.scheduleRerun(id);
|
|
10633
|
+
} else {
|
|
10634
|
+
const needsRerun = this.handleFileChanged(id);
|
|
10635
|
+
if (needsRerun) {
|
|
10636
|
+
this.scheduleRerun(id);
|
|
10637
|
+
}
|
|
10638
|
+
}
|
|
10639
|
+
};
|
|
10640
|
+
/**
|
|
10641
|
+
* @returns A value indicating whether rerun is needed (changedTests was mutated)
|
|
10642
|
+
*/
|
|
10643
|
+
handleFileChanged(filepath) {
|
|
10644
|
+
if (this.changedTests.has(filepath) || this.invalidates.has(filepath)) {
|
|
10645
|
+
return false;
|
|
10646
|
+
}
|
|
10647
|
+
if (mm.isMatch(filepath, this.vitest.config.forceRerunTriggers)) {
|
|
10648
|
+
this.vitest.state.getFilepaths().forEach((file) => this.changedTests.add(file));
|
|
10649
|
+
return true;
|
|
10650
|
+
}
|
|
10651
|
+
const projects = this.vitest.projects.filter((project) => {
|
|
10652
|
+
const moduleGraph = project.browser?.vite.moduleGraph || project.vite.moduleGraph;
|
|
10653
|
+
return moduleGraph.getModulesByFile(filepath)?.size;
|
|
10654
|
+
});
|
|
10655
|
+
if (!projects.length) {
|
|
10656
|
+
if (this.vitest.state.filesMap.has(filepath) || this.vitest.projects.some((project) => project.isCachedTestFile(filepath))) {
|
|
10657
|
+
this.changedTests.add(filepath);
|
|
10658
|
+
return true;
|
|
10659
|
+
}
|
|
10660
|
+
return false;
|
|
10661
|
+
}
|
|
10662
|
+
const files = [];
|
|
10663
|
+
for (const project of projects) {
|
|
10664
|
+
const mods = project.browser?.vite.moduleGraph.getModulesByFile(filepath) || project.vite.moduleGraph.getModulesByFile(filepath);
|
|
10665
|
+
if (!mods || !mods.size) {
|
|
10666
|
+
continue;
|
|
10667
|
+
}
|
|
10668
|
+
this.invalidates.add(filepath);
|
|
10669
|
+
if (this.vitest.state.filesMap.has(filepath) || project.isCachedTestFile(filepath)) {
|
|
10670
|
+
this.changedTests.add(filepath);
|
|
10671
|
+
files.push(filepath);
|
|
10672
|
+
continue;
|
|
10673
|
+
}
|
|
10674
|
+
let rerun = false;
|
|
10675
|
+
for (const mod of mods) {
|
|
10676
|
+
mod.importers.forEach((i) => {
|
|
10677
|
+
if (!i.file) {
|
|
10678
|
+
return;
|
|
10679
|
+
}
|
|
10680
|
+
const needsRerun = this.handleFileChanged(i.file);
|
|
10681
|
+
if (needsRerun) {
|
|
10682
|
+
rerun = true;
|
|
10683
|
+
}
|
|
10684
|
+
});
|
|
10685
|
+
}
|
|
10686
|
+
if (rerun) {
|
|
10687
|
+
files.push(filepath);
|
|
10688
|
+
}
|
|
10689
|
+
}
|
|
10690
|
+
return !!files.length;
|
|
10691
|
+
}
|
|
10692
|
+
}
|
|
10693
|
+
|
|
10694
|
+
const ESCAPE_SYMBOL = "\\";
|
|
10695
|
+
const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/;
|
|
10696
|
+
const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[[^[]*\]/;
|
|
10697
|
+
const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\([^(]*\|[^|]*\)/;
|
|
10698
|
+
const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\([^(]*\)/;
|
|
10699
|
+
const BRACE_EXPANSION_SEPARATORS_RE = /,|\.\./;
|
|
10700
|
+
function isDynamicPattern(pattern, options = {}) {
|
|
10701
|
+
if (pattern === "") {
|
|
10702
|
+
return false;
|
|
10703
|
+
}
|
|
10704
|
+
if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) {
|
|
10705
|
+
return true;
|
|
10706
|
+
}
|
|
10707
|
+
if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) {
|
|
10708
|
+
return true;
|
|
10709
|
+
}
|
|
10710
|
+
if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) {
|
|
10711
|
+
return true;
|
|
10712
|
+
}
|
|
10713
|
+
if (options.braceExpansion !== false && hasBraceExpansion(pattern)) {
|
|
10714
|
+
return true;
|
|
10715
|
+
}
|
|
10716
|
+
return false;
|
|
10717
|
+
}
|
|
10718
|
+
function hasBraceExpansion(pattern) {
|
|
10719
|
+
const openingBraceIndex = pattern.indexOf("{");
|
|
10720
|
+
if (openingBraceIndex === -1) {
|
|
10721
|
+
return false;
|
|
10722
|
+
}
|
|
10723
|
+
const closingBraceIndex = pattern.indexOf("}", openingBraceIndex + 1);
|
|
10724
|
+
if (closingBraceIndex === -1) {
|
|
10725
|
+
return false;
|
|
10726
|
+
}
|
|
10727
|
+
const braceContent = pattern.slice(openingBraceIndex, closingBraceIndex);
|
|
10728
|
+
return BRACE_EXPANSION_SEPARATORS_RE.test(braceContent);
|
|
10729
|
+
}
|
|
10730
|
+
|
|
10731
|
+
async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspaceDefinition) {
|
|
10732
|
+
const { configFiles, projectConfigs, nonConfigDirectories } = await resolveTestProjectConfigs(
|
|
10733
|
+
vitest,
|
|
10734
|
+
workspaceConfigPath,
|
|
10735
|
+
workspaceDefinition
|
|
10736
|
+
);
|
|
10419
10737
|
const overridesOptions = [
|
|
10420
10738
|
"logHeapUsage",
|
|
10421
10739
|
"allowOnly",
|
|
@@ -10454,8 +10772,8 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
|
|
|
10454
10772
|
)));
|
|
10455
10773
|
});
|
|
10456
10774
|
for (const path of fileProjects) {
|
|
10457
|
-
if (vitest.
|
|
10458
|
-
projectPromises.push(Promise.resolve(vitest.
|
|
10775
|
+
if (vitest.vite.config.configFile === path) {
|
|
10776
|
+
projectPromises.push(Promise.resolve(vitest._ensureRootProject()));
|
|
10459
10777
|
continue;
|
|
10460
10778
|
}
|
|
10461
10779
|
const configFile = path.endsWith("/") ? false : path;
|
|
@@ -10469,7 +10787,7 @@ async function resolveWorkspace(vitest, cliOptions, workspaceConfigPath, workspa
|
|
|
10469
10787
|
);
|
|
10470
10788
|
}
|
|
10471
10789
|
if (!projectPromises.length) {
|
|
10472
|
-
return [vitest.
|
|
10790
|
+
return [vitest._ensureRootProject()];
|
|
10473
10791
|
}
|
|
10474
10792
|
const resolvedProjects = await Promise.all(projectPromises);
|
|
10475
10793
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -10529,8 +10847,8 @@ async function resolveTestProjectConfigs(vitest, workspaceConfigPath, workspaceD
|
|
|
10529
10847
|
}
|
|
10530
10848
|
} else if (typeof definition === "function") {
|
|
10531
10849
|
projectsOptions.push(await definition({
|
|
10532
|
-
command: vitest.
|
|
10533
|
-
mode: vitest.
|
|
10850
|
+
command: vitest.vite.config.command,
|
|
10851
|
+
mode: vitest.vite.config.mode,
|
|
10534
10852
|
isPreview: false,
|
|
10535
10853
|
isSsrBuild: false
|
|
10536
10854
|
}));
|
|
@@ -10591,53 +10909,141 @@ class Vitest {
|
|
|
10591
10909
|
this.mode = mode;
|
|
10592
10910
|
this.logger = new Logger(this, options.stdout, options.stderr);
|
|
10593
10911
|
this.packageInstaller = options.packageInstaller || new VitestPackageInstaller();
|
|
10912
|
+
this.specifications = new VitestSpecifications(this);
|
|
10913
|
+
this.watcher = new VitestWatcher(this).onWatcherRerun(
|
|
10914
|
+
(file) => this.scheduleRerun([file])
|
|
10915
|
+
// TODO: error handling
|
|
10916
|
+
);
|
|
10594
10917
|
}
|
|
10918
|
+
/**
|
|
10919
|
+
* Current Vitest version.
|
|
10920
|
+
* @example '2.0.0'
|
|
10921
|
+
*/
|
|
10595
10922
|
version = version$1;
|
|
10596
|
-
|
|
10923
|
+
static version = version$1;
|
|
10924
|
+
/**
|
|
10925
|
+
* The logger instance used to log messages. It's recommended to use this logger instead of `console`.
|
|
10926
|
+
* It's possible to override stdout and stderr streams when initiating Vitest.
|
|
10927
|
+
* @example
|
|
10928
|
+
* new Vitest('test', {
|
|
10929
|
+
* stdout: new Writable(),
|
|
10930
|
+
* })
|
|
10931
|
+
*/
|
|
10932
|
+
logger;
|
|
10933
|
+
/**
|
|
10934
|
+
* The package installer instance used to install Vitest packages.
|
|
10935
|
+
* @example
|
|
10936
|
+
* await vitest.packageInstaller.ensureInstalled('@vitest/browser', process.cwd())
|
|
10937
|
+
*/
|
|
10938
|
+
packageInstaller;
|
|
10939
|
+
/**
|
|
10940
|
+
* A path to the built Vitest directory. This is usually a folder in `node_modules`.
|
|
10941
|
+
*/
|
|
10942
|
+
distPath = distDir;
|
|
10943
|
+
/**
|
|
10944
|
+
* A list of projects that are currently running.
|
|
10945
|
+
* If projects were filtered with `--project` flag, they won't appear here.
|
|
10946
|
+
*/
|
|
10947
|
+
projects = [];
|
|
10948
|
+
/** @internal */
|
|
10597
10949
|
configOverride = {};
|
|
10598
|
-
|
|
10599
|
-
state = void 0;
|
|
10600
|
-
snapshot = void 0;
|
|
10601
|
-
cache = void 0;
|
|
10602
|
-
reporters = void 0;
|
|
10950
|
+
/** @internal */
|
|
10603
10951
|
coverageProvider;
|
|
10604
|
-
|
|
10605
|
-
pool;
|
|
10606
|
-
vitenode = void 0;
|
|
10607
|
-
invalidates = /* @__PURE__ */ new Set();
|
|
10608
|
-
changedTests = /* @__PURE__ */ new Set();
|
|
10609
|
-
watchedTests = /* @__PURE__ */ new Set();
|
|
10952
|
+
/** @internal */
|
|
10610
10953
|
filenamePattern;
|
|
10954
|
+
/** @internal */
|
|
10611
10955
|
runningPromise;
|
|
10956
|
+
/** @internal */
|
|
10612
10957
|
closingPromise;
|
|
10958
|
+
/** @internal */
|
|
10613
10959
|
isCancelling = false;
|
|
10614
|
-
isFirstRun = true;
|
|
10615
|
-
restartsCount = 0;
|
|
10616
|
-
runner = void 0;
|
|
10617
|
-
packageInstaller;
|
|
10618
|
-
/** TODO: rename to `_coreRootProject` */
|
|
10619
10960
|
/** @internal */
|
|
10620
10961
|
coreWorkspaceProject;
|
|
10621
|
-
/** @
|
|
10962
|
+
/** @internal */
|
|
10622
10963
|
resolvedProjects = [];
|
|
10623
|
-
projects = [];
|
|
10624
|
-
distPath = distDir;
|
|
10625
|
-
_cachedSpecs = /* @__PURE__ */ new Map();
|
|
10626
|
-
_workspaceConfigPath;
|
|
10627
|
-
/** @deprecated use `_cachedSpecs` */
|
|
10628
|
-
projectTestFiles = this._cachedSpecs;
|
|
10629
10964
|
/** @internal */
|
|
10630
10965
|
_browserLastPort = defaultBrowserPort;
|
|
10631
10966
|
/** @internal */
|
|
10632
10967
|
_options = {};
|
|
10968
|
+
/** @internal */
|
|
10969
|
+
reporters = void 0;
|
|
10970
|
+
/** @internal */
|
|
10971
|
+
vitenode = void 0;
|
|
10972
|
+
/** @internal */
|
|
10973
|
+
runner = void 0;
|
|
10974
|
+
isFirstRun = true;
|
|
10975
|
+
restartsCount = 0;
|
|
10976
|
+
specifications;
|
|
10977
|
+
watcher;
|
|
10978
|
+
pool;
|
|
10979
|
+
_config;
|
|
10980
|
+
_vite;
|
|
10981
|
+
_state;
|
|
10982
|
+
_cache;
|
|
10983
|
+
_snapshot;
|
|
10984
|
+
_workspaceConfigPath;
|
|
10633
10985
|
_onRestartListeners = [];
|
|
10634
10986
|
_onClose = [];
|
|
10635
10987
|
_onSetServer = [];
|
|
10636
10988
|
_onCancelListeners = [];
|
|
10637
10989
|
_onUserTestsRerun = [];
|
|
10638
|
-
|
|
10990
|
+
_onFilterWatchedSpecification = [];
|
|
10991
|
+
/** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */
|
|
10992
|
+
get invalidates() {
|
|
10993
|
+
return this.watcher.invalidates;
|
|
10994
|
+
}
|
|
10995
|
+
/** @deprecated will be removed in 4.0, use `onFilterWatchedSpecification` instead */
|
|
10996
|
+
get changedTests() {
|
|
10997
|
+
return this.watcher.changedTests;
|
|
10998
|
+
}
|
|
10999
|
+
/**
|
|
11000
|
+
* The global config.
|
|
11001
|
+
*/
|
|
11002
|
+
get config() {
|
|
11003
|
+
assert(this._config, "config");
|
|
11004
|
+
return this._config;
|
|
11005
|
+
}
|
|
11006
|
+
/** @deprecated use `vitest.vite` instead */
|
|
11007
|
+
get server() {
|
|
11008
|
+
return this._vite;
|
|
11009
|
+
}
|
|
11010
|
+
/**
|
|
11011
|
+
* Global Vite's dev server instance.
|
|
11012
|
+
*/
|
|
11013
|
+
get vite() {
|
|
11014
|
+
assert(this._vite, "vite", "server");
|
|
11015
|
+
return this._vite;
|
|
11016
|
+
}
|
|
11017
|
+
/**
|
|
11018
|
+
* The global test state manager.
|
|
11019
|
+
* @experimental The State API is experimental and not subject to semver.
|
|
11020
|
+
*/
|
|
11021
|
+
get state() {
|
|
11022
|
+
assert(this._state, "state");
|
|
11023
|
+
return this._state;
|
|
11024
|
+
}
|
|
11025
|
+
/**
|
|
11026
|
+
* The global snapshot manager. You can access the current state on `snapshot.summary`.
|
|
11027
|
+
*/
|
|
11028
|
+
get snapshot() {
|
|
11029
|
+
assert(this._snapshot, "snapshot", "snapshot manager");
|
|
11030
|
+
return this._snapshot;
|
|
11031
|
+
}
|
|
11032
|
+
/**
|
|
11033
|
+
* Test results and test file stats cache. Primarily used by the sequencer to sort tests.
|
|
11034
|
+
*/
|
|
11035
|
+
get cache() {
|
|
11036
|
+
assert(this._cache, "cache");
|
|
11037
|
+
return this._cache;
|
|
11038
|
+
}
|
|
11039
|
+
/** @deprecated internal */
|
|
11040
|
+
setServer(options, server, cliOptions) {
|
|
11041
|
+
return this._setServer(options, server, cliOptions);
|
|
11042
|
+
}
|
|
11043
|
+
/** @internal */
|
|
11044
|
+
async _setServer(options, server, cliOptions) {
|
|
10639
11045
|
this._options = options;
|
|
10640
|
-
this.unregisterWatcher
|
|
11046
|
+
this.watcher.unregisterWatcher();
|
|
10641
11047
|
clearTimeout(this._rerunTimer);
|
|
10642
11048
|
this.restartsCount += 1;
|
|
10643
11049
|
this._browserLastPort = defaultBrowserPort;
|
|
@@ -10649,16 +11055,16 @@ class Vitest {
|
|
|
10649
11055
|
this._workspaceConfigPath = void 0;
|
|
10650
11056
|
this.coverageProvider = void 0;
|
|
10651
11057
|
this.runningPromise = void 0;
|
|
10652
|
-
this.
|
|
11058
|
+
this.specifications.clearCache();
|
|
10653
11059
|
this._onUserTestsRerun = [];
|
|
10654
11060
|
const resolved = resolveConfig(this.mode, options, server.config, this.logger);
|
|
10655
|
-
this.
|
|
10656
|
-
this.
|
|
10657
|
-
this.
|
|
10658
|
-
this.
|
|
10659
|
-
this.
|
|
11061
|
+
this._vite = server;
|
|
11062
|
+
this._config = resolved;
|
|
11063
|
+
this._state = new StateManager();
|
|
11064
|
+
this._cache = new VitestCache(this.version);
|
|
11065
|
+
this._snapshot = new SnapshotManager({ ...resolved.snapshotOptions });
|
|
10660
11066
|
if (this.config.watch) {
|
|
10661
|
-
this.registerWatcher();
|
|
11067
|
+
this.watcher.registerWatcher();
|
|
10662
11068
|
}
|
|
10663
11069
|
this.vitenode = new ViteNodeServer(server, this.config.server);
|
|
10664
11070
|
const node = this.vitenode;
|
|
@@ -10691,7 +11097,6 @@ class Vitest {
|
|
|
10691
11097
|
}
|
|
10692
11098
|
});
|
|
10693
11099
|
}
|
|
10694
|
-
this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this);
|
|
10695
11100
|
this.cache.results.setConfig(resolved.root, resolved.cache);
|
|
10696
11101
|
try {
|
|
10697
11102
|
await this.cache.results.readFromCache();
|
|
@@ -10705,6 +11110,9 @@ class Vitest {
|
|
|
10705
11110
|
this.projects = this.projects.filter(
|
|
10706
11111
|
(p) => filters.some((pattern) => pattern.test(p.name))
|
|
10707
11112
|
);
|
|
11113
|
+
if (!this.projects.length) {
|
|
11114
|
+
throw new Error(`No projects matched the filter "${toArray(resolved.project).join('", "')}".`);
|
|
11115
|
+
}
|
|
10708
11116
|
}
|
|
10709
11117
|
if (!this.coreWorkspaceProject) {
|
|
10710
11118
|
this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
@@ -10712,19 +11120,37 @@ class Vitest {
|
|
|
10712
11120
|
if (this.config.testNamePattern) {
|
|
10713
11121
|
this.configOverride.testNamePattern = this.config.testNamePattern;
|
|
10714
11122
|
}
|
|
11123
|
+
this.reporters = resolved.mode === "benchmark" ? await createBenchmarkReporters(toArray(resolved.benchmark?.reporters), this.runner) : await createReporters(resolved.reporters, this);
|
|
10715
11124
|
await Promise.all(this._onSetServer.map((fn) => fn()));
|
|
10716
11125
|
}
|
|
10717
|
-
provide(key, value) {
|
|
10718
|
-
this.getRootTestProject().provide(key, value);
|
|
10719
|
-
}
|
|
10720
11126
|
/**
|
|
10721
|
-
*
|
|
11127
|
+
* Provide a value to the test context. This value will be available to all tests with `inject`.
|
|
10722
11128
|
*/
|
|
10723
|
-
|
|
11129
|
+
provide = (key, value) => {
|
|
11130
|
+
this.getRootProject().provide(key, value);
|
|
11131
|
+
};
|
|
11132
|
+
/**
|
|
11133
|
+
* Get global provided context.
|
|
11134
|
+
*/
|
|
11135
|
+
getProvidedContext() {
|
|
11136
|
+
return this.getRootProject().getProvidedContext();
|
|
11137
|
+
}
|
|
11138
|
+
/** @internal */
|
|
11139
|
+
_ensureRootProject() {
|
|
11140
|
+
if (this.coreWorkspaceProject) {
|
|
11141
|
+
return this.coreWorkspaceProject;
|
|
11142
|
+
}
|
|
10724
11143
|
this.coreWorkspaceProject = TestProject._createBasicProject(this);
|
|
10725
11144
|
return this.coreWorkspaceProject;
|
|
10726
11145
|
}
|
|
10727
|
-
|
|
11146
|
+
/** @deprecated use `getRootProject` instead */
|
|
11147
|
+
getCoreWorkspaceProject() {
|
|
11148
|
+
return this.getRootProject();
|
|
11149
|
+
}
|
|
11150
|
+
/**
|
|
11151
|
+
* Return project that has the root (or "global") config.
|
|
11152
|
+
*/
|
|
11153
|
+
getRootProject() {
|
|
10728
11154
|
if (!this.coreWorkspaceProject) {
|
|
10729
11155
|
throw new Error(`Root project is not initialized. This means that the Vite server was not established yet and the the workspace config is not resolved.`);
|
|
10730
11156
|
}
|
|
@@ -10736,16 +11162,27 @@ class Vitest {
|
|
|
10736
11162
|
getProjectByTaskId(taskId) {
|
|
10737
11163
|
const task = this.state.idMap.get(taskId);
|
|
10738
11164
|
const projectName = task.projectName || task?.file?.projectName || "";
|
|
10739
|
-
return this.
|
|
11165
|
+
return this.getProjectByName(projectName);
|
|
10740
11166
|
}
|
|
10741
|
-
getProjectByName(name
|
|
10742
|
-
|
|
11167
|
+
getProjectByName(name) {
|
|
11168
|
+
const project = this.projects.find((p) => p.name === name) || this.coreWorkspaceProject || this.projects[0];
|
|
11169
|
+
if (!project) {
|
|
11170
|
+
throw new Error(`Project "${name}" was not found.`);
|
|
11171
|
+
}
|
|
11172
|
+
return project;
|
|
11173
|
+
}
|
|
11174
|
+
/**
|
|
11175
|
+
* Import a file using Vite module runner. The file will be transformed by Vite and executed in a separate context.
|
|
11176
|
+
* @param moduleId The ID of the module in Vite module graph
|
|
11177
|
+
*/
|
|
11178
|
+
import(moduleId) {
|
|
11179
|
+
return this.runner.executeId(moduleId);
|
|
10743
11180
|
}
|
|
10744
11181
|
async resolveWorkspaceConfigPath() {
|
|
10745
11182
|
if (typeof this.config.workspace === "string") {
|
|
10746
11183
|
return this.config.workspace;
|
|
10747
11184
|
}
|
|
10748
|
-
const configDir = this.
|
|
11185
|
+
const configDir = this.vite.config.configFile ? dirname(this.vite.config.configFile) : this.config.root;
|
|
10749
11186
|
const rootFiles = await promises.readdir(configDir);
|
|
10750
11187
|
const workspaceConfigName = workspacesFiles.find((configFile) => {
|
|
10751
11188
|
return rootFiles.includes(configFile);
|
|
@@ -10767,9 +11204,9 @@ class Vitest {
|
|
|
10767
11204
|
const workspaceConfigPath = await this.resolveWorkspaceConfigPath();
|
|
10768
11205
|
this._workspaceConfigPath = workspaceConfigPath;
|
|
10769
11206
|
if (!workspaceConfigPath) {
|
|
10770
|
-
return [this.
|
|
11207
|
+
return [this._ensureRootProject()];
|
|
10771
11208
|
}
|
|
10772
|
-
const workspaceModule = await this.
|
|
11209
|
+
const workspaceModule = await this.import(workspaceConfigPath);
|
|
10773
11210
|
if (!workspaceModule.default || !Array.isArray(workspaceModule.default)) {
|
|
10774
11211
|
throw new TypeError(`Workspace config file "${workspaceConfigPath}" must export a default array of project paths.`);
|
|
10775
11212
|
}
|
|
@@ -10780,6 +11217,13 @@ class Vitest {
|
|
|
10780
11217
|
workspaceModule.default
|
|
10781
11218
|
);
|
|
10782
11219
|
}
|
|
11220
|
+
/**
|
|
11221
|
+
* Glob test files in every project and create a TestSpecification for each file and pool.
|
|
11222
|
+
* @param filters String filters to match the test files.
|
|
11223
|
+
*/
|
|
11224
|
+
async globTestSpecifications(filters = []) {
|
|
11225
|
+
return this.specifications.globTestSpecifications(filters);
|
|
11226
|
+
}
|
|
10783
11227
|
async initCoverageProvider() {
|
|
10784
11228
|
if (this.coverageProvider !== void 0) {
|
|
10785
11229
|
return;
|
|
@@ -10794,16 +11238,19 @@ class Vitest {
|
|
|
10794
11238
|
}
|
|
10795
11239
|
return this.coverageProvider;
|
|
10796
11240
|
}
|
|
10797
|
-
|
|
11241
|
+
/**
|
|
11242
|
+
* Merge reports from multiple runs located in the specified directory (value from `--merge-reports` if not specified).
|
|
11243
|
+
*/
|
|
11244
|
+
async mergeReports(directory) {
|
|
10798
11245
|
if (this.reporters.some((r) => r instanceof BlobReporter)) {
|
|
10799
11246
|
throw new Error("Cannot merge reports when `--reporter=blob` is used. Remove blob reporter from the config first.");
|
|
10800
11247
|
}
|
|
10801
|
-
const { files, errors, coverages } = await readBlobs(this.version, this.config.mergeReports, this.projects);
|
|
11248
|
+
const { files, errors, coverages } = await readBlobs(this.version, directory || this.config.mergeReports, this.projects);
|
|
10802
11249
|
await this.report("onInit", this);
|
|
10803
11250
|
await this.report("onPathsCollected", files.flatMap((f) => f.filepath));
|
|
10804
11251
|
const workspaceSpecs = /* @__PURE__ */ new Map();
|
|
10805
11252
|
for (const file of files) {
|
|
10806
|
-
const project = this.getProjectByName(file.projectName);
|
|
11253
|
+
const project = this.getProjectByName(file.projectName || "");
|
|
10807
11254
|
const specs = workspaceSpecs.get(project) || [];
|
|
10808
11255
|
specs.push(file);
|
|
10809
11256
|
workspaceSpecs.set(project, specs);
|
|
@@ -10836,31 +11283,42 @@ class Vitest {
|
|
|
10836
11283
|
if (hasFailed(files)) {
|
|
10837
11284
|
process.exitCode = 1;
|
|
10838
11285
|
}
|
|
10839
|
-
this.
|
|
11286
|
+
this._checkUnhandledErrors(errors);
|
|
10840
11287
|
await this.report("onFinished", files, errors);
|
|
10841
11288
|
await this.initCoverageProvider();
|
|
10842
11289
|
await this.coverageProvider?.mergeReports?.(coverages);
|
|
11290
|
+
return {
|
|
11291
|
+
testModules: this.state.getTestModules(),
|
|
11292
|
+
unhandledErrors: this.state.getUnhandledErrors()
|
|
11293
|
+
};
|
|
10843
11294
|
}
|
|
10844
11295
|
async collect(filters) {
|
|
10845
11296
|
this._onClose = [];
|
|
10846
|
-
const files = await this.
|
|
10847
|
-
await this.globTestFiles(filters)
|
|
10848
|
-
);
|
|
11297
|
+
const files = await this.specifications.getRelevantTestSpecifications(filters);
|
|
10849
11298
|
if (!files.length) {
|
|
10850
|
-
return {
|
|
11299
|
+
return { testModules: [], unhandledErrors: [] };
|
|
10851
11300
|
}
|
|
10852
|
-
|
|
10853
|
-
return {
|
|
10854
|
-
tests: this.state.getFiles(),
|
|
10855
|
-
errors: this.state.getUnhandledErrors()
|
|
10856
|
-
};
|
|
11301
|
+
return this.collectTests(files);
|
|
10857
11302
|
}
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
10861
|
-
|
|
10862
|
-
|
|
11303
|
+
/** @deprecated use `getRelevantTestSpecifications` instead */
|
|
11304
|
+
listFiles(filters) {
|
|
11305
|
+
return this.getRelevantTestSpecifications(filters);
|
|
11306
|
+
}
|
|
11307
|
+
/**
|
|
11308
|
+
* Returns the list of test files that match the config and filters.
|
|
11309
|
+
* @param filters String filters to match the test files
|
|
11310
|
+
*/
|
|
11311
|
+
getRelevantTestSpecifications(filters) {
|
|
11312
|
+
return this.specifications.getRelevantTestSpecifications(filters);
|
|
10863
11313
|
}
|
|
11314
|
+
/**
|
|
11315
|
+
* Initialize reporters, the coverage provider, and run tests.
|
|
11316
|
+
* This method can throw an error:
|
|
11317
|
+
* - `FilesNotFoundError` if no tests are found
|
|
11318
|
+
* - `GitNotFoundError` if `--related` flag is used, but git repository is not initialized
|
|
11319
|
+
* - `Error` from the user reporters
|
|
11320
|
+
* @param filters String filters to match the test files
|
|
11321
|
+
*/
|
|
10864
11322
|
async start(filters) {
|
|
10865
11323
|
this._onClose = [];
|
|
10866
11324
|
try {
|
|
@@ -10869,9 +11327,8 @@ class Vitest {
|
|
|
10869
11327
|
} finally {
|
|
10870
11328
|
await this.report("onInit", this);
|
|
10871
11329
|
}
|
|
10872
|
-
|
|
10873
|
-
|
|
10874
|
-
);
|
|
11330
|
+
this.filenamePattern = filters && filters?.length > 0 ? filters : void 0;
|
|
11331
|
+
const files = await this.specifications.getRelevantTestSpecifications(filters);
|
|
10875
11332
|
if (!files.length) {
|
|
10876
11333
|
const coverage = await this.coverageProvider?.generateCoverage?.({ allTestsRun: true });
|
|
10877
11334
|
await this.reportCoverage(coverage, true);
|
|
@@ -10882,121 +11339,85 @@ class Vitest {
|
|
|
10882
11339
|
throw new FilesNotFoundError(this.mode);
|
|
10883
11340
|
}
|
|
10884
11341
|
}
|
|
11342
|
+
let testModules = {
|
|
11343
|
+
testModules: [],
|
|
11344
|
+
unhandledErrors: []
|
|
11345
|
+
};
|
|
10885
11346
|
if (files.length) {
|
|
10886
11347
|
await this.cache.stats.populateStats(this.config.root, files);
|
|
10887
|
-
await this.runFiles(files, true);
|
|
11348
|
+
testModules = await this.runFiles(files, true);
|
|
10888
11349
|
}
|
|
10889
11350
|
if (this.config.watch) {
|
|
10890
11351
|
await this.report("onWatcherStart");
|
|
10891
11352
|
}
|
|
11353
|
+
return testModules;
|
|
10892
11354
|
}
|
|
11355
|
+
/**
|
|
11356
|
+
* Initialize reporters and the coverage provider. This method doesn't run any tests.
|
|
11357
|
+
* If the `--watch` flag is provided, Vitest will still run changed tests even if this method was not called.
|
|
11358
|
+
*/
|
|
10893
11359
|
async init() {
|
|
10894
11360
|
this._onClose = [];
|
|
10895
11361
|
try {
|
|
10896
11362
|
await this.initCoverageProvider();
|
|
10897
11363
|
await this.coverageProvider?.clean(this.config.coverage.clean);
|
|
10898
11364
|
} finally {
|
|
10899
|
-
await this.report("onInit", this);
|
|
10900
|
-
}
|
|
10901
|
-
await this.globTestFiles();
|
|
10902
|
-
if (this.config.watch) {
|
|
10903
|
-
await this.report("onWatcherStart");
|
|
10904
|
-
}
|
|
10905
|
-
}
|
|
10906
|
-
async getTestDependencies(spec, deps = /* @__PURE__ */ new Set()) {
|
|
10907
|
-
const addImports = async (project, filepath) => {
|
|
10908
|
-
if (deps.has(filepath)) {
|
|
10909
|
-
return;
|
|
10910
|
-
}
|
|
10911
|
-
deps.add(filepath);
|
|
10912
|
-
const mod = project.vite.moduleGraph.getModuleById(filepath);
|
|
10913
|
-
const transformed = mod?.ssrTransformResult || await project.vitenode.transformRequest(filepath);
|
|
10914
|
-
if (!transformed) {
|
|
10915
|
-
return;
|
|
10916
|
-
}
|
|
10917
|
-
const dependencies = [...transformed.deps || [], ...transformed.dynamicDeps || []];
|
|
10918
|
-
await Promise.all(dependencies.map(async (dep) => {
|
|
10919
|
-
const path = await project.vite.pluginContainer.resolveId(dep, filepath, { ssr: true });
|
|
10920
|
-
const fsPath = path && !path.external && path.id.split("?")[0];
|
|
10921
|
-
if (fsPath && !fsPath.includes("node_modules") && !deps.has(fsPath) && existsSync(fsPath)) {
|
|
10922
|
-
await addImports(project, fsPath);
|
|
10923
|
-
}
|
|
10924
|
-
}));
|
|
10925
|
-
};
|
|
10926
|
-
await addImports(spec.project, spec.moduleId);
|
|
10927
|
-
deps.delete(spec.moduleId);
|
|
10928
|
-
return deps;
|
|
10929
|
-
}
|
|
10930
|
-
async filterTestsBySource(specs) {
|
|
10931
|
-
if (this.config.changed && !this.config.related) {
|
|
10932
|
-
const { VitestGit } = await import('./git.B5SDxu-n.js');
|
|
10933
|
-
const vitestGit = new VitestGit(this.config.root);
|
|
10934
|
-
const related2 = await vitestGit.findChangedFiles({
|
|
10935
|
-
changedSince: this.config.changed
|
|
10936
|
-
});
|
|
10937
|
-
if (!related2) {
|
|
10938
|
-
process.exitCode = 1;
|
|
10939
|
-
throw new GitNotFoundError();
|
|
10940
|
-
}
|
|
10941
|
-
this.config.related = Array.from(new Set(related2));
|
|
10942
|
-
}
|
|
10943
|
-
const related = this.config.related;
|
|
10944
|
-
if (!related) {
|
|
10945
|
-
return specs;
|
|
10946
|
-
}
|
|
10947
|
-
const forceRerunTriggers = this.config.forceRerunTriggers;
|
|
10948
|
-
if (forceRerunTriggers.length && mm(related, forceRerunTriggers).length) {
|
|
10949
|
-
return specs;
|
|
10950
|
-
}
|
|
10951
|
-
if (!this.config.watch && !related.length) {
|
|
10952
|
-
return [];
|
|
11365
|
+
await this.report("onInit", this);
|
|
10953
11366
|
}
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
return [spec, deps];
|
|
10958
|
-
})
|
|
10959
|
-
);
|
|
10960
|
-
const runningTests = [];
|
|
10961
|
-
for (const [filepath, deps] of testGraphs) {
|
|
10962
|
-
if (related.some((path) => path === filepath[1] || deps.has(path))) {
|
|
10963
|
-
runningTests.push(filepath);
|
|
10964
|
-
}
|
|
11367
|
+
await this.globTestSpecifications();
|
|
11368
|
+
if (this.config.watch) {
|
|
11369
|
+
await this.report("onWatcherStart");
|
|
10965
11370
|
}
|
|
10966
|
-
return runningTests;
|
|
10967
11371
|
}
|
|
10968
11372
|
/**
|
|
10969
|
-
* @deprecated remove when vscode extension supports "
|
|
11373
|
+
* @deprecated remove when vscode extension supports "getModuleSpecifications"
|
|
10970
11374
|
*/
|
|
10971
11375
|
getProjectsByTestFile(file) {
|
|
10972
|
-
return this.
|
|
11376
|
+
return this.getModuleSpecifications(file);
|
|
10973
11377
|
}
|
|
11378
|
+
/** @deprecated */
|
|
10974
11379
|
getFileWorkspaceSpecs(file) {
|
|
10975
|
-
|
|
10976
|
-
if (_cached) {
|
|
10977
|
-
return _cached;
|
|
10978
|
-
}
|
|
10979
|
-
const specs = [];
|
|
10980
|
-
for (const project of this.projects) {
|
|
10981
|
-
if (project.isTestFile(file)) {
|
|
10982
|
-
specs.push(project.createSpecification(file));
|
|
10983
|
-
}
|
|
10984
|
-
if (project.isTypecheckFile(file)) {
|
|
10985
|
-
specs.push(project.createSpecification(file, "typescript"));
|
|
10986
|
-
}
|
|
10987
|
-
}
|
|
10988
|
-
specs.forEach((spec) => this.ensureSpecCached(spec));
|
|
10989
|
-
return specs;
|
|
11380
|
+
return this.getModuleSpecifications(file);
|
|
10990
11381
|
}
|
|
10991
|
-
|
|
10992
|
-
|
|
10993
|
-
|
|
10994
|
-
|
|
10995
|
-
|
|
10996
|
-
|
|
10997
|
-
|
|
10998
|
-
|
|
10999
|
-
|
|
11382
|
+
/**
|
|
11383
|
+
* Get test specifications assosiated with the given module. If module is not a test file, an empty array is returned.
|
|
11384
|
+
*
|
|
11385
|
+
* **Note:** this method relies on a cache generated by `globTestSpecifications`. If the file was not processed yet, use `project.matchesGlobPattern` instead.
|
|
11386
|
+
* @param moduleId The module ID to get test specifications for.
|
|
11387
|
+
*/
|
|
11388
|
+
getModuleSpecifications(moduleId) {
|
|
11389
|
+
return this.specifications.getModuleSpecifications(moduleId);
|
|
11390
|
+
}
|
|
11391
|
+
/**
|
|
11392
|
+
* Vitest automatically caches test specifications for each file. This method clears the cache for the given file or the whole cache alltogether.
|
|
11393
|
+
*/
|
|
11394
|
+
clearSpecificationsCache(moduleId) {
|
|
11395
|
+
this.specifications.clearCache(moduleId);
|
|
11396
|
+
}
|
|
11397
|
+
/**
|
|
11398
|
+
* Run tests for the given test specifications. This does not trigger `onWatcher*` events.
|
|
11399
|
+
* @param specifications A list of specifications to run.
|
|
11400
|
+
* @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
|
|
11401
|
+
*/
|
|
11402
|
+
runTestSpecifications(specifications, allTestsRun = false) {
|
|
11403
|
+
specifications.forEach((spec) => this.specifications.ensureSpecificationCached(spec));
|
|
11404
|
+
return this.runFiles(specifications, allTestsRun);
|
|
11405
|
+
}
|
|
11406
|
+
/**
|
|
11407
|
+
* Rerun files and trigger `onWatcherRerun`, `onWatcherStart` and `onTestsRerun` events.
|
|
11408
|
+
* @param specifications A list of specifications to run.
|
|
11409
|
+
* @param allTestsRun Indicates whether all tests were run. This only matters for coverage.
|
|
11410
|
+
*/
|
|
11411
|
+
async rerunTestSpecifications(specifications, allTestsRun = false) {
|
|
11412
|
+
this.configOverride.testNamePattern = void 0;
|
|
11413
|
+
const files = specifications.map((spec) => spec.moduleId);
|
|
11414
|
+
await Promise.all([
|
|
11415
|
+
this.report("onWatcherRerun", files, "rerun test"),
|
|
11416
|
+
...this._onUserTestsRerun.map((fn) => fn(specifications))
|
|
11417
|
+
]);
|
|
11418
|
+
const result = await this.runTestSpecifications(specifications, allTestsRun);
|
|
11419
|
+
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
11420
|
+
return result;
|
|
11000
11421
|
}
|
|
11001
11422
|
async runFiles(specs, allTestsRun) {
|
|
11002
11423
|
const filepaths = specs.map((spec) => spec.moduleId);
|
|
@@ -11011,8 +11432,8 @@ class Vitest {
|
|
|
11011
11432
|
if (!this.pool) {
|
|
11012
11433
|
this.pool = createPool(this);
|
|
11013
11434
|
}
|
|
11014
|
-
const invalidates = Array.from(this.invalidates);
|
|
11015
|
-
this.invalidates.clear();
|
|
11435
|
+
const invalidates = Array.from(this.watcher.invalidates);
|
|
11436
|
+
this.watcher.invalidates.clear();
|
|
11016
11437
|
this.snapshot.clear();
|
|
11017
11438
|
this.state.clearErrors();
|
|
11018
11439
|
if (!this.isFirstRun && this.config.coverage.cleanOnRerun) {
|
|
@@ -11030,11 +11451,15 @@ class Vitest {
|
|
|
11030
11451
|
}
|
|
11031
11452
|
this.cache.results.updateResults(files);
|
|
11032
11453
|
await this.cache.results.writeToCache();
|
|
11454
|
+
return {
|
|
11455
|
+
testModules: this.state.getTestModules(),
|
|
11456
|
+
unhandledErrors: this.state.getUnhandledErrors()
|
|
11457
|
+
};
|
|
11033
11458
|
} finally {
|
|
11034
11459
|
const files = Array.from(new Set(specs.map((spec) => spec.moduleId)));
|
|
11035
11460
|
const errors = this.state.getUnhandledErrors();
|
|
11036
11461
|
const coverage = await this.coverageProvider?.generateCoverage({ allTestsRun });
|
|
11037
|
-
this.
|
|
11462
|
+
this._checkUnhandledErrors(errors);
|
|
11038
11463
|
await this.report("onFinished", this.state.getFiles(files), errors, coverage);
|
|
11039
11464
|
await this.reportCoverage(coverage, allTestsRun);
|
|
11040
11465
|
}
|
|
@@ -11046,8 +11471,12 @@ class Vitest {
|
|
|
11046
11471
|
});
|
|
11047
11472
|
return await this.runningPromise;
|
|
11048
11473
|
}
|
|
11049
|
-
|
|
11050
|
-
|
|
11474
|
+
/**
|
|
11475
|
+
* Collect tests in specified modules. Vitest will run the files to collect tests.
|
|
11476
|
+
* @param specifications A list of specifications to run.
|
|
11477
|
+
*/
|
|
11478
|
+
async collectTests(specifications) {
|
|
11479
|
+
const filepaths = specifications.map((spec) => spec.moduleId);
|
|
11051
11480
|
this.state.collectPaths(filepaths);
|
|
11052
11481
|
await this.runningPromise;
|
|
11053
11482
|
this._onCancelListeners = [];
|
|
@@ -11056,13 +11485,13 @@ class Vitest {
|
|
|
11056
11485
|
if (!this.pool) {
|
|
11057
11486
|
this.pool = createPool(this);
|
|
11058
11487
|
}
|
|
11059
|
-
const invalidates = Array.from(this.invalidates);
|
|
11060
|
-
this.invalidates.clear();
|
|
11488
|
+
const invalidates = Array.from(this.watcher.invalidates);
|
|
11489
|
+
this.watcher.invalidates.clear();
|
|
11061
11490
|
this.snapshot.clear();
|
|
11062
11491
|
this.state.clearErrors();
|
|
11063
|
-
await this.initializeGlobalSetup(
|
|
11492
|
+
await this.initializeGlobalSetup(specifications);
|
|
11064
11493
|
try {
|
|
11065
|
-
await this.pool.collectTests(
|
|
11494
|
+
await this.pool.collectTests(specifications, invalidates);
|
|
11066
11495
|
} catch (err) {
|
|
11067
11496
|
this.state.catchError(err, "Unhandled Error");
|
|
11068
11497
|
}
|
|
@@ -11070,6 +11499,10 @@ class Vitest {
|
|
|
11070
11499
|
if (hasFailed(files)) {
|
|
11071
11500
|
process.exitCode = 1;
|
|
11072
11501
|
}
|
|
11502
|
+
return {
|
|
11503
|
+
testModules: this.state.getTestModules(),
|
|
11504
|
+
unhandledErrors: this.state.getUnhandledErrors()
|
|
11505
|
+
};
|
|
11073
11506
|
})().finally(() => {
|
|
11074
11507
|
this.runningPromise = void 0;
|
|
11075
11508
|
this.config.changed = false;
|
|
@@ -11077,31 +11510,45 @@ class Vitest {
|
|
|
11077
11510
|
});
|
|
11078
11511
|
return await this.runningPromise;
|
|
11079
11512
|
}
|
|
11513
|
+
/**
|
|
11514
|
+
* Gracefully cancel the current test run. Vitest will wait until all running tests are finished before cancelling.
|
|
11515
|
+
*/
|
|
11080
11516
|
async cancelCurrentRun(reason) {
|
|
11081
11517
|
this.isCancelling = true;
|
|
11082
11518
|
await Promise.all(this._onCancelListeners.splice(0).map((listener) => listener(reason)));
|
|
11083
11519
|
}
|
|
11084
|
-
|
|
11520
|
+
/** @internal */
|
|
11521
|
+
async _initBrowserServers() {
|
|
11085
11522
|
await Promise.all(this.projects.map((p) => p._initBrowserServer()));
|
|
11086
11523
|
}
|
|
11524
|
+
async initializeGlobalSetup(paths) {
|
|
11525
|
+
const projects = new Set(paths.map((spec) => spec.project));
|
|
11526
|
+
const coreProject = this.getRootProject();
|
|
11527
|
+
if (!projects.has(coreProject)) {
|
|
11528
|
+
projects.add(coreProject);
|
|
11529
|
+
}
|
|
11530
|
+
for (const project of projects) {
|
|
11531
|
+
await project._initializeGlobalSetup();
|
|
11532
|
+
}
|
|
11533
|
+
}
|
|
11534
|
+
/** @internal */
|
|
11087
11535
|
async rerunFiles(files = this.state.getFilepaths(), trigger, allTestsRun = true, resetTestNamePattern = false) {
|
|
11088
11536
|
if (resetTestNamePattern) {
|
|
11089
11537
|
this.configOverride.testNamePattern = void 0;
|
|
11090
11538
|
}
|
|
11091
11539
|
if (this.filenamePattern) {
|
|
11092
|
-
const filteredFiles = await this.
|
|
11093
|
-
files = files.filter((file) => filteredFiles.some((f) => f
|
|
11540
|
+
const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
|
|
11541
|
+
files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
|
|
11094
11542
|
}
|
|
11543
|
+
const specifications = files.flatMap((file) => this.getModuleSpecifications(file));
|
|
11095
11544
|
await Promise.all([
|
|
11096
11545
|
this.report("onWatcherRerun", files, trigger),
|
|
11097
|
-
...this._onUserTestsRerun.map((fn) => fn(
|
|
11546
|
+
...this._onUserTestsRerun.map((fn) => fn(specifications))
|
|
11098
11547
|
]);
|
|
11099
|
-
await this.runFiles(
|
|
11548
|
+
await this.runFiles(specifications, allTestsRun);
|
|
11100
11549
|
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
11101
11550
|
}
|
|
11102
|
-
|
|
11103
|
-
return Object.hasOwnProperty.call(task, "tasks");
|
|
11104
|
-
}
|
|
11551
|
+
/** @internal */
|
|
11105
11552
|
async rerunTask(id) {
|
|
11106
11553
|
const task = this.state.idMap.get(id);
|
|
11107
11554
|
if (!task) {
|
|
@@ -11110,9 +11557,10 @@ class Vitest {
|
|
|
11110
11557
|
await this.changeNamePattern(
|
|
11111
11558
|
task.name,
|
|
11112
11559
|
[task.file.filepath],
|
|
11113
|
-
|
|
11560
|
+
"tasks" in task ? "rerun suite" : "rerun test"
|
|
11114
11561
|
);
|
|
11115
11562
|
}
|
|
11563
|
+
/** @internal */
|
|
11116
11564
|
async changeProjectName(pattern) {
|
|
11117
11565
|
if (pattern === "") {
|
|
11118
11566
|
delete this.configOverride.project;
|
|
@@ -11120,9 +11568,10 @@ class Vitest {
|
|
|
11120
11568
|
this.configOverride.project = pattern;
|
|
11121
11569
|
}
|
|
11122
11570
|
this.projects = this.resolvedProjects.filter((p) => p.name === pattern);
|
|
11123
|
-
const files = (await this.
|
|
11571
|
+
const files = (await this.globTestSpecifications()).map((spec) => spec.moduleId);
|
|
11124
11572
|
await this.rerunFiles(files, "change project filter", pattern === "");
|
|
11125
11573
|
}
|
|
11574
|
+
/** @internal */
|
|
11126
11575
|
async changeNamePattern(pattern, files = this.state.getFilepaths(), trigger) {
|
|
11127
11576
|
if (pattern === "") {
|
|
11128
11577
|
this.filenamePattern = void 0;
|
|
@@ -11140,31 +11589,68 @@ class Vitest {
|
|
|
11140
11589
|
}
|
|
11141
11590
|
await this.rerunFiles(files, trigger, pattern === "");
|
|
11142
11591
|
}
|
|
11592
|
+
/** @internal */
|
|
11143
11593
|
async changeFilenamePattern(pattern, files = this.state.getFilepaths()) {
|
|
11144
|
-
this.filenamePattern = pattern;
|
|
11145
|
-
const trigger = this.filenamePattern ? "change filename pattern" : "reset filename pattern";
|
|
11594
|
+
this.filenamePattern = pattern ? [pattern] : [];
|
|
11595
|
+
const trigger = this.filenamePattern.length ? "change filename pattern" : "reset filename pattern";
|
|
11146
11596
|
await this.rerunFiles(files, trigger, pattern === "");
|
|
11147
11597
|
}
|
|
11598
|
+
/** @internal */
|
|
11148
11599
|
async rerunFailed() {
|
|
11149
11600
|
await this.rerunFiles(this.state.getFailedFilepaths(), "rerun failed", false);
|
|
11150
11601
|
}
|
|
11602
|
+
/** @internal */
|
|
11151
11603
|
async updateSnapshot(files) {
|
|
11152
11604
|
files = files || [
|
|
11153
11605
|
...this.state.getFailedFilepaths(),
|
|
11154
11606
|
...this.snapshot.summary.uncheckedKeysByFile.map((s) => s.filePath)
|
|
11155
11607
|
];
|
|
11608
|
+
this.enableSnapshotUpdate();
|
|
11609
|
+
try {
|
|
11610
|
+
await this.rerunFiles(files, "update snapshot", false);
|
|
11611
|
+
} finally {
|
|
11612
|
+
this.resetSnapshotUpdate();
|
|
11613
|
+
}
|
|
11614
|
+
}
|
|
11615
|
+
/**
|
|
11616
|
+
* Enable the mode that allows updating snapshots when running tests.
|
|
11617
|
+
* This method doesn't run any tests.
|
|
11618
|
+
*
|
|
11619
|
+
* Every test that runs after this method is called will update snapshots.
|
|
11620
|
+
* To disable the mode, call `resetSnapshotUpdate`.
|
|
11621
|
+
*/
|
|
11622
|
+
enableSnapshotUpdate() {
|
|
11156
11623
|
this.configOverride.snapshotOptions = {
|
|
11157
11624
|
updateSnapshot: "all",
|
|
11158
11625
|
// environment is resolved inside a worker thread
|
|
11159
11626
|
snapshotEnvironment: null
|
|
11160
11627
|
};
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
|
|
11164
|
-
|
|
11628
|
+
}
|
|
11629
|
+
/**
|
|
11630
|
+
* Disable the mode that allows updating snapshots when running tests.
|
|
11631
|
+
*/
|
|
11632
|
+
resetSnapshotUpdate() {
|
|
11633
|
+
delete this.configOverride.snapshotOptions;
|
|
11634
|
+
}
|
|
11635
|
+
/**
|
|
11636
|
+
* Set the global test name pattern to a regexp.
|
|
11637
|
+
* This method doesn't run any tests.
|
|
11638
|
+
*/
|
|
11639
|
+
setGlobalTestNamePattern(pattern) {
|
|
11640
|
+
if (pattern instanceof RegExp) {
|
|
11641
|
+
this.configOverride.testNamePattern = pattern;
|
|
11642
|
+
} else {
|
|
11643
|
+
this.configOverride.testNamePattern = pattern ? new RegExp(pattern) : void 0;
|
|
11165
11644
|
}
|
|
11166
11645
|
}
|
|
11646
|
+
/**
|
|
11647
|
+
* Resets the global test name pattern. This method doesn't run any tests.
|
|
11648
|
+
*/
|
|
11649
|
+
resetGlobalTestNamePattern() {
|
|
11650
|
+
this.configOverride.testNamePattern = void 0;
|
|
11651
|
+
}
|
|
11167
11652
|
_rerunTimer;
|
|
11653
|
+
// we can't use a single `triggerId` yet because vscode extension relies on this
|
|
11168
11654
|
async scheduleRerun(triggerId) {
|
|
11169
11655
|
const currentCount = this.restartsCount;
|
|
11170
11656
|
clearTimeout(this._rerunTimer);
|
|
@@ -11174,15 +11660,8 @@ class Vitest {
|
|
|
11174
11660
|
return;
|
|
11175
11661
|
}
|
|
11176
11662
|
this._rerunTimer = setTimeout(async () => {
|
|
11177
|
-
if (this.
|
|
11178
|
-
this.
|
|
11179
|
-
if (!this.watchedTests.has(test)) {
|
|
11180
|
-
this.changedTests.delete(test);
|
|
11181
|
-
}
|
|
11182
|
-
});
|
|
11183
|
-
}
|
|
11184
|
-
if (this.changedTests.size === 0) {
|
|
11185
|
-
this.invalidates.clear();
|
|
11663
|
+
if (this.watcher.changedTests.size === 0) {
|
|
11664
|
+
this.watcher.invalidates.clear();
|
|
11186
11665
|
return;
|
|
11187
11666
|
}
|
|
11188
11667
|
if (this.restartsCount !== currentCount) {
|
|
@@ -11190,161 +11669,54 @@ class Vitest {
|
|
|
11190
11669
|
}
|
|
11191
11670
|
this.isFirstRun = false;
|
|
11192
11671
|
this.snapshot.clear();
|
|
11193
|
-
let files = Array.from(this.changedTests);
|
|
11672
|
+
let files = Array.from(this.watcher.changedTests);
|
|
11194
11673
|
if (this.filenamePattern) {
|
|
11195
|
-
const filteredFiles = await this.
|
|
11196
|
-
files = files.filter((file) => filteredFiles.some((f) => f
|
|
11674
|
+
const filteredFiles = await this.globTestSpecifications(this.filenamePattern);
|
|
11675
|
+
files = files.filter((file) => filteredFiles.some((f) => f.moduleId === file));
|
|
11197
11676
|
if (files.length === 0) {
|
|
11198
11677
|
return;
|
|
11199
11678
|
}
|
|
11200
11679
|
}
|
|
11201
|
-
this.changedTests.clear();
|
|
11680
|
+
this.watcher.changedTests.clear();
|
|
11202
11681
|
const triggerIds = new Set(triggerId.map((id) => relative(this.config.root, id)));
|
|
11203
11682
|
const triggerLabel = Array.from(triggerIds).join(", ");
|
|
11683
|
+
const specifications = files.flatMap((file) => this.getModuleSpecifications(file)).filter((specification) => {
|
|
11684
|
+
if (this._onFilterWatchedSpecification.length === 0) {
|
|
11685
|
+
return true;
|
|
11686
|
+
}
|
|
11687
|
+
return this._onFilterWatchedSpecification.every((fn) => fn(specification));
|
|
11688
|
+
});
|
|
11204
11689
|
await Promise.all([
|
|
11205
11690
|
this.report("onWatcherRerun", files, triggerLabel),
|
|
11206
|
-
...this._onUserTestsRerun.map((fn) => fn(
|
|
11691
|
+
...this._onUserTestsRerun.map((fn) => fn(specifications))
|
|
11207
11692
|
]);
|
|
11208
|
-
await this.runFiles(
|
|
11693
|
+
await this.runFiles(specifications, false);
|
|
11209
11694
|
await this.report("onWatcherStart", this.state.getFiles(files));
|
|
11210
11695
|
}, WATCHER_DEBOUNCE);
|
|
11211
11696
|
}
|
|
11212
|
-
getModuleProjects(filepath) {
|
|
11213
|
-
return this.projects.filter((project) => {
|
|
11214
|
-
return project.getModulesByFilepath(filepath).size;
|
|
11215
|
-
});
|
|
11216
|
-
}
|
|
11217
11697
|
/**
|
|
11218
|
-
*
|
|
11698
|
+
* Invalidate a file in all projects.
|
|
11219
11699
|
*/
|
|
11220
|
-
|
|
11221
|
-
this.
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
}
|
|
11225
|
-
updateLastChanged(filepath) {
|
|
11226
|
-
const projects = this.getModuleProjects(filepath);
|
|
11227
|
-
projects.forEach(({ server, browser }) => {
|
|
11228
|
-
const serverMods = server.moduleGraph.getModulesByFile(filepath);
|
|
11229
|
-
serverMods?.forEach((mod) => server.moduleGraph.invalidateModule(mod));
|
|
11700
|
+
invalidateFile(filepath) {
|
|
11701
|
+
this.projects.forEach(({ vite, browser }) => {
|
|
11702
|
+
const serverMods = vite.moduleGraph.getModulesByFile(filepath);
|
|
11703
|
+
serverMods?.forEach((mod) => vite.moduleGraph.invalidateModule(mod));
|
|
11230
11704
|
if (browser) {
|
|
11231
11705
|
const browserMods = browser.vite.moduleGraph.getModulesByFile(filepath);
|
|
11232
11706
|
browserMods?.forEach((mod) => browser.vite.moduleGraph.invalidateModule(mod));
|
|
11233
11707
|
}
|
|
11234
11708
|
});
|
|
11235
11709
|
}
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
this.
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
this.scheduleRerun(needsRerun);
|
|
11243
|
-
}
|
|
11244
|
-
};
|
|
11245
|
-
onUnlink = (id) => {
|
|
11246
|
-
id = slash(id);
|
|
11247
|
-
this.logger.clearHighlightCache(id);
|
|
11248
|
-
this.invalidates.add(id);
|
|
11249
|
-
if (this.state.filesMap.has(id)) {
|
|
11250
|
-
this.state.filesMap.delete(id);
|
|
11251
|
-
this.cache.results.removeFromCache(id);
|
|
11252
|
-
this.cache.stats.removeStats(id);
|
|
11253
|
-
this.changedTests.delete(id);
|
|
11254
|
-
this.report("onTestRemoved", id);
|
|
11255
|
-
}
|
|
11256
|
-
};
|
|
11257
|
-
onAdd = async (id) => {
|
|
11258
|
-
id = slash(id);
|
|
11259
|
-
this.updateLastChanged(id);
|
|
11260
|
-
const fileContent = readFileSync(id, "utf-8");
|
|
11261
|
-
const matchingProjects = [];
|
|
11262
|
-
this.projects.forEach((project) => {
|
|
11263
|
-
if (project.matchesTestGlob(id, fileContent)) {
|
|
11264
|
-
matchingProjects.push(project);
|
|
11265
|
-
project._markTestFile(id);
|
|
11266
|
-
}
|
|
11267
|
-
});
|
|
11268
|
-
if (matchingProjects.length > 0) {
|
|
11269
|
-
this.changedTests.add(id);
|
|
11270
|
-
this.scheduleRerun([id]);
|
|
11271
|
-
} else {
|
|
11272
|
-
const needsRerun = this.handleFileChanged(id);
|
|
11273
|
-
if (needsRerun.length) {
|
|
11274
|
-
this.scheduleRerun(needsRerun);
|
|
11275
|
-
}
|
|
11276
|
-
}
|
|
11277
|
-
};
|
|
11278
|
-
checkUnhandledErrors(errors) {
|
|
11710
|
+
/** @deprecated use `invalidateFile` */
|
|
11711
|
+
updateLastChanged(filepath) {
|
|
11712
|
+
this.invalidateFile(filepath);
|
|
11713
|
+
}
|
|
11714
|
+
/** @internal */
|
|
11715
|
+
_checkUnhandledErrors(errors) {
|
|
11279
11716
|
if (errors.length && !this.config.dangerouslyIgnoreUnhandledErrors) {
|
|
11280
11717
|
process.exitCode = 1;
|
|
11281
11718
|
}
|
|
11282
11719
|
}
|
|
11283
|
-
unregisterWatcher = noop;
|
|
11284
|
-
registerWatcher() {
|
|
11285
|
-
const watcher = this.server.watcher;
|
|
11286
|
-
if (this.config.forceRerunTriggers.length) {
|
|
11287
|
-
watcher.add(this.config.forceRerunTriggers);
|
|
11288
|
-
}
|
|
11289
|
-
watcher.on("change", this.onChange);
|
|
11290
|
-
watcher.on("unlink", this.onUnlink);
|
|
11291
|
-
watcher.on("add", this.onAdd);
|
|
11292
|
-
this.unregisterWatcher = () => {
|
|
11293
|
-
watcher.off("change", this.onChange);
|
|
11294
|
-
watcher.off("unlink", this.onUnlink);
|
|
11295
|
-
watcher.off("add", this.onAdd);
|
|
11296
|
-
this.unregisterWatcher = noop;
|
|
11297
|
-
};
|
|
11298
|
-
}
|
|
11299
|
-
/**
|
|
11300
|
-
* @returns A value indicating whether rerun is needed (changedTests was mutated)
|
|
11301
|
-
*/
|
|
11302
|
-
handleFileChanged(filepath) {
|
|
11303
|
-
if (this.changedTests.has(filepath) || this.invalidates.has(filepath)) {
|
|
11304
|
-
return [];
|
|
11305
|
-
}
|
|
11306
|
-
if (mm.isMatch(filepath, this.config.forceRerunTriggers)) {
|
|
11307
|
-
this.state.getFilepaths().forEach((file) => this.changedTests.add(file));
|
|
11308
|
-
return [filepath];
|
|
11309
|
-
}
|
|
11310
|
-
const projects = this.getModuleProjects(filepath);
|
|
11311
|
-
if (!projects.length) {
|
|
11312
|
-
if (this.state.filesMap.has(filepath) || this.projects.some((project) => project.isTestFile(filepath))) {
|
|
11313
|
-
this.changedTests.add(filepath);
|
|
11314
|
-
return [filepath];
|
|
11315
|
-
}
|
|
11316
|
-
return [];
|
|
11317
|
-
}
|
|
11318
|
-
const files = [];
|
|
11319
|
-
for (const project of projects) {
|
|
11320
|
-
const mods = project.getModulesByFilepath(filepath);
|
|
11321
|
-
if (!mods.size) {
|
|
11322
|
-
continue;
|
|
11323
|
-
}
|
|
11324
|
-
this.invalidates.add(filepath);
|
|
11325
|
-
if (this.state.filesMap.has(filepath) || project.isTestFile(filepath)) {
|
|
11326
|
-
this.changedTests.add(filepath);
|
|
11327
|
-
files.push(filepath);
|
|
11328
|
-
continue;
|
|
11329
|
-
}
|
|
11330
|
-
let rerun = false;
|
|
11331
|
-
for (const mod of mods) {
|
|
11332
|
-
mod.importers.forEach((i) => {
|
|
11333
|
-
if (!i.file) {
|
|
11334
|
-
return;
|
|
11335
|
-
}
|
|
11336
|
-
const heedsRerun = this.handleFileChanged(i.file);
|
|
11337
|
-
if (heedsRerun.length) {
|
|
11338
|
-
rerun = true;
|
|
11339
|
-
}
|
|
11340
|
-
});
|
|
11341
|
-
}
|
|
11342
|
-
if (rerun) {
|
|
11343
|
-
files.push(filepath);
|
|
11344
|
-
}
|
|
11345
|
-
}
|
|
11346
|
-
return Array.from(new Set(files));
|
|
11347
|
-
}
|
|
11348
11720
|
async reportCoverage(coverage, allTestsRun) {
|
|
11349
11721
|
if (this.state.getCountOfFailedTests() > 0) {
|
|
11350
11722
|
await this.coverageProvider?.onTestFailure?.();
|
|
@@ -11361,19 +11733,23 @@ class Vitest {
|
|
|
11361
11733
|
}
|
|
11362
11734
|
}
|
|
11363
11735
|
}
|
|
11736
|
+
/**
|
|
11737
|
+
* Closes all projects and their associated resources.
|
|
11738
|
+
* This can only be called once; the closing promise is cached until the server restarts.
|
|
11739
|
+
*/
|
|
11364
11740
|
async close() {
|
|
11365
11741
|
if (!this.closingPromise) {
|
|
11366
11742
|
this.closingPromise = (async () => {
|
|
11367
11743
|
const teardownProjects = [...this.projects];
|
|
11368
|
-
if (!teardownProjects.includes(this.coreWorkspaceProject)) {
|
|
11744
|
+
if (this.coreWorkspaceProject && !teardownProjects.includes(this.coreWorkspaceProject)) {
|
|
11369
11745
|
teardownProjects.push(this.coreWorkspaceProject);
|
|
11370
11746
|
}
|
|
11371
11747
|
for (const project of teardownProjects.reverse()) {
|
|
11372
11748
|
await project._teardownGlobalSetup();
|
|
11373
11749
|
}
|
|
11374
11750
|
const closePromises = this.resolvedProjects.map((w) => w.close());
|
|
11375
|
-
if (!this.resolvedProjects.includes(this.coreWorkspaceProject)) {
|
|
11376
|
-
closePromises.push(this.coreWorkspaceProject.close().then(() => this.
|
|
11751
|
+
if (this.coreWorkspaceProject && !this.resolvedProjects.includes(this.coreWorkspaceProject)) {
|
|
11752
|
+
closePromises.push(this.coreWorkspaceProject.close().then(() => this._vite = void 0));
|
|
11377
11753
|
}
|
|
11378
11754
|
if (this.pool) {
|
|
11379
11755
|
closePromises.push((async () => {
|
|
@@ -11395,7 +11771,8 @@ class Vitest {
|
|
|
11395
11771
|
return this.closingPromise;
|
|
11396
11772
|
}
|
|
11397
11773
|
/**
|
|
11398
|
-
*
|
|
11774
|
+
* Closes all projects and exit the process
|
|
11775
|
+
* @param force If true, the process will exit immediately after closing the projects.
|
|
11399
11776
|
*/
|
|
11400
11777
|
async exit(force = false) {
|
|
11401
11778
|
setTimeout(() => {
|
|
@@ -11403,7 +11780,7 @@ class Vitest {
|
|
|
11403
11780
|
console.warn(`close timed out after ${this.config.teardownTimeout}ms`);
|
|
11404
11781
|
this.state.getProcessTimeoutCauses().forEach((cause) => console.warn(cause));
|
|
11405
11782
|
if (!this.pool) {
|
|
11406
|
-
const runningServers = [this.
|
|
11783
|
+
const runningServers = [this.vite, ...this.resolvedProjects.map((p) => p.vite)].filter(Boolean).length;
|
|
11407
11784
|
if (runningServers === 1) {
|
|
11408
11785
|
console.warn("Tests closed successfully but something prevents Vite server from exiting");
|
|
11409
11786
|
} else if (runningServers > 1) {
|
|
@@ -11421,94 +11798,90 @@ class Vitest {
|
|
|
11421
11798
|
process.exit();
|
|
11422
11799
|
}
|
|
11423
11800
|
}
|
|
11801
|
+
/** @internal */
|
|
11424
11802
|
async report(name, ...args) {
|
|
11425
11803
|
await Promise.all(this.reporters.map((r) => r[name]?.(
|
|
11426
11804
|
...args
|
|
11427
11805
|
)));
|
|
11428
11806
|
}
|
|
11429
|
-
|
|
11430
|
-
|
|
11807
|
+
/** @internal */
|
|
11808
|
+
async _globTestFilepaths() {
|
|
11809
|
+
const specifications = await this.globTestSpecifications();
|
|
11810
|
+
return Array.from(new Set(specifications.map((spec) => spec.moduleId)));
|
|
11431
11811
|
}
|
|
11812
|
+
/**
|
|
11813
|
+
* @deprecated use `globTestSpecifications` instead
|
|
11814
|
+
*/
|
|
11432
11815
|
async globTestSpecs(filters = []) {
|
|
11433
|
-
|
|
11434
|
-
const dir = process.cwd();
|
|
11435
|
-
const parsedFilters = filters.map((f) => parseFilter(f));
|
|
11436
|
-
if (!this.config.includeTaskLocation && parsedFilters.some((f) => f.lineNumber !== void 0)) {
|
|
11437
|
-
throw new IncludeTaskLocationDisabledError();
|
|
11438
|
-
}
|
|
11439
|
-
const testLocations = groupFilters(parsedFilters.map(
|
|
11440
|
-
(f) => ({ ...f, filename: slash(resolve$1(dir, f.filename)) })
|
|
11441
|
-
));
|
|
11442
|
-
const testLocHasMatch = {};
|
|
11443
|
-
await Promise.all(this.projects.map(async (project) => {
|
|
11444
|
-
const { testFiles, typecheckTestFiles } = await project.globTestFiles(
|
|
11445
|
-
parsedFilters.map((f) => f.filename)
|
|
11446
|
-
);
|
|
11447
|
-
testFiles.forEach((file) => {
|
|
11448
|
-
const loc = testLocations[file];
|
|
11449
|
-
testLocHasMatch[file] = true;
|
|
11450
|
-
const spec = project.createSpecification(file, void 0, loc);
|
|
11451
|
-
this.ensureSpecCached(spec);
|
|
11452
|
-
files.push(spec);
|
|
11453
|
-
});
|
|
11454
|
-
typecheckTestFiles.forEach((file) => {
|
|
11455
|
-
const loc = testLocations[file];
|
|
11456
|
-
testLocHasMatch[file] = true;
|
|
11457
|
-
const spec = project.createSpecification(file, "typescript", loc);
|
|
11458
|
-
this.ensureSpecCached(spec);
|
|
11459
|
-
files.push(spec);
|
|
11460
|
-
});
|
|
11461
|
-
}));
|
|
11462
|
-
Object.entries(testLocations).forEach(([filepath, loc]) => {
|
|
11463
|
-
if (loc.length !== 0 && !testLocHasMatch[filepath]) {
|
|
11464
|
-
throw new LocationFilterFileNotFoundError(
|
|
11465
|
-
relative(dir, filepath)
|
|
11466
|
-
);
|
|
11467
|
-
}
|
|
11468
|
-
});
|
|
11469
|
-
return files;
|
|
11816
|
+
return this.globTestSpecifications(filters);
|
|
11470
11817
|
}
|
|
11471
11818
|
/**
|
|
11472
|
-
* @deprecated use `
|
|
11819
|
+
* @deprecated use `globTestSpecifications` instead
|
|
11473
11820
|
*/
|
|
11474
11821
|
async globTestFiles(filters = []) {
|
|
11475
|
-
return this.
|
|
11822
|
+
return this.globTestSpecifications(filters);
|
|
11476
11823
|
}
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
specs.push(spec);
|
|
11483
|
-
this._cachedSpecs.set(file, specs);
|
|
11484
|
-
}
|
|
11824
|
+
/** @deprecated filter by `this.projects` yourself */
|
|
11825
|
+
getModuleProjects(filepath) {
|
|
11826
|
+
return this.projects.filter((project) => {
|
|
11827
|
+
return project.getModulesByFilepath(filepath).size;
|
|
11828
|
+
});
|
|
11485
11829
|
}
|
|
11486
|
-
|
|
11830
|
+
/**
|
|
11831
|
+
* Should the server be kept running after the tests are done.
|
|
11832
|
+
*/
|
|
11487
11833
|
shouldKeepServer() {
|
|
11488
11834
|
return !!this.config?.watch;
|
|
11489
11835
|
}
|
|
11836
|
+
/**
|
|
11837
|
+
* Register a handler that will be called when the server is restarted due to a config change.
|
|
11838
|
+
*/
|
|
11490
11839
|
onServerRestart(fn) {
|
|
11491
11840
|
this._onRestartListeners.push(fn);
|
|
11492
11841
|
}
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11842
|
+
/**
|
|
11843
|
+
* Register a handler that will be called when the test run is cancelled with `vitest.cancelCurrentRun`.
|
|
11844
|
+
*/
|
|
11496
11845
|
onCancel(fn) {
|
|
11497
11846
|
this._onCancelListeners.push(fn);
|
|
11498
11847
|
}
|
|
11848
|
+
/**
|
|
11849
|
+
* Register a handler that will be called when the server is closed.
|
|
11850
|
+
*/
|
|
11499
11851
|
onClose(fn) {
|
|
11500
11852
|
this._onClose.push(fn);
|
|
11501
11853
|
}
|
|
11854
|
+
/**
|
|
11855
|
+
* Register a handler that will be called when the tests are rerunning.
|
|
11856
|
+
*/
|
|
11502
11857
|
onTestsRerun(fn) {
|
|
11503
11858
|
this._onUserTestsRerun.push(fn);
|
|
11504
11859
|
}
|
|
11860
|
+
/**
|
|
11861
|
+
* Register a handler that will be called when a file is changed.
|
|
11862
|
+
* This callback should return `true` of `false` indicating whether the test file needs to be rerun.
|
|
11863
|
+
* @example
|
|
11864
|
+
* const testsToRun = [resolve('./test.spec.ts')]
|
|
11865
|
+
* vitest.onFilterWatchedSpecification(specification => testsToRun.includes(specification.moduleId))
|
|
11866
|
+
*/
|
|
11867
|
+
onFilterWatchedSpecification(fn) {
|
|
11868
|
+
this._onFilterWatchedSpecification.push(fn);
|
|
11869
|
+
}
|
|
11870
|
+
/** @internal */
|
|
11871
|
+
onAfterSetServer(fn) {
|
|
11872
|
+
this._onSetServer.push(fn);
|
|
11873
|
+
}
|
|
11874
|
+
}
|
|
11875
|
+
function assert(condition, property, name = property) {
|
|
11876
|
+
if (!condition) {
|
|
11877
|
+
throw new Error(`The ${name} was not set. It means that \`vitest.${property}\` was called before the Vite server was established. Either await the Vitest promise or check that it is initialized with \`vitest.ready()\` before accessing \`vitest.${property}\`.`);
|
|
11878
|
+
}
|
|
11505
11879
|
}
|
|
11506
11880
|
|
|
11507
11881
|
async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
11508
11882
|
const userConfig = deepMerge({}, options);
|
|
11509
|
-
const getRoot = () => ctx.config?.root || options.root || process.cwd();
|
|
11510
11883
|
async function UIPlugin() {
|
|
11511
|
-
await ctx.packageInstaller.ensureInstalled("@vitest/ui",
|
|
11884
|
+
await ctx.packageInstaller.ensureInstalled("@vitest/ui", options.root || process.cwd(), ctx.version);
|
|
11512
11885
|
return (await import('@vitest/ui')).default(ctx);
|
|
11513
11886
|
}
|
|
11514
11887
|
return [
|
|
@@ -11558,7 +11931,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
11558
11931
|
ws: testConfig.api?.middlewareMode ? false : void 0,
|
|
11559
11932
|
preTransformRequests: false,
|
|
11560
11933
|
fs: {
|
|
11561
|
-
allow: resolveFsAllow(
|
|
11934
|
+
allow: resolveFsAllow(options.root || process.cwd(), testConfig.config)
|
|
11562
11935
|
}
|
|
11563
11936
|
},
|
|
11564
11937
|
build: {
|
|
@@ -11634,7 +12007,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
11634
12007
|
config.css.modules ??= {};
|
|
11635
12008
|
if (config.css.modules) {
|
|
11636
12009
|
config.css.modules.generateScopedName = (name, filename) => {
|
|
11637
|
-
const root =
|
|
12010
|
+
const root = ctx.config.root || options.root || process.cwd();
|
|
11638
12011
|
return generateScopedClassName(
|
|
11639
12012
|
classNameStrategy,
|
|
11640
12013
|
name,
|
|
@@ -11665,6 +12038,11 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
11665
12038
|
viteConfig.server.watch = null;
|
|
11666
12039
|
}
|
|
11667
12040
|
hijackVitePluginInject(viteConfig);
|
|
12041
|
+
Object.defineProperty(viteConfig, "_vitest", {
|
|
12042
|
+
value: options,
|
|
12043
|
+
enumerable: false,
|
|
12044
|
+
configurable: true
|
|
12045
|
+
});
|
|
11668
12046
|
},
|
|
11669
12047
|
configureServer: {
|
|
11670
12048
|
// runs after vite:import-analysis as it relies on `server` instance on Vite 5
|
|
@@ -11675,7 +12053,7 @@ async function VitestPlugin(options = {}, ctx = new Vitest("test")) {
|
|
|
11675
12053
|
console.log("[debug] watcher is ready");
|
|
11676
12054
|
});
|
|
11677
12055
|
}
|
|
11678
|
-
await ctx.
|
|
12056
|
+
await ctx._setServer(options, server, userConfig);
|
|
11679
12057
|
if (options.api && options.watch) {
|
|
11680
12058
|
(await Promise.resolve().then(function () { return setup$1; })).setup(ctx);
|
|
11681
12059
|
}
|
|
@@ -11947,7 +12325,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout2) {
|
|
|
11947
12325
|
return ctx.updateSnapshot();
|
|
11948
12326
|
}
|
|
11949
12327
|
if (name === "a" || name === "return") {
|
|
11950
|
-
const files = await ctx.
|
|
12328
|
+
const files = await ctx._globTestFilepaths();
|
|
11951
12329
|
return ctx.changeNamePattern("", files, "rerun all tests");
|
|
11952
12330
|
}
|
|
11953
12331
|
if (name === "r") {
|
|
@@ -11966,7 +12344,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout2) {
|
|
|
11966
12344
|
return inputFilePattern();
|
|
11967
12345
|
}
|
|
11968
12346
|
if (name === "b") {
|
|
11969
|
-
await ctx.
|
|
12347
|
+
await ctx._initBrowserServers();
|
|
11970
12348
|
ctx.projects.forEach((project) => {
|
|
11971
12349
|
ctx.logger.log();
|
|
11972
12350
|
ctx.logger.printBrowserBanner(project);
|
|
@@ -11999,7 +12377,7 @@ function registerConsoleShortcuts(ctx, stdin = process.stdin, stdout2) {
|
|
|
11999
12377
|
return;
|
|
12000
12378
|
}
|
|
12001
12379
|
const files = ctx.state.getFilepaths();
|
|
12002
|
-
const cliFiles = ctx.config.standalone && !files.length ? await ctx.
|
|
12380
|
+
const cliFiles = ctx.config.standalone && !files.length ? await ctx._globTestFilepaths() : void 0;
|
|
12003
12381
|
await ctx.changeNamePattern(
|
|
12004
12382
|
filter?.trim() || "",
|
|
12005
12383
|
cliFiles,
|
|
@@ -12153,11 +12531,10 @@ async function prepareVitest(mode, options = {}, viteOverrides, vitestOptions) {
|
|
|
12153
12531
|
function processCollected(ctx, files, options) {
|
|
12154
12532
|
let errorsPrinted = false;
|
|
12155
12533
|
forEachSuite(files, (suite) => {
|
|
12156
|
-
|
|
12157
|
-
errors.forEach((error) => {
|
|
12534
|
+
suite.errors().forEach((error) => {
|
|
12158
12535
|
errorsPrinted = true;
|
|
12159
12536
|
ctx.logger.printError(error, {
|
|
12160
|
-
project:
|
|
12537
|
+
project: suite.project
|
|
12161
12538
|
});
|
|
12162
12539
|
});
|
|
12163
12540
|
});
|
|
@@ -12215,43 +12592,50 @@ function processJsonOutput(files, options) {
|
|
|
12215
12592
|
writeFileSync(jsonPath, JSON.stringify(formatCollectedAsJSON(files), null, 2));
|
|
12216
12593
|
}
|
|
12217
12594
|
}
|
|
12218
|
-
function forEachSuite(
|
|
12219
|
-
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
12595
|
+
function forEachSuite(modules, callback) {
|
|
12596
|
+
modules.forEach((testModule) => {
|
|
12597
|
+
callback(testModule);
|
|
12598
|
+
for (const suite of testModule.children.allSuites()) {
|
|
12599
|
+
callback(suite);
|
|
12223
12600
|
}
|
|
12224
12601
|
});
|
|
12225
12602
|
}
|
|
12226
12603
|
function formatCollectedAsJSON(files) {
|
|
12227
|
-
|
|
12228
|
-
|
|
12229
|
-
|
|
12604
|
+
const results = [];
|
|
12605
|
+
files.forEach((file) => {
|
|
12606
|
+
for (const test of file.children.allTests()) {
|
|
12607
|
+
if (test.skipped()) {
|
|
12608
|
+
continue;
|
|
12609
|
+
}
|
|
12230
12610
|
const result = {
|
|
12231
|
-
name:
|
|
12232
|
-
file:
|
|
12611
|
+
name: test.fullName,
|
|
12612
|
+
file: test.module.moduleId
|
|
12233
12613
|
};
|
|
12234
|
-
if (test.
|
|
12235
|
-
result.projectName = test.
|
|
12614
|
+
if (test.project.name) {
|
|
12615
|
+
result.projectName = test.project.name;
|
|
12236
12616
|
}
|
|
12237
12617
|
if (test.location) {
|
|
12238
12618
|
result.location = test.location;
|
|
12239
12619
|
}
|
|
12240
|
-
|
|
12241
|
-
}
|
|
12242
|
-
})
|
|
12620
|
+
results.push(result);
|
|
12621
|
+
}
|
|
12622
|
+
});
|
|
12623
|
+
return results;
|
|
12243
12624
|
}
|
|
12244
|
-
function formatCollectedAsString(
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
return `[${test.file.projectName}] ${name}`;
|
|
12625
|
+
function formatCollectedAsString(testModules) {
|
|
12626
|
+
const results = [];
|
|
12627
|
+
testModules.forEach((testModule) => {
|
|
12628
|
+
for (const test of testModule.children.allTests()) {
|
|
12629
|
+
if (test.skipped()) {
|
|
12630
|
+
continue;
|
|
12251
12631
|
}
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12632
|
+
const fullName = `${test.module.task.name} > ${test.fullName}`;
|
|
12633
|
+
results.push(
|
|
12634
|
+
(test.project.name ? `[${test.project.name}] ` : "") + fullName
|
|
12635
|
+
);
|
|
12636
|
+
}
|
|
12637
|
+
});
|
|
12638
|
+
return results;
|
|
12255
12639
|
}
|
|
12256
12640
|
const envPackageNames = {
|
|
12257
12641
|
"jsdom": "jsdom",
|
|
@@ -12281,4 +12665,4 @@ var cliApi = /*#__PURE__*/Object.freeze({
|
|
|
12281
12665
|
startVitest: startVitest
|
|
12282
12666
|
});
|
|
12283
12667
|
|
|
12284
|
-
export { FilesNotFoundError as F, GitNotFoundError as G,
|
|
12668
|
+
export { FilesNotFoundError as F, GitNotFoundError as G, Vitest as V, VitestPlugin as a, VitestPackageInstaller as b, createVitest as c, registerConsoleShortcuts as d, createViteLogger as e, cliApi as f, resolveFsAllow as r, startVitest as s };
|