vitest 3.0.7 → 3.0.9

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.
Files changed (66) hide show
  1. package/dist/browser.d.ts +14 -43
  2. package/dist/browser.js +4 -4
  3. package/dist/chunks/{base.BgUWWWYp.js → base.DV59CbtV.js} +2 -2
  4. package/dist/chunks/{benchmark.Cdu9hjj4.js → benchmark.DL72EVN-.js} +1 -1
  5. package/dist/chunks/{benchmark.CFFwLv-O.d.ts → benchmark.d.BwvBVTda.d.ts} +11 -11
  6. package/dist/chunks/{cac.87F_onld.js → cac.CeVHgzve.js} +30 -6
  7. package/dist/chunks/{cli-api.BZbq1zTX.js → cli-api.Ckwz_xSb.js} +21 -23
  8. package/dist/chunks/config.d.DevWltVl.d.ts +218 -0
  9. package/dist/chunks/{constants.fzPh7AOq.js → constants.DTYd6dNH.js} +1 -1
  10. package/dist/chunks/{coverage.DnNIv-kJ.js → coverage.A3sS5-Wm.js} +1 -29
  11. package/dist/chunks/coverage.d.S9RMNXIe.d.ts +35 -0
  12. package/dist/chunks/{resolveConfig.BbcK25zb.js → coverage.gV8doR2Y.js} +500 -131
  13. package/dist/chunks/{creator.2CFRE1Yx.js → creator.BsBnpTzI.js} +1 -1
  14. package/dist/chunks/defaults.C2Ndd9wx.js +119 -0
  15. package/dist/chunks/env.D4Lgay0q.js +8 -0
  16. package/dist/chunks/environment.d.C8UItCbf.d.ts +170 -0
  17. package/dist/chunks/{execute.Bhwls1-Z.js → execute.eDH0aFFd.js} +4 -4
  18. package/dist/chunks/global.d.Cg2sEPIm.d.ts +127 -0
  19. package/dist/chunks/{globals.BCtI_nQG.js → globals.BEpDe-k3.js} +5 -5
  20. package/dist/chunks/{index.C1f-_gvH.js → index.B8tIoLPT.js} +8 -3
  21. package/dist/chunks/{index.B8haHJlQ.js → index.D7Ny8f_s.js} +2 -2
  22. package/dist/chunks/{index.BmFFzXX_.js → index.uXkkC4xl.js} +1 -2
  23. package/dist/chunks/{mocker.cRtM890J.d.ts → mocker.d.BE_2ls6u.d.ts} +6 -6
  24. package/dist/chunks/reporters.d.CqBhtcTq.d.ts +3006 -0
  25. package/dist/chunks/{runBaseTests.9XCQcSZC.js → runBaseTests.BVrL_ow3.js} +9 -9
  26. package/dist/chunks/{setup-common.wObu9a36.js → setup-common.CPvtqi8q.js} +25 -2
  27. package/dist/chunks/{suite.qtkXWc6R.d.ts → suite.d.FvehnV49.d.ts} +1 -1
  28. package/dist/chunks/{typechecker.cZ0LjdSi.js → typechecker.BlF3eHsb.js} +2 -7
  29. package/dist/chunks/{vi.DT3m61kS.js → vi.nSCvwQ7l.js} +4 -4
  30. package/dist/chunks/vite.d.BUZTGxQ3.d.ts +11 -0
  31. package/dist/chunks/{vm.6kNys9FN.js → vm.jEFQDlX_.js} +1 -1
  32. package/dist/chunks/{worker.DaAIyCKm.d.ts → worker.d.C58isfFm.d.ts} +62 -62
  33. package/dist/chunks/{worker.B2JXutr8.d.ts → worker.d.CSFlSYJg.d.ts} +2 -2
  34. package/dist/cli.js +2 -2
  35. package/dist/config.d.ts +48 -45
  36. package/dist/config.js +6 -123
  37. package/dist/coverage.d.ts +82 -79
  38. package/dist/coverage.js +19 -469
  39. package/dist/environments.d.ts +11 -11
  40. package/dist/execute.d.ts +109 -109
  41. package/dist/execute.js +1 -1
  42. package/dist/index.d.ts +414 -412
  43. package/dist/index.js +4 -4
  44. package/dist/node.d.ts +51 -48
  45. package/dist/node.js +13 -10
  46. package/dist/reporters.d.ts +7 -4
  47. package/dist/reporters.js +3 -2
  48. package/dist/runners.d.ts +28 -28
  49. package/dist/runners.js +3 -4
  50. package/dist/snapshot.d.ts +2 -2
  51. package/dist/suite.d.ts +2 -2
  52. package/dist/suite.js +1 -1
  53. package/dist/workers/forks.js +2 -2
  54. package/dist/workers/runVmTests.js +9 -9
  55. package/dist/workers/threads.js +2 -2
  56. package/dist/workers/vmForks.js +2 -2
  57. package/dist/workers/vmThreads.js +2 -2
  58. package/dist/workers.d.ts +13 -13
  59. package/dist/workers.js +3 -3
  60. package/package.json +12 -12
  61. package/dist/chunks/config.BRtC-JeT.d.ts +0 -215
  62. package/dist/chunks/environment.d8YfPkTm.d.ts +0 -173
  63. package/dist/chunks/global.CnI8_G5V.d.ts +0 -133
  64. package/dist/chunks/reporters.QZ837uWx.d.ts +0 -3051
  65. package/dist/chunks/spy.Cf_4R5Oe.js +0 -22
  66. package/dist/chunks/vite.vM3UZq1q.d.ts +0 -11
