vitest 2.1.2 → 2.1.3
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/LICENSE.md +320 -30
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +1 -1
- package/dist/chunks/{base.tiemDJX6.js → base.BO5Jx7vw.js} +1 -1
- package/dist/chunks/{cac.B9PaPYY1.js → cac.BSMVokHR.js} +4 -4
- package/dist/chunks/{cli-api.CHxC4-U8.js → cli-api.btGgw3PC.js} +2843 -2778
- package/dist/chunks/{console.DI3gHgtH.js → console.CfT1Wjed.js} +1 -1
- package/dist/chunks/{creator.Cf-MKt9i.js → creator.CBPphXqR.js} +1 -1
- package/dist/chunks/{globals.HsM2o-0O.js → globals.Bdzt04Qm.js} +2 -2
- package/dist/chunks/{index.mAqbj9F9.js → index.-d_XpZEA.js} +1 -1
- package/dist/chunks/{index.Ckn0Cw1h.js → index.4GFF2h22.js} +1 -1
- package/dist/chunks/{index.FcPVJkIQ.js → index.Dz2opmmU.js} +21 -4
- package/dist/chunks/{index.BpojBOif.js → index.X0nbfr6-.js} +3 -3
- package/dist/chunks/{reporters.DAfKSDh5.d.ts → reporters.C4ZHgdxQ.d.ts} +9 -9
- package/dist/chunks/{resolveConfig.D1DENLPF.js → resolveConfig.Dha6ilPI.js} +58 -40
- package/dist/chunks/{runBaseTests.D-Gcin7G.js → runBaseTests.Cx4wXyTR.js} +5 -5
- package/dist/chunks/{setup-common.DF96bIYE.js → setup-common.BKyF15v_.js} +1 -1
- package/dist/chunks/{vi.DUs2eKik.js → vi.BskyZC5g.js} +2 -0
- package/dist/chunks/{vite.8fk186v-.d.ts → vite.YH7MrecS.d.ts} +1 -1
- package/dist/chunks/{vm.CPXwWp4C.js → vm.DB_hLchi.js} +1 -1
- package/dist/chunks/{worker.Chrs-_NL.d.ts → worker.B6RjTtbk.d.ts} +40 -26
- package/dist/chunks/{worker.Qtv8v5nL.d.ts → worker.CcJLfX8w.d.ts} +1 -1
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +16 -11
- package/dist/coverage.d.ts +65 -28
- package/dist/coverage.js +249 -108
- package/dist/execute.d.ts +1 -1
- package/dist/index.d.ts +29 -12
- package/dist/index.js +3 -3
- package/dist/node.d.ts +4 -4
- package/dist/node.js +7 -6
- package/dist/reporters.d.ts +1 -1
- package/dist/reporters.js +1 -1
- package/dist/runners.js +1 -1
- package/dist/workers/forks.js +1 -1
- package/dist/workers/runVmTests.js +4 -4
- package/dist/workers/threads.js +1 -1
- package/dist/workers/vmForks.js +2 -2
- package/dist/workers/vmThreads.js +2 -2
- package/dist/workers.d.ts +2 -2
- package/dist/workers.js +3 -3
- package/package.json +12 -12
package/dist/coverage.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as vite from 'vite';
|
|
2
|
-
import {
|
|
2
|
+
import { A as AfterSuiteRunMeta } from './chunks/environment.CzISCQ7o.js';
|
|
3
|
+
import { R as ResolvedCoverageOptions, V as Vitest, a as ReportContext } from './chunks/reporters.C4ZHgdxQ.js';
|
|
3
4
|
import '@vitest/runner';
|
|
4
5
|
import '@vitest/pretty-format';
|
|
5
6
|
import './chunks/config.Crbj2GAb.js';
|
|
6
7
|
import '@vitest/snapshot';
|
|
7
8
|
import '@vitest/snapshot/environment';
|
|
8
9
|
import 'vite-node';
|
|
9
|
-
import './chunks/environment.CzISCQ7o.js';
|
|
10
10
|
import 'node:stream';
|
|
11
11
|
import 'vite-node/client';
|
|
12
12
|
import '@vitest/snapshot/manager';
|
|
@@ -129,39 +129,76 @@ interface ResolvedThreshold {
|
|
|
129
129
|
name: string;
|
|
130
130
|
thresholds: Partial<Record<Threshold, number | undefined>>;
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Holds info about raw coverage results that are stored on file system:
|
|
134
|
+
*
|
|
135
|
+
* ```json
|
|
136
|
+
* "project-a": {
|
|
137
|
+
* "web": {
|
|
138
|
+
* "tests/math.test.ts": "coverage-1.json",
|
|
139
|
+
* "tests/utils.test.ts": "coverage-2.json",
|
|
140
|
+
* // ^^^^^^^^^^^^^^^ Raw coverage on file system
|
|
141
|
+
* },
|
|
142
|
+
* "ssr": { ... },
|
|
143
|
+
* "browser": { ... },
|
|
144
|
+
* },
|
|
145
|
+
* "project-b": ...
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
type CoverageFiles = Map<NonNullable<AfterSuiteRunMeta['projectName']> | symbol, Record<AfterSuiteRunMeta['transformMode'], {
|
|
149
|
+
[TestFilenames: string]: string;
|
|
150
|
+
}>>;
|
|
151
|
+
declare class BaseCoverageProvider<Options extends ResolvedCoverageOptions<'istanbul' | 'v8'>> {
|
|
152
|
+
ctx: Vitest;
|
|
153
|
+
readonly name: 'v8' | 'istanbul';
|
|
154
|
+
version: string;
|
|
155
|
+
options: Options;
|
|
156
|
+
coverageFiles: CoverageFiles;
|
|
157
|
+
pendingPromises: Promise<void>[];
|
|
158
|
+
coverageFilesDirectory: string;
|
|
159
|
+
_initialize(ctx: Vitest): void;
|
|
160
|
+
createCoverageMap(): CoverageMap;
|
|
161
|
+
generateReports(_: CoverageMap, __: boolean | undefined): Promise<void>;
|
|
162
|
+
parseConfigModule(_: string): Promise<{
|
|
163
|
+
generate: () => {
|
|
164
|
+
code: string;
|
|
165
|
+
};
|
|
166
|
+
}>;
|
|
167
|
+
resolveOptions(): Options;
|
|
168
|
+
clean(clean?: boolean): Promise<void>;
|
|
169
|
+
onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }: AfterSuiteRunMeta): void;
|
|
170
|
+
readCoverageFiles<CoverageType>({ onFileRead, onFinished, onDebug }: {
|
|
171
|
+
/** Callback invoked with a single coverage result */
|
|
172
|
+
onFileRead: (data: CoverageType) => void;
|
|
173
|
+
/** Callback invoked once all results of a project for specific transform mode are read */
|
|
174
|
+
onFinished: (project: Vitest['projects'][number], transformMode: AfterSuiteRunMeta['transformMode']) => Promise<void>;
|
|
175
|
+
onDebug: ((...logs: any[]) => void) & {
|
|
176
|
+
enabled: boolean;
|
|
177
|
+
};
|
|
178
|
+
}): Promise<void>;
|
|
179
|
+
cleanAfterRun(): Promise<void>;
|
|
180
|
+
onTestFailure(): Promise<void>;
|
|
181
|
+
reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise<void>;
|
|
182
|
+
reportThresholds(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise<void>;
|
|
150
183
|
/**
|
|
151
184
|
* Constructs collected coverage and users' threshold options into separate sets
|
|
152
185
|
* where each threshold set holds their own coverage maps. Threshold set is either
|
|
153
186
|
* for specific files defined by glob pattern or global for all other files.
|
|
154
187
|
*/
|
|
155
|
-
resolveThresholds
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}): ResolvedThreshold[];
|
|
188
|
+
private resolveThresholds;
|
|
189
|
+
/**
|
|
190
|
+
* Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
|
|
191
|
+
*/
|
|
192
|
+
private checkThresholds;
|
|
161
193
|
/**
|
|
162
|
-
*
|
|
194
|
+
* Check if current coverage is above configured thresholds and bump the thresholds if needed
|
|
163
195
|
*/
|
|
164
|
-
|
|
196
|
+
updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }: {
|
|
197
|
+
thresholds: ResolvedThreshold[];
|
|
198
|
+
configurationFile: unknown;
|
|
199
|
+
onUpdate: () => void;
|
|
200
|
+
}): Promise<void>;
|
|
201
|
+
mergeReports(coverageMaps: unknown[]): Promise<void>;
|
|
165
202
|
hasTerminalReporter(reporters: ResolvedCoverageOptions['reporter']): boolean;
|
|
166
203
|
toSlices<T>(array: T[], size: number): T[][];
|
|
167
204
|
createUncoveredFileTransformer(ctx: Vitest): (filename: string) => Promise<vite.TransformResult | null | undefined>;
|
package/dist/coverage.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, promises, readdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { resolve, relative } from 'pathe';
|
|
3
|
+
import { c as coverageConfigDefaults, r as resolveCoverageReporters, m as mm } from './chunks/resolveConfig.Dha6ilPI.js';
|
|
4
|
+
import c from 'tinyrainbow';
|
|
3
5
|
import 'node:path';
|
|
4
|
-
import 'node:fs';
|
|
5
6
|
import 'node:fs/promises';
|
|
6
7
|
import 'node:process';
|
|
7
8
|
import 'node:module';
|
|
@@ -9,7 +10,6 @@ import 'node:url';
|
|
|
9
10
|
import 'node:assert';
|
|
10
11
|
import 'node:v8';
|
|
11
12
|
import 'node:util';
|
|
12
|
-
import 'tinyrainbow';
|
|
13
13
|
import './chunks/constants.fzPh7AOq.js';
|
|
14
14
|
import 'node:os';
|
|
15
15
|
import './chunks/env.CmHVDJnw.js';
|
|
@@ -42,98 +42,176 @@ const THRESHOLD_KEYS = [
|
|
|
42
42
|
"branches"
|
|
43
43
|
];
|
|
44
44
|
const GLOBAL_THRESHOLDS_KEY = "global";
|
|
45
|
+
const DEFAULT_PROJECT = Symbol.for("default-project");
|
|
46
|
+
let uniqueId = 0;
|
|
45
47
|
class BaseCoverageProvider {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
48
|
+
ctx;
|
|
49
|
+
name;
|
|
50
|
+
version;
|
|
51
|
+
options;
|
|
52
|
+
coverageFiles = /* @__PURE__ */ new Map();
|
|
53
|
+
pendingPromises = [];
|
|
54
|
+
coverageFilesDirectory;
|
|
55
|
+
_initialize(ctx) {
|
|
56
|
+
this.ctx = ctx;
|
|
57
|
+
if (ctx.version !== this.version) {
|
|
58
|
+
ctx.logger.warn(
|
|
59
|
+
c.yellow(
|
|
60
|
+
`Loaded ${c.inverse(c.yellow(` vitest@${ctx.version} `))} and ${c.inverse(c.yellow(` @vitest/coverage-${this.name}@${this.version} `))}.
|
|
61
|
+
Running mixed versions is not supported and may lead into bugs
|
|
62
|
+
Update your dependencies and make sure the versions match.`
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const config = ctx.config.coverage;
|
|
67
|
+
this.options = {
|
|
68
|
+
...coverageConfigDefaults,
|
|
69
|
+
// User's options
|
|
70
|
+
...config,
|
|
71
|
+
// Resolved fields
|
|
72
|
+
provider: this.name,
|
|
73
|
+
reportsDirectory: resolve(
|
|
74
|
+
ctx.config.root,
|
|
75
|
+
config.reportsDirectory || coverageConfigDefaults.reportsDirectory
|
|
76
|
+
),
|
|
77
|
+
reporter: resolveCoverageReporters(
|
|
78
|
+
config.reporter || coverageConfigDefaults.reporter
|
|
79
|
+
),
|
|
80
|
+
thresholds: config.thresholds && {
|
|
81
|
+
...config.thresholds,
|
|
82
|
+
lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
|
|
83
|
+
branches: config.thresholds["100"] ? 100 : config.thresholds.branches,
|
|
84
|
+
functions: config.thresholds["100"] ? 100 : config.thresholds.functions,
|
|
85
|
+
statements: config.thresholds["100"] ? 100 : config.thresholds.statements
|
|
83
86
|
}
|
|
87
|
+
};
|
|
88
|
+
const shard = this.ctx.config.shard;
|
|
89
|
+
const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
|
|
90
|
+
this.coverageFilesDirectory = resolve(
|
|
91
|
+
this.options.reportsDirectory,
|
|
92
|
+
tempDirectory
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
createCoverageMap() {
|
|
96
|
+
throw new Error("BaseReporter's createCoverageMap was not overwritten");
|
|
97
|
+
}
|
|
98
|
+
async generateReports(_, __) {
|
|
99
|
+
throw new Error("BaseReporter's generateReports was not overwritten");
|
|
100
|
+
}
|
|
101
|
+
async parseConfigModule(_) {
|
|
102
|
+
throw new Error("BaseReporter's parseConfigModule was not overwritten");
|
|
103
|
+
}
|
|
104
|
+
resolveOptions() {
|
|
105
|
+
return this.options;
|
|
106
|
+
}
|
|
107
|
+
async clean(clean = true) {
|
|
108
|
+
if (clean && existsSync(this.options.reportsDirectory)) {
|
|
109
|
+
await promises.rm(this.options.reportsDirectory, {
|
|
110
|
+
recursive: true,
|
|
111
|
+
force: true,
|
|
112
|
+
maxRetries: 10
|
|
113
|
+
});
|
|
84
114
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
115
|
+
if (existsSync(this.coverageFilesDirectory)) {
|
|
116
|
+
await promises.rm(this.coverageFilesDirectory, {
|
|
117
|
+
recursive: true,
|
|
118
|
+
force: true,
|
|
119
|
+
maxRetries: 10
|
|
120
|
+
});
|
|
90
121
|
}
|
|
122
|
+
await promises.mkdir(this.coverageFilesDirectory, { recursive: true });
|
|
123
|
+
this.coverageFiles = /* @__PURE__ */ new Map();
|
|
124
|
+
this.pendingPromises = [];
|
|
91
125
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (perFile && file) {
|
|
127
|
-
errorMessage += ` for ${relative("./", file).replace(
|
|
128
|
-
/\\/g,
|
|
129
|
-
"/"
|
|
130
|
-
)}`;
|
|
131
|
-
}
|
|
132
|
-
onError(errorMessage);
|
|
133
|
-
}
|
|
126
|
+
onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }) {
|
|
127
|
+
if (!coverage) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (transformMode !== "web" && transformMode !== "ssr" && transformMode !== "browser") {
|
|
131
|
+
throw new Error(`Invalid transform mode: ${transformMode}`);
|
|
132
|
+
}
|
|
133
|
+
let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
|
|
134
|
+
if (!entry) {
|
|
135
|
+
entry = { web: {}, ssr: {}, browser: {} };
|
|
136
|
+
this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
|
|
137
|
+
}
|
|
138
|
+
const testFilenames = testFiles.join();
|
|
139
|
+
const filename = resolve(
|
|
140
|
+
this.coverageFilesDirectory,
|
|
141
|
+
`coverage-${uniqueId++}.json`
|
|
142
|
+
);
|
|
143
|
+
entry[transformMode][testFilenames] = filename;
|
|
144
|
+
const promise = promises.writeFile(filename, JSON.stringify(coverage), "utf-8");
|
|
145
|
+
this.pendingPromises.push(promise);
|
|
146
|
+
}
|
|
147
|
+
async readCoverageFiles({ onFileRead, onFinished, onDebug }) {
|
|
148
|
+
let index = 0;
|
|
149
|
+
const total = this.pendingPromises.length;
|
|
150
|
+
await Promise.all(this.pendingPromises);
|
|
151
|
+
this.pendingPromises = [];
|
|
152
|
+
for (const [projectName, coveragePerProject] of this.coverageFiles.entries()) {
|
|
153
|
+
for (const [transformMode, coverageByTestfiles] of Object.entries(coveragePerProject)) {
|
|
154
|
+
const filenames = Object.values(coverageByTestfiles);
|
|
155
|
+
const project = this.ctx.getProjectByName(projectName);
|
|
156
|
+
for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
|
|
157
|
+
if (onDebug.enabled) {
|
|
158
|
+
index += chunk.length;
|
|
159
|
+
onDebug("Covered files %d/%d", index, total);
|
|
134
160
|
}
|
|
161
|
+
await Promise.all(
|
|
162
|
+
chunk.map(async (filename) => {
|
|
163
|
+
const contents = await promises.readFile(filename, "utf-8");
|
|
164
|
+
const coverage = JSON.parse(contents);
|
|
165
|
+
onFileRead(coverage);
|
|
166
|
+
})
|
|
167
|
+
);
|
|
135
168
|
}
|
|
169
|
+
await onFinished(project, transformMode);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async cleanAfterRun() {
|
|
174
|
+
this.coverageFiles = /* @__PURE__ */ new Map();
|
|
175
|
+
await promises.rm(this.coverageFilesDirectory, { recursive: true });
|
|
176
|
+
if (readdirSync(this.options.reportsDirectory).length === 0) {
|
|
177
|
+
await promises.rm(this.options.reportsDirectory, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async onTestFailure() {
|
|
181
|
+
if (!this.options.reportOnFailure) {
|
|
182
|
+
await this.cleanAfterRun();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async reportCoverage(coverageMap, { allTestsRun }) {
|
|
186
|
+
await this.generateReports(
|
|
187
|
+
coverageMap || this.createCoverageMap(),
|
|
188
|
+
allTestsRun
|
|
189
|
+
);
|
|
190
|
+
const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
|
|
191
|
+
if (!keepResults) {
|
|
192
|
+
await this.cleanAfterRun();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async reportThresholds(coverageMap, allTestsRun) {
|
|
196
|
+
const resolvedThresholds = this.resolveThresholds(coverageMap);
|
|
197
|
+
this.checkThresholds(resolvedThresholds);
|
|
198
|
+
if (this.options.thresholds?.autoUpdate && allTestsRun) {
|
|
199
|
+
if (!this.ctx.server.config.configFile) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
|
|
202
|
+
);
|
|
136
203
|
}
|
|
204
|
+
const configFilePath = this.ctx.server.config.configFile;
|
|
205
|
+
const configModule = await this.parseConfigModule(configFilePath);
|
|
206
|
+
await this.updateThresholds({
|
|
207
|
+
thresholds: resolvedThresholds,
|
|
208
|
+
configurationFile: configModule,
|
|
209
|
+
onUpdate: () => writeFileSync(
|
|
210
|
+
configFilePath,
|
|
211
|
+
configModule.generate().code,
|
|
212
|
+
"utf-8"
|
|
213
|
+
)
|
|
214
|
+
});
|
|
137
215
|
}
|
|
138
216
|
}
|
|
139
217
|
/**
|
|
@@ -141,26 +219,19 @@ class BaseCoverageProvider {
|
|
|
141
219
|
* where each threshold set holds their own coverage maps. Threshold set is either
|
|
142
220
|
* for specific files defined by glob pattern or global for all other files.
|
|
143
221
|
*/
|
|
144
|
-
resolveThresholds({
|
|
145
|
-
coverageMap,
|
|
146
|
-
thresholds,
|
|
147
|
-
createCoverageMap,
|
|
148
|
-
root
|
|
149
|
-
}) {
|
|
222
|
+
resolveThresholds(coverageMap) {
|
|
150
223
|
const resolvedThresholds = [];
|
|
151
224
|
const files = coverageMap.files();
|
|
152
|
-
const globalCoverageMap = createCoverageMap();
|
|
153
|
-
for (const key of Object.keys(
|
|
154
|
-
thresholds
|
|
155
|
-
)) {
|
|
225
|
+
const globalCoverageMap = this.createCoverageMap();
|
|
226
|
+
for (const key of Object.keys(this.options.thresholds)) {
|
|
156
227
|
if (key === "perFile" || key === "autoUpdate" || key === "100" || THRESHOLD_KEYS.includes(key)) {
|
|
157
228
|
continue;
|
|
158
229
|
}
|
|
159
230
|
const glob = key;
|
|
160
|
-
const globThresholds = resolveGlobThresholds(thresholds[glob]);
|
|
161
|
-
const globCoverageMap = createCoverageMap();
|
|
231
|
+
const globThresholds = resolveGlobThresholds(this.options.thresholds[glob]);
|
|
232
|
+
const globCoverageMap = this.createCoverageMap();
|
|
162
233
|
const matchingFiles = files.filter(
|
|
163
|
-
(file) => mm.isMatch(relative(root, file), glob)
|
|
234
|
+
(file) => mm.isMatch(relative(this.ctx.config.root, file), glob)
|
|
164
235
|
);
|
|
165
236
|
for (const file of matchingFiles) {
|
|
166
237
|
const fileCoverage = coverageMap.fileCoverageFor(file);
|
|
@@ -180,19 +251,89 @@ class BaseCoverageProvider {
|
|
|
180
251
|
name: GLOBAL_THRESHOLDS_KEY,
|
|
181
252
|
coverageMap: globalCoverageMap,
|
|
182
253
|
thresholds: {
|
|
183
|
-
branches: thresholds
|
|
184
|
-
functions: thresholds
|
|
185
|
-
lines: thresholds
|
|
186
|
-
statements: thresholds
|
|
254
|
+
branches: this.options.thresholds?.branches,
|
|
255
|
+
functions: this.options.thresholds?.functions,
|
|
256
|
+
lines: this.options.thresholds?.lines,
|
|
257
|
+
statements: this.options.thresholds?.statements
|
|
187
258
|
}
|
|
188
259
|
});
|
|
189
260
|
return resolvedThresholds;
|
|
190
261
|
}
|
|
191
262
|
/**
|
|
192
|
-
*
|
|
263
|
+
* Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
|
|
264
|
+
*/
|
|
265
|
+
checkThresholds(allThresholds) {
|
|
266
|
+
for (const { coverageMap, thresholds, name } of allThresholds) {
|
|
267
|
+
if (thresholds.branches === void 0 && thresholds.functions === void 0 && thresholds.lines === void 0 && thresholds.statements === void 0) {
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
const summaries = this.options.thresholds?.perFile ? coverageMap.files().map((file) => ({
|
|
271
|
+
file,
|
|
272
|
+
summary: coverageMap.fileCoverageFor(file).toSummary()
|
|
273
|
+
})) : [{ file: null, summary: coverageMap.getCoverageSummary() }];
|
|
274
|
+
for (const { summary, file } of summaries) {
|
|
275
|
+
for (const thresholdKey of THRESHOLD_KEYS) {
|
|
276
|
+
const threshold = thresholds[thresholdKey];
|
|
277
|
+
if (threshold !== void 0) {
|
|
278
|
+
const coverage = summary.data[thresholdKey].pct;
|
|
279
|
+
if (coverage < threshold) {
|
|
280
|
+
process.exitCode = 1;
|
|
281
|
+
let errorMessage = `ERROR: Coverage for ${thresholdKey} (${coverage}%) does not meet ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${threshold}%)`;
|
|
282
|
+
if (this.options.thresholds?.perFile && file) {
|
|
283
|
+
errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
|
|
284
|
+
}
|
|
285
|
+
this.ctx.logger.error(errorMessage);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Check if current coverage is above configured thresholds and bump the thresholds if needed
|
|
193
294
|
*/
|
|
194
|
-
|
|
195
|
-
|
|
295
|
+
async updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }) {
|
|
296
|
+
let updatedThresholds = false;
|
|
297
|
+
const config = resolveConfig(configurationFile);
|
|
298
|
+
assertConfigurationModule(config);
|
|
299
|
+
for (const { coverageMap, thresholds, name } of allThresholds) {
|
|
300
|
+
const summaries = this.options.thresholds?.perFile ? coverageMap.files().map(
|
|
301
|
+
(file) => coverageMap.fileCoverageFor(file).toSummary()
|
|
302
|
+
) : [coverageMap.getCoverageSummary()];
|
|
303
|
+
const thresholdsToUpdate = [];
|
|
304
|
+
for (const key of THRESHOLD_KEYS) {
|
|
305
|
+
const threshold = thresholds[key] ?? 100;
|
|
306
|
+
const actual = Math.min(
|
|
307
|
+
...summaries.map((summary) => summary[key].pct)
|
|
308
|
+
);
|
|
309
|
+
if (actual > threshold) {
|
|
310
|
+
thresholdsToUpdate.push([key, actual]);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (thresholdsToUpdate.length === 0) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
updatedThresholds = true;
|
|
317
|
+
for (const [threshold, newValue] of thresholdsToUpdate) {
|
|
318
|
+
if (name === GLOBAL_THRESHOLDS_KEY) {
|
|
319
|
+
config.test.coverage.thresholds[threshold] = newValue;
|
|
320
|
+
} else {
|
|
321
|
+
const glob = config.test.coverage.thresholds[name];
|
|
322
|
+
glob[threshold] = newValue;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (updatedThresholds) {
|
|
327
|
+
this.ctx.logger.log("Updating thresholds to configuration file. You may want to push with updated coverage thresholds.");
|
|
328
|
+
onUpdate();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
async mergeReports(coverageMaps) {
|
|
332
|
+
const coverageMap = this.createCoverageMap();
|
|
333
|
+
for (const coverage of coverageMaps) {
|
|
334
|
+
coverageMap.merge(coverage);
|
|
335
|
+
}
|
|
336
|
+
await this.generateReports(coverageMap, true);
|
|
196
337
|
}
|
|
197
338
|
hasTerminalReporter(reporters) {
|
|
198
339
|
return reporters.some(
|
package/dist/execute.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import vm from 'node:vm';
|
|
2
2
|
import { ViteNodeRunner } from 'vite-node/client';
|
|
3
3
|
import { ViteNodeRunnerOptions } from 'vite-node';
|
|
4
|
-
import { R as RuntimeRPC, W as WorkerGlobalState } from './chunks/worker.
|
|
4
|
+
import { R as RuntimeRPC, W as WorkerGlobalState } from './chunks/worker.B6RjTtbk.js';
|
|
5
5
|
import * as _vitest_mocker from '@vitest/mocker';
|
|
6
6
|
import { MockedModuleType } from '@vitest/mocker';
|
|
7
7
|
import { P as PendingSuiteMock, b as MockFactory, a as MockOptions } from './chunks/mocker.cRtM890J.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import './chunks/vite.
|
|
1
|
+
import './chunks/vite.YH7MrecS.js';
|
|
2
2
|
import { Plugin } from '@vitest/pretty-format';
|
|
3
3
|
import { SnapshotState } from '@vitest/snapshot';
|
|
4
4
|
export { SnapshotData, SnapshotMatchOptions, SnapshotResult, SnapshotSerializer, SnapshotStateOptions, SnapshotSummary, SnapshotUpdateState, UncheckedSnapshot } from '@vitest/snapshot';
|
|
5
5
|
import { PromisifyAssertion, Tester, ExpectStatic } from '@vitest/expect';
|
|
6
6
|
export { Assertion, AsymmetricMatchersContaining, ExpectPollOptions, ExpectStatic, JestAssertion } from '@vitest/expect';
|
|
7
|
-
import {
|
|
7
|
+
import { f as VitestEnvironment$1, S as SerializedTestSpecification, g as RawErrsMap$1, T as TscErrorInfo$1, h as CollectLineNumbers$1, i as CollectLines$1, j as RootAndTarget$1, k as Context$1, C as CoverageProvider$1, a as ReportContext$1, b as CoverageProviderModule$1, l as CoverageReporter$1, m as CoverageProviderName, n as CoverageOptions$1, R as ResolvedCoverageOptions$1, B as BaseCoverageOptions$1, o as CoverageIstanbulOptions$1, c as CoverageV8Options$1, p as CustomProviderOptions$1, q as Reporter$1, V as Vitest$1, r as BrowserScript$1, s as BrowserConfigOptions$1, t as BuiltinEnvironment$1, P as Pool$1, u as PoolOptions$1, v as CSSModuleScopeStrategy$1, A as ApiConfig$1, w as VitestRunMode$1, D as DepsOptimizationOptions$1, x as TransformModePatterns$1, I as InlineConfig$1, y as TypecheckConfig$1, z as UserConfig$1, E as ResolvedConfig$1, F as ProjectConfig$1, U as UserWorkspaceConfig$1, G as BenchmarkUserOptions$1 } from './chunks/reporters.C4ZHgdxQ.js';
|
|
8
8
|
import { B as BenchmarkResult } from './chunks/benchmark.JVlTzojj.js';
|
|
9
9
|
export { b as BenchFunction, a as Benchmark, c as BenchmarkAPI } from './chunks/benchmark.JVlTzojj.js';
|
|
10
10
|
import { U as UserConsoleLog, P as ProvidedContext, M as ModuleGraphData, b as Awaitable$1, N as Nullable$1, c as Arrayable$1, d as ArgumentsType$1, e as MutableArray$1, C as Constructable$1, O as OnServerRestartHandler$1, a as EnvironmentReturn$1, V as VmEnvironmentReturn$1, E as Environment$1, R as ResolvedTestEnvironment$1, J as JSDOMOptions$1, H as HappyDOMOptions$1, f as EnvironmentOptions$1 } from './chunks/environment.CzISCQ7o.js';
|
|
11
11
|
export { A as AfterSuiteRunMeta, g as ModuleCache } from './chunks/environment.CzISCQ7o.js';
|
|
12
|
-
import { TaskPopulated, TaskResultPack, File as File$1, Suite as Suite$1, Test as Test$1, Custom as Custom$1, Task as Task$1, SequenceHooks as SequenceHooks$1, SequenceSetupFiles as SequenceSetupFiles$1 } from '@vitest/runner';
|
|
13
|
-
export { CancelReason,
|
|
12
|
+
import { TaskPopulated, TaskResultPack as TaskResultPack$1, File as File$1, Suite as Suite$1, Test as Test$1, Custom as Custom$1, Task as Task$1, TaskBase as TaskBase$1, TaskResult as TaskResult$1, DoneCallback as DoneCallback$1, RuntimeContext as RuntimeContext$1, SuiteHooks as SuiteHooks$1, SequenceHooks as SequenceHooks$1, SequenceSetupFiles as SequenceSetupFiles$1 } from '@vitest/runner';
|
|
13
|
+
export { CancelReason, ExtendedContext, HookCleanupCallback, HookListener, OnTestFailedHandler, OnTestFinishedHandler, RunMode, Custom as RunnerCustomCase, Task as RunnerTask, TaskBase as RunnerTaskBase, TaskResult as RunnerTaskResult, TaskResultPack as RunnerTaskResultPack, Test as RunnerTestCase, File as RunnerTestFile, Suite as RunnerTestSuite, SuiteAPI, SuiteCollector, SuiteFactory, TaskContext, TaskCustomOptions, TaskMeta, TaskState, TestAPI, TestContext, TestFunction, TestOptions, afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from '@vitest/runner';
|
|
14
|
+
import { a as BirpcReturn, b as WorkerRPC$1 } from './chunks/worker.B6RjTtbk.js';
|
|
15
|
+
export { C as ContextRPC, e as ContextTestEnvironment, d as ResolveIdFunction, c as RunnerRPC, R as RuntimeRPC, W as WorkerGlobalState } from './chunks/worker.B6RjTtbk.js';
|
|
16
|
+
import { W as WorkerContext$1 } from './chunks/worker.CcJLfX8w.js';
|
|
14
17
|
export { b as bench } from './chunks/suite.BMWOKiTe.js';
|
|
15
18
|
import { F as FakeTimerInstallOpts, R as RuntimeOptions, S as SerializedConfig } from './chunks/config.Crbj2GAb.js';
|
|
16
19
|
export { b as RuntimeConfig, a as SerializedCoverageConfig } from './chunks/config.Crbj2GAb.js';
|
|
17
20
|
import { M as MockFactoryWithHelper, a as MockOptions } from './chunks/mocker.cRtM890J.js';
|
|
18
21
|
import { spyOn, fn, MaybeMockedDeep, MaybeMocked, MaybePartiallyMocked, MaybePartiallyMockedDeep, MockInstance } from '@vitest/spy';
|
|
19
22
|
export { Mock, MockContext, MockInstance, Mocked, MockedClass, MockedFunction, MockedObject } from '@vitest/spy';
|
|
20
|
-
import { a as BirpcReturn } from './chunks/worker.Chrs-_NL.js';
|
|
21
|
-
export { C as ContextRPC, e as ContextTestEnvironment, c as ResolveIdFunction, b as RunnerRPC, R as RuntimeRPC, W as WorkerGlobalState, d as WorkerRPC } from './chunks/worker.Chrs-_NL.js';
|
|
22
|
-
export { W as WorkerContext } from './chunks/worker.Qtv8v5nL.js';
|
|
23
23
|
export { ErrorWithDiff, ParsedStack, SerializedError, TestError } from '@vitest/utils';
|
|
24
24
|
export { DiffOptions } from '@vitest/utils/diff';
|
|
25
25
|
import * as chai from 'chai';
|
|
@@ -35,9 +35,9 @@ import 'vite-node/server';
|
|
|
35
35
|
import '@vitest/utils/source-map';
|
|
36
36
|
import 'node:fs';
|
|
37
37
|
import '@vitest/runner/utils';
|
|
38
|
+
import 'node:worker_threads';
|
|
38
39
|
import '@vitest/snapshot/environment';
|
|
39
40
|
import '@vitest/mocker';
|
|
40
|
-
import 'node:worker_threads';
|
|
41
41
|
|
|
42
42
|
declare global {
|
|
43
43
|
namespace Chai {
|
|
@@ -1508,7 +1508,7 @@ interface VitestUtils {
|
|
|
1508
1508
|
declare const vitest: VitestUtils;
|
|
1509
1509
|
declare const vi: VitestUtils;
|
|
1510
1510
|
|
|
1511
|
-
declare function getRunningMode(): "
|
|
1511
|
+
declare function getRunningMode(): "watch" | "run";
|
|
1512
1512
|
declare function isWatchMode(): boolean;
|
|
1513
1513
|
|
|
1514
1514
|
/**
|
|
@@ -1543,7 +1543,7 @@ interface TransformResultWithSource {
|
|
|
1543
1543
|
source?: string;
|
|
1544
1544
|
}
|
|
1545
1545
|
interface WebSocketHandlers {
|
|
1546
|
-
onTaskUpdate: (packs: TaskResultPack[]) => void;
|
|
1546
|
+
onTaskUpdate: (packs: TaskResultPack$1[]) => void;
|
|
1547
1547
|
getFiles: () => File$1[];
|
|
1548
1548
|
getTestFiles: () => Promise<SerializedTestSpecification[]>;
|
|
1549
1549
|
getPaths: () => string[];
|
|
@@ -1559,7 +1559,7 @@ interface WebSocketHandlers {
|
|
|
1559
1559
|
interface WebSocketEvents {
|
|
1560
1560
|
onCollected?: (files?: File$1[]) => Awaitable$1<void>;
|
|
1561
1561
|
onFinished?: (files: File$1[], errors: unknown[], coverage?: unknown) => Awaitable$1<void>;
|
|
1562
|
-
onTaskUpdate?: (packs: TaskResultPack[]) => Awaitable$1<void>;
|
|
1562
|
+
onTaskUpdate?: (packs: TaskResultPack$1[]) => Awaitable$1<void>;
|
|
1563
1563
|
onUserConsoleLog?: (log: UserConsoleLog) => Awaitable$1<void>;
|
|
1564
1564
|
onPathsCollected?: (paths?: string[]) => Awaitable$1<void>;
|
|
1565
1565
|
onSpecsCollected?: (specs?: SerializedTestSpecification[]) => Awaitable$1<void>;
|
|
@@ -1589,6 +1589,23 @@ type Test = Test$1;
|
|
|
1589
1589
|
type Custom = Custom$1;
|
|
1590
1590
|
/** @deprecated use `RunnerTask` instead */
|
|
1591
1591
|
type Task = Task$1;
|
|
1592
|
+
/** @deprecated use `RunnerTaskBase` instead */
|
|
1593
|
+
type TaskBase = TaskBase$1;
|
|
1594
|
+
/** @deprecated use `RunnerTaskResult` instead */
|
|
1595
|
+
type TaskResult = TaskResult$1;
|
|
1596
|
+
/** @deprecated use `RunnerTaskResultPack` instead */
|
|
1597
|
+
type TaskResultPack = TaskResultPack$1;
|
|
1598
|
+
/** @deprecated don't use `DoneCallback` since it's not supported */
|
|
1599
|
+
type DoneCallback = DoneCallback$1;
|
|
1600
|
+
/** @deprecated internal type, don't use it */
|
|
1601
|
+
type RuntimeContext = RuntimeContext$1;
|
|
1602
|
+
/** @deprecated internal type, don't use it */
|
|
1603
|
+
type SuiteHooks = SuiteHooks$1;
|
|
1604
|
+
|
|
1605
|
+
/** @deprecated import from `vitest/node` instead */
|
|
1606
|
+
type WorkerContext = WorkerContext$1;
|
|
1607
|
+
/** @deprecated import from `vitest/node` instead */
|
|
1608
|
+
type WorkerRPC = WorkerRPC$1;
|
|
1592
1609
|
|
|
1593
1610
|
/** @deprecated do not use, internal helper */
|
|
1594
1611
|
type Awaitable<T> = Awaitable$1<T>;
|
|
@@ -1690,4 +1707,4 @@ type SerializableSpec = SerializedTestSpecification;
|
|
|
1690
1707
|
/** @deprecated import from `vitest/node` instead */
|
|
1691
1708
|
type BenchmarkUserOptions = BenchmarkUserOptions$1;
|
|
1692
1709
|
|
|
1693
|
-
export { type ApiConfig, type ArgumentsType, type Arrayable, type AssertType, type Awaitable, type BaseCoverageOptions, BenchmarkResult, type BenchmarkUserOptions, type BrowserConfigOptions, type BrowserScript, type BrowserUI, type BuiltinEnvironment, type CSSModuleScopeStrategy, type CollectLineNumbers, type CollectLines, type Constructable, type Context, type CoverageIstanbulOptions, type CoverageOptions, type CoverageProvider, type CoverageProviderModule, type CoverageReporter, type CoverageV8Options, type Custom, type CustomProviderOptions, type DepsOptimizationOptions, type Environment, type EnvironmentOptions, type EnvironmentReturn, type ExpectTypeOf, type File, type HappyDOMOptions, type InlineConfig, type JSDOMOptions, ModuleGraphData, type MutableArray, type Nullable, type OnServerRestartHandler, type Pool, type PoolOptions, type ProjectConfig, ProvidedContext, type RawErrsMap, type ReportContext, type Reporter, type ResolvedConfig, type ResolvedCoverageOptions, type ResolvedTestEnvironment, type RootAndTarget, type SequenceHooks, type SequenceSetupFiles, type SerializableSpec, SerializedConfig, SerializedTestSpecification, type Suite, type Task, type Test, type TransformModePatterns, type TransformResultWithSource, type TscErrorInfo, type TypecheckConfig, type UserConfig, UserConsoleLog, type UserWorkspaceConfig, type Vitest, type VitestEnvironment, type VitestRunMode, type VitestUtils, type VmEnvironmentReturn, type WebSocketEvents, type WebSocketHandlers, type WebSocketRPC, assertType, createExpect, globalExpect as expect, expectTypeOf, getRunningMode, inject, isFirstRun, isWatchMode, runOnce, vi, vitest };
|
|
1710
|
+
export { type ApiConfig, type ArgumentsType, type Arrayable, type AssertType, type Awaitable, type BaseCoverageOptions, BenchmarkResult, type BenchmarkUserOptions, type BrowserConfigOptions, type BrowserScript, type BrowserUI, type BuiltinEnvironment, type CSSModuleScopeStrategy, type CollectLineNumbers, type CollectLines, type Constructable, type Context, type CoverageIstanbulOptions, type CoverageOptions, type CoverageProvider, type CoverageProviderModule, type CoverageReporter, type CoverageV8Options, type Custom, type CustomProviderOptions, type DepsOptimizationOptions, type DoneCallback, type Environment, type EnvironmentOptions, type EnvironmentReturn, type ExpectTypeOf, type File, type HappyDOMOptions, type InlineConfig, type JSDOMOptions, ModuleGraphData, type MutableArray, type Nullable, type OnServerRestartHandler, type Pool, type PoolOptions, type ProjectConfig, ProvidedContext, type RawErrsMap, type ReportContext, type Reporter, type ResolvedConfig, type ResolvedCoverageOptions, type ResolvedTestEnvironment, type RootAndTarget, type RuntimeContext, type SequenceHooks, type SequenceSetupFiles, type SerializableSpec, SerializedConfig, SerializedTestSpecification, type Suite, type SuiteHooks, type Task, type TaskBase, type TaskResult, type TaskResultPack, type Test, type TransformModePatterns, type TransformResultWithSource, type TscErrorInfo, type TypecheckConfig, type UserConfig, UserConsoleLog, type UserWorkspaceConfig, type Vitest, type VitestEnvironment, type VitestRunMode, type VitestUtils, type VmEnvironmentReturn, type WebSocketEvents, type WebSocketHandlers, type WebSocketRPC, type WorkerContext, type WorkerRPC, assertType, createExpect, globalExpect as expect, expectTypeOf, getRunningMode, inject, isFirstRun, isWatchMode, runOnce, vi, vitest };
|