@@ -1,102 +1,105 @@
1
- import { R as ResolvedCoverageOptions, V as Vitest, C as CoverageMap, a as ReportContext } from './chunks/reporters.QZ837uWx.js';
1
+ import { R as ResolvedCoverageOptions, V as Vitest, C as CoverageMap, a as ReportContext } from './chunks/reporters.d.CqBhtcTq.js';
2
2
  import { TransformResult } from 'vite';
3
- import { A as AfterSuiteRunMeta } from './chunks/environment.d8YfPkTm.js';
3
+ import { A as AfterSuiteRunMeta } from './chunks/environment.d.C8UItCbf.js';
4
4
  import '@vitest/runner';
5
5
  import '@vitest/utils';
6
6
  import 'node:stream';
7
+ import 'node:console';
7
8
  import '@vitest/utils/source-map';
8
- import './chunks/config.BRtC-JeT.js';
9
+ import './chunks/config.d.DevWltVl.js';
9
10
  import '@vitest/pretty-format';
10
11
  import '@vitest/snapshot';
11
12
  import '@vitest/snapshot/environment';
12
13
  import '@vitest/utils/diff';
13
14
  import 'vite-node';
14
15
  import 'chai';
15
- import './chunks/benchmark.CFFwLv-O.js';
16
+ import './chunks/benchmark.d.BwvBVTda.js';
16
17
  import '@vitest/runner/utils';
17
18
  import 'tinybench';
19
+ import './chunks/coverage.d.S9RMNXIe.js';
20
+ import 'vite-node/client';
18
21
  import '@vitest/snapshot/manager';
19
22
  import 'node:fs';
20
23
 
21
- type Threshold = 'lines' | 'functions' | 'statements' | 'branches';
24
+ type Threshold = "lines" | "functions" | "statements" | "branches";
22
25
  interface ResolvedThreshold {
23
- coverageMap: CoverageMap;
24
- name: string;
25
- thresholds: Partial<Record<Threshold, number | undefined>>;
26
+ coverageMap: CoverageMap;
27
+ name: string;
28
+ thresholds: Partial<Record<Threshold, number | undefined>>;
26
29
  }
27
30
  /**
28
- * Holds info about raw coverage results that are stored on file system:
29
- *
30
- * ```json
31
- * "project-a": {
32
- * "web": {
33
- * "tests/math.test.ts": "coverage-1.json",
34
- * "tests/utils.test.ts": "coverage-2.json",
35
- * // ^^^^^^^^^^^^^^^ Raw coverage on file system
36
- * },
37
- * "ssr": { ... },
38
- * "browser": { ... },
39
- * },
40
- * "project-b": ...
41
- * ```
42
- */
43
- type CoverageFiles = Map<NonNullable<AfterSuiteRunMeta['projectName']> | symbol, Record<AfterSuiteRunMeta['transformMode'], {
44
- [TestFilenames: string]: string;
31
+ * Holds info about raw coverage results that are stored on file system:
32
+ *
33
+ * ```json
34
+ * "project-a": {
35
+ * "web": {
36
+ * "tests/math.test.ts": "coverage-1.json",
37
+ * "tests/utils.test.ts": "coverage-2.json",
38
+ * // ^^^^^^^^^^^^^^^ Raw coverage on file system
39
+ * },
40
+ * "ssr": { ... },
41
+ * "browser": { ... },
42
+ * },
43
+ * "project-b": ...
44
+ * ```
45
+ */
46
+ type CoverageFiles = Map<NonNullable<AfterSuiteRunMeta["projectName"]> | symbol, Record<AfterSuiteRunMeta["transformMode"], {
47
+ [TestFilenames: string]: string
45
48
  }>>;
46
- declare class BaseCoverageProvider<Options extends ResolvedCoverageOptions<'istanbul' | 'v8'>> {
47
- ctx: Vitest;
48
- readonly name: 'v8' | 'istanbul';
49
- version: string;
50
- options: Options;
51
- coverageFiles: CoverageFiles;
52
- pendingPromises: Promise<void>[];
53
- coverageFilesDirectory: string;
54
- _initialize(ctx: Vitest): void;
55
- createCoverageMap(): CoverageMap;
56
- generateReports(_: CoverageMap, __: boolean | undefined): Promise<void>;
57
- parseConfigModule(_: string): Promise<{
58
- generate: () => {
59
- code: string;
60
- };
61
- }>;
62
- resolveOptions(): Options;
63
- clean(clean?: boolean): Promise<void>;
64
- onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }: AfterSuiteRunMeta): void;
65
- readCoverageFiles<CoverageType>({ onFileRead, onFinished, onDebug }: {
66
- /** Callback invoked with a single coverage result */
67
- onFileRead: (data: CoverageType) => void;
68
- /** Callback invoked once all results of a project for specific transform mode are read */
69
- onFinished: (project: Vitest['projects'][number], transformMode: AfterSuiteRunMeta['transformMode']) => Promise<void>;
70
- onDebug: ((...logs: any[]) => void) & {
71
- enabled: boolean;
72
- };
73
- }): Promise<void>;
74
- cleanAfterRun(): Promise<void>;
75
- onTestFailure(): Promise<void>;
76
- reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise<void>;
77
- reportThresholds(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise<void>;
78
- /**
79
- * Constructs collected coverage and users' threshold options into separate sets
80
- * where each threshold set holds their own coverage maps. Threshold set is either
81
- * for specific files defined by glob pattern or global for all other files.
82
- */
83
- private resolveThresholds;
84
- /**
85
- * Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
86
- */
87
- private checkThresholds;
88
- /**
89
- * Check if current coverage is above configured thresholds and bump the thresholds if needed
90
- */
91
- updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }: {
92
- thresholds: ResolvedThreshold[];
93
- configurationFile: unknown;
94
- onUpdate: () => void;
95
- }): Promise<void>;
96
- mergeReports(coverageMaps: unknown[]): Promise<void>;
97
- hasTerminalReporter(reporters: ResolvedCoverageOptions['reporter']): boolean;
98
- toSlices<T>(array: T[], size: number): T[][];
99
- createUncoveredFileTransformer(ctx: Vitest): (filename: string) => Promise<TransformResult | null | undefined>;
49
+ declare class BaseCoverageProvider<Options extends ResolvedCoverageOptions<"istanbul" | "v8">> {
50
+ ctx: Vitest;
51
+ readonly name: "v8" | "istanbul";
52
+ version: string;
53
+ options: Options;
54
+ coverageFiles: CoverageFiles;
55
+ pendingPromises: Promise<void>[];
56
+ coverageFilesDirectory: string;
57
+ _initialize(ctx: Vitest): void;
58
+ createCoverageMap(): CoverageMap;
59
+ generateReports(_: CoverageMap, __: boolean | undefined): Promise<void>;
60
+ parseConfigModule(_: string): Promise<{
61
+ generate: () => {
62
+ code: string
63
+ }
64
+ }>;
65
+ resolveOptions(): Options;
66
+ clean(clean?: boolean): Promise<void>;
67
+ onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }: AfterSuiteRunMeta): void;
68
+ readCoverageFiles<CoverageType>({ onFileRead, onFinished, onDebug }: {
69
+ /** Callback invoked with a single coverage result */
70
+ onFileRead: (data: CoverageType) => void
71
+ /** Callback invoked once all results of a project for specific transform mode are read */
72
+ onFinished: (project: Vitest["projects"][number], transformMode: AfterSuiteRunMeta["transformMode"]) => Promise<void>
73
+ onDebug: ((...logs: any[]) => void) & {
74
+ enabled: boolean
75
+ }
76
+ }): Promise<void>;
77
+ cleanAfterRun(): Promise<void>;
78
+ onTestFailure(): Promise<void>;
79
+ reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise<void>;
80
+ reportThresholds(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise<void>;
81
+ /**
82
+ * Constructs collected coverage and users' threshold options into separate sets
83
+ * where each threshold set holds their own coverage maps. Threshold set is either
84
+ * for specific files defined by glob pattern or global for all other files.
85
+ */
86
+ private resolveThresholds;
87
+ /**
88
+ * Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
89
+ */
90
+ private checkThresholds;
91
+ /**
92
+ * Check if current coverage is above configured thresholds and bump the thresholds if needed
93
+ */
94
+ updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }: {
95
+ thresholds: ResolvedThreshold[]
96
+ configurationFile: unknown
97
+ onUpdate: () => void
98
+ }): Promise<void>;
99
+ mergeReports(coverageMaps: unknown[]): Promise<void>;
100
+ hasTerminalReporter(reporters: ResolvedCoverageOptions["reporter"]): boolean;
101
+ toSlices<T>(array: T[], size: number): T[][];
102
+ createUncoveredFileTransformer(ctx: Vitest): (filename: string) => Promise<TransformResult | null | undefined>;
100
103
  }
101
104
 
102
105
  export { BaseCoverageProvider };
package/dist/coverage.js CHANGED
@@ -1,7 +1,14 @@
1
- import { existsSync, promises, readdirSync, writeFileSync } from 'node:fs';
2
- import { r as resolveCoverageReporters, c as coverageConfigDefaults, m as mm } from './chunks/resolveConfig.BbcK25zb.js';
3
- import { resolve, relative } from 'pathe';
4
- import c from 'tinyrainbow';
1
+ export { B as BaseCoverageProvider } from './chunks/coverage.gV8doR2Y.js';
2
+ import 'node:fs';
3
+ import './chunks/_commonjsHelpers.BFTU3MAI.js';
4
+ import 'util';
5
+ import 'path';
6
+ import 'pathe';
7
+ import 'tinyrainbow';
8
+ import './chunks/defaults.C2Ndd9wx.js';
9
+ import 'node:os';
10
+ import './chunks/env.D4Lgay0q.js';
11
+ import 'std-env';
5
12
  import 'node:crypto';
6
13
  import '@vitest/utils';
7
14
  import 'node:fs/promises';
@@ -12,476 +19,19 @@ import 'node:url';
12
19
  import 'node:assert';
13
20
  import 'node:v8';
14
21
  import 'node:util';
15
- import './chunks/constants.fzPh7AOq.js';
16
- import 'node:os';
17
- import './chunks/typechecker.cZ0LjdSi.js';
18
- import 'std-env';
22
+ import './chunks/constants.DTYd6dNH.js';
23
+ import 'node:tty';
24
+ import 'vite';
25
+ import 'node:events';
26
+ import './chunks/index.68735LiX.js';
27
+ import 'tinypool';
28
+ import './chunks/typechecker.BlF3eHsb.js';
19
29
  import 'node:perf_hooks';
20
30
  import '@vitest/utils/source-map';
21
31
  import 'tinyexec';
22
32
  import '@vitest/runner/utils';
23
- import 'vite';
24
33
  import 'fs';
25
- import 'node:tty';
26
- import './chunks/_commonjsHelpers.BFTU3MAI.js';
27
- import 'util';
28
- import 'path';
29
- import 'node:events';
30
- import './chunks/index.68735LiX.js';
31
- import 'tinypool';
32
34
  import 'node:worker_threads';
33
35
  import './path.js';
34
36
  import 'vite-node/utils';
35
-
36
- const THRESHOLD_KEYS = [
37
- "lines",
38
- "functions",
39
- "statements",
40
- "branches"
41
- ];
42
- const GLOBAL_THRESHOLDS_KEY = "global";
43
- const DEFAULT_PROJECT = Symbol.for("default-project");
44
- let uniqueId = 0;
45
- class BaseCoverageProvider {
46
- ctx;
47
- name;
48
- version;
49
- options;
50
- coverageFiles = /* @__PURE__ */ new Map();
51
- pendingPromises = [];
52
- coverageFilesDirectory;
53
- _initialize(ctx) {
54
- this.ctx = ctx;
55
- if (ctx.version !== this.version) {
56
- ctx.logger.warn(
57
- c.yellow(
58
- `Loaded ${c.inverse(c.yellow(` vitest@${ctx.version} `))} and ${c.inverse(c.yellow(` @vitest/coverage-${this.name}@${this.version} `))}.
59
- Running mixed versions is not supported and may lead into bugs
60
- Update your dependencies and make sure the versions match.`
61
- )
62
- );
63
- }
64
- const config = ctx.config.coverage;
65
- this.options = {
66
- ...coverageConfigDefaults,
67
- // User's options
68
- ...config,
69
- // Resolved fields
70
- provider: this.name,
71
- reportsDirectory: resolve(
72
- ctx.config.root,
73
- config.reportsDirectory || coverageConfigDefaults.reportsDirectory
74
- ),
75
- reporter: resolveCoverageReporters(
76
- config.reporter || coverageConfigDefaults.reporter
77
- ),
78
- thresholds: config.thresholds && {
79
- ...config.thresholds,
80
- lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
81
- branches: config.thresholds["100"] ? 100 : config.thresholds.branches,
82
- functions: config.thresholds["100"] ? 100 : config.thresholds.functions,
83
- statements: config.thresholds["100"] ? 100 : config.thresholds.statements
84
- }
85
- };
86
- const shard = this.ctx.config.shard;
87
- const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
88
- this.coverageFilesDirectory = resolve(
89
- this.options.reportsDirectory,
90
- tempDirectory
91
- );
92
- }
93
- createCoverageMap() {
94
- throw new Error("BaseReporter's createCoverageMap was not overwritten");
95
- }
96
- async generateReports(_, __) {
97
- throw new Error("BaseReporter's generateReports was not overwritten");
98
- }
99
- async parseConfigModule(_) {
100
- throw new Error("BaseReporter's parseConfigModule was not overwritten");
101
- }
102
- resolveOptions() {
103
- return this.options;
104
- }
105
- async clean(clean = true) {
106
- if (clean && existsSync(this.options.reportsDirectory)) {
107
- await promises.rm(this.options.reportsDirectory, {
108
- recursive: true,
109
- force: true,
110
- maxRetries: 10
111
- });
112
- }
113
- if (existsSync(this.coverageFilesDirectory)) {
114
- await promises.rm(this.coverageFilesDirectory, {
115
- recursive: true,
116
- force: true,
117
- maxRetries: 10
118
- });
119
- }
120
- await promises.mkdir(this.coverageFilesDirectory, { recursive: true });
121
- this.coverageFiles = /* @__PURE__ */ new Map();
122
- this.pendingPromises = [];
123
- }
124
- onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }) {
125
- if (!coverage) {
126
- return;
127
- }
128
- if (transformMode !== "web" && transformMode !== "ssr" && transformMode !== "browser") {
129
- throw new Error(`Invalid transform mode: ${transformMode}`);
130
- }
131
- let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
132
- if (!entry) {
133
- entry = { web: {}, ssr: {}, browser: {} };
134
- this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
135
- }
136
- const testFilenames = testFiles.join();
137
- const filename = resolve(
138
- this.coverageFilesDirectory,
139
- `coverage-${uniqueId++}.json`
140
- );
141
- entry[transformMode][testFilenames] = filename;
142
- const promise = promises.writeFile(filename, JSON.stringify(coverage), "utf-8");
143
- this.pendingPromises.push(promise);
144
- }
145
- async readCoverageFiles({ onFileRead, onFinished, onDebug }) {
146
- let index = 0;
147
- const total = this.pendingPromises.length;
148
- await Promise.all(this.pendingPromises);
149
- this.pendingPromises = [];
150
- for (const [projectName, coveragePerProject] of this.coverageFiles.entries()) {
151
- for (const [transformMode, coverageByTestfiles] of Object.entries(coveragePerProject)) {
152
- const filenames = Object.values(coverageByTestfiles);
153
- const project = this.ctx.getProjectByName(projectName);
154
- for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
155
- if (onDebug.enabled) {
156
- index += chunk.length;
157
- onDebug("Covered files %d/%d", index, total);
158
- }
159
- await Promise.all(
160
- chunk.map(async (filename) => {
161
- const contents = await promises.readFile(filename, "utf-8");
162
- const coverage = JSON.parse(contents);
163
- onFileRead(coverage);
164
- })
165
- );
166
- }
167
- await onFinished(project, transformMode);
168
- }
169
- }
170
- }
171
- async cleanAfterRun() {
172
- this.coverageFiles = /* @__PURE__ */ new Map();
173
- await promises.rm(this.coverageFilesDirectory, { recursive: true });
174
- if (readdirSync(this.options.reportsDirectory).length === 0) {
175
- await promises.rm(this.options.reportsDirectory, { recursive: true });
176
- }
177
- }
178
- async onTestFailure() {
179
- if (!this.options.reportOnFailure) {
180
- await this.cleanAfterRun();
181
- }
182
- }
183
- async reportCoverage(coverageMap, { allTestsRun }) {
184
- await this.generateReports(
185
- coverageMap || this.createCoverageMap(),
186
- allTestsRun
187
- );
188
- const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
189
- if (!keepResults) {
190
- await this.cleanAfterRun();
191
- }
192
- }
193
- async reportThresholds(coverageMap, allTestsRun) {
194
- const resolvedThresholds = this.resolveThresholds(coverageMap);
195
- this.checkThresholds(resolvedThresholds);
196
- if (this.options.thresholds?.autoUpdate && allTestsRun) {
197
- if (!this.ctx.server.config.configFile) {
198
- throw new Error(
199
- 'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
200
- );
201
- }
202
- const configFilePath = this.ctx.server.config.configFile;
203
- const configModule = await this.parseConfigModule(configFilePath);
204
- await this.updateThresholds({
205
- thresholds: resolvedThresholds,
206
- configurationFile: configModule,
207
- onUpdate: () => writeFileSync(
208
- configFilePath,
209
- configModule.generate().code,
210
- "utf-8"
211
- )
212
- });
213
- }
214
- }
215
- /**
216
- * Constructs collected coverage and users' threshold options into separate sets
217
- * where each threshold set holds their own coverage maps. Threshold set is either
218
- * for specific files defined by glob pattern or global for all other files.
219
- */
220
- resolveThresholds(coverageMap) {
221
- const resolvedThresholds = [];
222
- const files = coverageMap.files();
223
- const globalCoverageMap = this.createCoverageMap();
224
- for (const key of Object.keys(this.options.thresholds)) {
225
- if (key === "perFile" || key === "autoUpdate" || key === "100" || THRESHOLD_KEYS.includes(key)) {
226
- continue;
227
- }
228
- const glob = key;
229
- const globThresholds = resolveGlobThresholds(this.options.thresholds[glob]);
230
- const globCoverageMap = this.createCoverageMap();
231
- const matchingFiles = files.filter(
232
- (file) => mm.isMatch(relative(this.ctx.config.root, file), glob)
233
- );
234
- for (const file of matchingFiles) {
235
- const fileCoverage = coverageMap.fileCoverageFor(file);
236
- globCoverageMap.addFileCoverage(fileCoverage);
237
- }
238
- resolvedThresholds.push({
239
- name: glob,
240
- coverageMap: globCoverageMap,
241
- thresholds: globThresholds
242
- });
243
- }
244
- for (const file of files) {
245
- const fileCoverage = coverageMap.fileCoverageFor(file);
246
- globalCoverageMap.addFileCoverage(fileCoverage);
247
- }
248
- resolvedThresholds.unshift({
249
- name: GLOBAL_THRESHOLDS_KEY,
250
- coverageMap: globalCoverageMap,
251
- thresholds: {
252
- branches: this.options.thresholds?.branches,
253
- functions: this.options.thresholds?.functions,
254
- lines: this.options.thresholds?.lines,
255
- statements: this.options.thresholds?.statements
256
- }
257
- });
258
- return resolvedThresholds;
259
- }
260
- /**
261
- * Check collected coverage against configured thresholds. Sets exit code to 1 when thresholds not reached.
262
- */
263
- checkThresholds(allThresholds) {
264
- for (const { coverageMap, thresholds, name } of allThresholds) {
265
- if (thresholds.branches === void 0 && thresholds.functions === void 0 && thresholds.lines === void 0 && thresholds.statements === void 0) {
266
- continue;
267
- }
268
- const summaries = this.options.thresholds?.perFile ? coverageMap.files().map((file) => ({
269
- file,
270
- summary: coverageMap.fileCoverageFor(file).toSummary()
271
- })) : [{ file: null, summary: coverageMap.getCoverageSummary() }];
272
- for (const { summary, file } of summaries) {
273
- for (const thresholdKey of THRESHOLD_KEYS) {
274
- const threshold = thresholds[thresholdKey];
275
- if (threshold === void 0) {
276
- continue;
277
- }
278
- if (threshold >= 0) {
279
- const coverage = summary.data[thresholdKey].pct;
280
- if (coverage < threshold) {
281
- process.exitCode = 1;
282
- let errorMessage = `ERROR: Coverage for ${thresholdKey} (${coverage}%) does not meet ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${threshold}%)`;
283
- if (this.options.thresholds?.perFile && file) {
284
- errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
285
- }
286
- this.ctx.logger.error(errorMessage);
287
- }
288
- } else {
289
- const uncovered = summary.data[thresholdKey].total - summary.data[thresholdKey].covered;
290
- const absoluteThreshold = threshold * -1;
291
- if (uncovered > absoluteThreshold) {
292
- process.exitCode = 1;
293
- let errorMessage = `ERROR: Uncovered ${thresholdKey} (${uncovered}) exceed ${name === GLOBAL_THRESHOLDS_KEY ? name : `"${name}"`} threshold (${absoluteThreshold})`;
294
- if (this.options.thresholds?.perFile && file) {
295
- errorMessage += ` for ${relative("./", file).replace(/\\/g, "/")}`;
296
- }
297
- this.ctx.logger.error(errorMessage);
298
- }
299
- }
300
- }
301
- }
302
- }
303
- }
304
- /**
305
- * Check if current coverage is above configured thresholds and bump the thresholds if needed
306
- */
307
- async updateThresholds({ thresholds: allThresholds, onUpdate, configurationFile }) {
308
- let updatedThresholds = false;
309
- const config = resolveConfig(configurationFile);
310
- assertConfigurationModule(config);
311
- for (const { coverageMap, thresholds, name } of allThresholds) {
312
- const summaries = this.options.thresholds?.perFile ? coverageMap.files().map(
313
- (file) => coverageMap.fileCoverageFor(file).toSummary()
314
- ) : [coverageMap.getCoverageSummary()];
315
- const thresholdsToUpdate = [];
316
- for (const key of THRESHOLD_KEYS) {
317
- const threshold = thresholds[key] ?? 100;
318
- if (threshold >= 0) {
319
- const actual = Math.min(
320
- ...summaries.map((summary) => summary[key].pct)
321
- );
322
- if (actual > threshold) {
323
- thresholdsToUpdate.push([key, actual]);
324
- }
325
- } else {
326
- const absoluteThreshold = threshold * -1;
327
- const actual = Math.max(
328
- ...summaries.map((summary) => summary[key].total - summary[key].covered)
329
- );
330
- if (actual < absoluteThreshold) {
331
- const updatedThreshold = actual === 0 ? 100 : actual * -1;
332
- thresholdsToUpdate.push([key, updatedThreshold]);
333
- }
334
- }
335
- }
336
- if (thresholdsToUpdate.length === 0) {
337
- continue;
338
- }
339
- updatedThresholds = true;
340
- for (const [threshold, newValue] of thresholdsToUpdate) {
341
- if (name === GLOBAL_THRESHOLDS_KEY) {
342
- config.test.coverage.thresholds[threshold] = newValue;
343
- } else {
344
- const glob = config.test.coverage.thresholds[name];
345
- glob[threshold] = newValue;
346
- }
347
- }
348
- }
349
- if (updatedThresholds) {
350
- this.ctx.logger.log("Updating thresholds to configuration file. You may want to push with updated coverage thresholds.");
351
- onUpdate();
352
- }
353
- }
354
- async mergeReports(coverageMaps) {
355
- const coverageMap = this.createCoverageMap();
356
- for (const coverage of coverageMaps) {
357
- coverageMap.merge(coverage);
358
- }
359
- await this.generateReports(coverageMap, true);
360
- }
361
- hasTerminalReporter(reporters) {
362
- return reporters.some(
363
- ([reporter]) => reporter === "text" || reporter === "text-summary" || reporter === "text-lcov" || reporter === "teamcity"
364
- );
365
- }
366
- toSlices(array, size) {
367
- return array.reduce((chunks, item) => {
368
- const index = Math.max(0, chunks.length - 1);
369
- const lastChunk = chunks[index] || [];
370
- chunks[index] = lastChunk;
371
- if (lastChunk.length >= size) {
372
- chunks.push([item]);
373
- } else {
374
- lastChunk.push(item);
375
- }
376
- return chunks;
377
- }, []);
378
- }
379
- createUncoveredFileTransformer(ctx) {
380
- const servers = [
381
- ...ctx.projects.map((project) => ({
382
- root: project.config.root,
383
- vitenode: project.vitenode
384
- })),
385
- // Check core last as it will match all files anyway
386
- { root: ctx.config.root, vitenode: ctx.vitenode }
387
- ];
388
- return async function transformFile(filename) {
389
- let lastError;
390
- for (const { root, vitenode } of servers) {
391
- if (!filename.startsWith(root)) {
392
- continue;
393
- }
394
- try {
395
- return await vitenode.transformRequest(filename);
396
- } catch (error) {
397
- lastError = error;
398
- }
399
- }
400
- throw lastError;
401
- };
402
- }
403
- }
404
- function resolveGlobThresholds(thresholds) {
405
- if (!thresholds || typeof thresholds !== "object") {
406
- return {};
407
- }
408
- if (100 in thresholds && thresholds[100] === true) {
409
- return {
410
- lines: 100,
411
- branches: 100,
412
- functions: 100,
413
- statements: 100
414
- };
415
- }
416
- return {
417
- lines: "lines" in thresholds && typeof thresholds.lines === "number" ? thresholds.lines : void 0,
418
- branches: "branches" in thresholds && typeof thresholds.branches === "number" ? thresholds.branches : void 0,
419
- functions: "functions" in thresholds && typeof thresholds.functions === "number" ? thresholds.functions : void 0,
420
- statements: "statements" in thresholds && typeof thresholds.statements === "number" ? thresholds.statements : void 0
421
- };
422
- }
423
- function assertConfigurationModule(config) {
424
- try {
425
- if (typeof config.test.coverage.thresholds !== "object") {
426
- throw new TypeError(
427
- "Expected config.test.coverage.thresholds to be an object"
428
- );
429
- }
430
- } catch (error) {
431
- const message = error instanceof Error ? error.message : String(error);
432
- throw new Error(
433
- `Unable to parse thresholds from configuration file: ${message}`
434
- );
435
- }
436
- }
437
- function resolveConfig(configModule) {
438
- const mod = configModule.exports.default;
439
- try {
440
- if (mod.$type === "object") {
441
- return mod;
442
- }
443
- let config = resolveDefineConfig(mod);
444
- if (config) {
445
- return config;
446
- }
447
- if (mod.$type === "function-call" && mod.$callee === "mergeConfig") {
448
- config = resolveMergeConfig(mod);
449
- if (config) {
450
- return config;
451
- }
452
- }
453
- } catch (error) {
454
- throw new Error(error instanceof Error ? error.message : String(error));
455
- }
456
- throw new Error(
457
- "Failed to update coverage thresholds. Configuration file is too complex."
458
- );
459
- }
460
- function resolveDefineConfig(mod) {
461
- if (mod.$type === "function-call" && mod.$callee === "defineConfig") {
462
- if (mod.$args[0].$type === "object") {
463
- return mod.$args[0];
464
- }
465
- if (mod.$args[0].$type === "arrow-function-expression") {
466
- if (mod.$args[0].$body.$type === "object") {
467
- return mod.$args[0].$body;
468
- }
469
- const config = resolveMergeConfig(mod.$args[0].$body);
470
- if (config) {
471
- return config;
472
- }
473
- }
474
- }
475
- }
476
- function resolveMergeConfig(mod) {
477
- if (mod.$type === "function-call" && mod.$callee === "mergeConfig") {
478
- for (const arg of mod.$args) {
479
- const config = resolveDefineConfig(arg);
480
- if (config) {
481
- return config;
482
- }
483
- }
484
- }
485
- }
486
-
487
- export { BaseCoverageProvider };
37
+ import './chunks/coverage.A3sS5-Wm.js';