@vitest/coverage-istanbul 2.0.0-beta.1 → 2.0.0-beta.11

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.
@@ -38,8 +38,11 @@ declare class IstanbulCoverageProvider extends BaseCoverageProvider implements C
38
38
  } | undefined;
39
39
  onAfterSuiteRun({ coverage, transformMode, projectName }: AfterSuiteRunMeta): void;
40
40
  clean(clean?: boolean): Promise<void>;
41
- reportCoverage({ allTestsRun }?: ReportContext): Promise<void>;
42
- getCoverageMapForUncoveredFiles(coveredFiles: string[]): Promise<CoverageMap>;
41
+ generateCoverage({ allTestsRun }: ReportContext): Promise<CoverageMap>;
42
+ reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise<void>;
43
+ generateReports(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise<void>;
44
+ mergeReports(coverageMaps: unknown[]): Promise<void>;
45
+ private getCoverageMapForUncoveredFiles;
43
46
  }
44
47
 
45
48
  export { IstanbulCoverageProvider };
package/dist/provider.js CHANGED
@@ -1,4 +1,4 @@
1
- import { promises, existsSync, writeFileSync } from 'node:fs';
1
+ import { promises, existsSync, readdirSync, writeFileSync } from 'node:fs';
2
2
  import { coverageConfigDefaults, defaultExclude, defaultInclude } from 'vitest/config';
3
3
  import { BaseCoverageProvider } from 'vitest/coverage';
4
4
  import c from 'picocolors';
@@ -128,8 +128,13 @@ class IstanbulCoverageProvider extends BaseCoverageProvider {
128
128
  ...config,
129
129
  // Resolved fields
130
130
  provider: "istanbul",
131
- reportsDirectory: resolve(ctx.config.root, config.reportsDirectory || coverageConfigDefaults.reportsDirectory),
132
- reporter: this.resolveReporters(config.reporter || coverageConfigDefaults.reporter),
131
+ reportsDirectory: resolve(
132
+ ctx.config.root,
133
+ config.reportsDirectory || coverageConfigDefaults.reportsDirectory
134
+ ),
135
+ reporter: this.resolveReporters(
136
+ config.reporter || coverageConfigDefaults.reporter
137
+ ),
133
138
  thresholds: config.thresholds && {
134
139
  ...config.thresholds,
135
140
  lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
@@ -159,18 +164,29 @@ class IstanbulCoverageProvider extends BaseCoverageProvider {
159
164
  });
160
165
  const shard = this.ctx.config.shard;
161
166
  const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
162
- this.coverageFilesDirectory = resolve(this.options.reportsDirectory, tempDirectory);
167
+ this.coverageFilesDirectory = resolve(
168
+ this.options.reportsDirectory,
169
+ tempDirectory
170
+ );
163
171
  }
164
172
  resolveOptions() {
165
173
  return this.options;
166
174
  }
167
175
  onFileTransform(sourceCode, id, pluginCtx) {
168
- if (!this.testExclude.shouldInstrument(id))
176
+ if (!this.testExclude.shouldInstrument(id)) {
169
177
  return;
178
+ }
170
179
  const sourceMap = pluginCtx.getCombinedSourcemap();
171
180
  sourceMap.sources = sourceMap.sources.map(removeQueryParameters);
172
- sourceCode = sourceCode.replaceAll("_ts_decorate", "/* istanbul ignore next */_ts_decorate");
173
- const code = this.instrumenter.instrumentSync(sourceCode, id, sourceMap);
181
+ sourceCode = sourceCode.replaceAll(
182
+ "_ts_decorate",
183
+ "/* istanbul ignore next */_ts_decorate"
184
+ );
185
+ const code = this.instrumenter.instrumentSync(
186
+ sourceCode,
187
+ id,
188
+ sourceMap
189
+ );
174
190
  const map = this.instrumenter.lastSourceMap();
175
191
  return { code, map };
176
192
  }
@@ -180,65 +196,112 @@ class IstanbulCoverageProvider extends BaseCoverageProvider {
180
196
  * backwards compatibility is a breaking change.
181
197
  */
182
198
  onAfterSuiteRun({ coverage, transformMode, projectName }) {
183
- if (!coverage)
199
+ if (!coverage) {
184
200
  return;
185
- if (transformMode !== "web" && transformMode !== "ssr")
201
+ }
202
+ if (transformMode !== "web" && transformMode !== "ssr") {
186
203
  throw new Error(`Invalid transform mode: ${transformMode}`);
204
+ }
187
205
  let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
188
206
  if (!entry) {
189
207
  entry = { web: [], ssr: [] };
190
208
  this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
191
209
  }
192
- const filename = resolve(this.coverageFilesDirectory, `coverage-${uniqueId++}.json`);
210
+ const filename = resolve(
211
+ this.coverageFilesDirectory,
212
+ `coverage-${uniqueId++}.json`
213
+ );
193
214
  entry[transformMode].push(filename);
194
215
  const promise = promises.writeFile(filename, JSON.stringify(coverage), "utf-8");
195
216
  this.pendingPromises.push(promise);
196
217
  }
197
218
  async clean(clean = true) {
198
- if (clean && existsSync(this.options.reportsDirectory))
199
- await promises.rm(this.options.reportsDirectory, { recursive: true, force: true, maxRetries: 10 });
200
- if (existsSync(this.coverageFilesDirectory))
201
- await promises.rm(this.coverageFilesDirectory, { recursive: true, force: true, maxRetries: 10 });
219
+ if (clean && existsSync(this.options.reportsDirectory)) {
220
+ await promises.rm(this.options.reportsDirectory, {
221
+ recursive: true,
222
+ force: true,
223
+ maxRetries: 10
224
+ });
225
+ }
226
+ if (existsSync(this.coverageFilesDirectory)) {
227
+ await promises.rm(this.coverageFilesDirectory, {
228
+ recursive: true,
229
+ force: true,
230
+ maxRetries: 10
231
+ });
232
+ }
202
233
  await promises.mkdir(this.coverageFilesDirectory, { recursive: true });
203
234
  this.coverageFiles = /* @__PURE__ */ new Map();
204
235
  this.pendingPromises = [];
205
236
  }
206
- async reportCoverage({ allTestsRun } = {}) {
237
+ async generateCoverage({ allTestsRun }) {
207
238
  const coverageMap = libCoverage.createCoverageMap({});
208
239
  let index = 0;
209
240
  const total = this.pendingPromises.length;
210
241
  await Promise.all(this.pendingPromises);
211
242
  this.pendingPromises = [];
212
243
  for (const coveragePerProject of this.coverageFiles.values()) {
213
- for (const filenames of [coveragePerProject.ssr, coveragePerProject.web]) {
244
+ for (const filenames of [
245
+ coveragePerProject.ssr,
246
+ coveragePerProject.web
247
+ ]) {
214
248
  const coverageMapByTransformMode = libCoverage.createCoverageMap({});
215
- for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
249
+ for (const chunk of this.toSlices(
250
+ filenames,
251
+ this.options.processingConcurrency
252
+ )) {
216
253
  if (debug.enabled) {
217
254
  index += chunk.length;
218
255
  debug("Covered files %d/%d", index, total);
219
256
  }
220
- await Promise.all(chunk.map(async (filename) => {
221
- const contents = await promises.readFile(filename, "utf-8");
222
- const coverage = JSON.parse(contents);
223
- coverageMapByTransformMode.merge(coverage);
224
- }));
257
+ await Promise.all(
258
+ chunk.map(async (filename) => {
259
+ const contents = await promises.readFile(filename, "utf-8");
260
+ const coverage = JSON.parse(contents);
261
+ coverageMapByTransformMode.merge(coverage);
262
+ })
263
+ );
225
264
  }
226
- const transformedCoverage = await transformCoverage(coverageMapByTransformMode);
265
+ const transformedCoverage = await transformCoverage(
266
+ coverageMapByTransformMode
267
+ );
227
268
  coverageMap.merge(transformedCoverage);
228
269
  }
229
270
  }
230
271
  if (this.options.all && allTestsRun) {
231
272
  const coveredFiles = coverageMap.files();
232
- const uncoveredCoverage = await this.getCoverageMapForUncoveredFiles(coveredFiles);
273
+ const uncoveredCoverage = await this.getCoverageMapForUncoveredFiles(
274
+ coveredFiles
275
+ );
233
276
  coverageMap.merge(await transformCoverage(uncoveredCoverage));
234
277
  }
278
+ return coverageMap;
279
+ }
280
+ async reportCoverage(coverageMap, { allTestsRun }) {
281
+ await this.generateReports(
282
+ coverageMap || libCoverage.createCoverageMap({}),
283
+ allTestsRun
284
+ );
285
+ const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
286
+ if (!keepResults) {
287
+ this.coverageFiles = /* @__PURE__ */ new Map();
288
+ await promises.rm(this.coverageFilesDirectory, { recursive: true });
289
+ if (readdirSync(this.options.reportsDirectory).length === 0) {
290
+ await promises.rm(this.options.reportsDirectory, { recursive: true });
291
+ }
292
+ }
293
+ }
294
+ async generateReports(coverageMap, allTestsRun) {
235
295
  const context = libReport.createContext({
236
296
  dir: this.options.reportsDirectory,
237
297
  coverageMap,
238
298
  watermarks: this.options.watermarks
239
299
  });
240
- if (this.hasTerminalReporter(this.options.reporter))
241
- this.ctx.logger.log(c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name));
300
+ if (this.hasTerminalReporter(this.options.reporter)) {
301
+ this.ctx.logger.log(
302
+ c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name)
303
+ );
304
+ }
242
305
  for (const reporter of this.options.reporter) {
243
306
  reports.create(reporter[0], {
244
307
  skipFull: this.options.skipFull,
@@ -258,30 +321,46 @@ class IstanbulCoverageProvider extends BaseCoverageProvider {
258
321
  perFile: this.options.thresholds.perFile
259
322
  });
260
323
  if (this.options.thresholds.autoUpdate && allTestsRun) {
261
- if (!this.ctx.server.config.configFile)
262
- throw new Error('Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.');
324
+ if (!this.ctx.server.config.configFile) {
325
+ throw new Error(
326
+ 'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
327
+ );
328
+ }
263
329
  const configFilePath = this.ctx.server.config.configFile;
264
- const configModule = parseModule(await promises.readFile(configFilePath, "utf8"));
330
+ const configModule = parseModule(
331
+ await promises.readFile(configFilePath, "utf8")
332
+ );
265
333
  this.updateThresholds({
266
334
  thresholds: resolvedThresholds,
267
335
  perFile: this.options.thresholds.perFile,
268
336
  configurationFile: configModule,
269
- onUpdate: () => writeFileSync(configFilePath, configModule.generate().code, "utf-8")
337
+ onUpdate: () => writeFileSync(
338
+ configFilePath,
339
+ configModule.generate().code,
340
+ "utf-8"
341
+ )
270
342
  });
271
343
  }
272
344
  }
273
- const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
274
- if (!keepResults) {
275
- this.coverageFiles = /* @__PURE__ */ new Map();
276
- await promises.rm(this.coverageFilesDirectory, { recursive: true });
345
+ }
346
+ async mergeReports(coverageMaps) {
347
+ const coverageMap = libCoverage.createCoverageMap({});
348
+ for (const coverage of coverageMaps) {
349
+ coverageMap.merge(coverage);
277
350
  }
351
+ await this.generateReports(coverageMap, true);
278
352
  }
279
353
  async getCoverageMapForUncoveredFiles(coveredFiles) {
280
354
  const allFiles = await this.testExclude.glob(this.ctx.config.root);
281
- let includedFiles = allFiles.map((file) => resolve(this.ctx.config.root, file));
282
- if (this.ctx.config.changed)
283
- includedFiles = (this.ctx.config.related || []).filter((file) => includedFiles.includes(file));
284
- const uncoveredFiles = includedFiles.filter((file) => !coveredFiles.includes(file));
355
+ let includedFiles = allFiles.map(
356
+ (file) => resolve(this.ctx.config.root, file)
357
+ );
358
+ if (this.ctx.config.changed) {
359
+ includedFiles = (this.ctx.config.related || []).filter(
360
+ (file) => includedFiles.includes(file)
361
+ );
362
+ }
363
+ const uncoveredFiles = includedFiles.filter((file) => !coveredFiles.includes(file)).sort();
285
364
  const cacheKey = (/* @__PURE__ */ new Date()).getTime();
286
365
  const coverageMap = libCoverage.createCoverageMap({});
287
366
  for (const [index, filename] of uncoveredFiles.entries()) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/coverage-istanbul",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.1",
4
+ "version": "2.0.0-beta.11",
5
5
  "description": "Istanbul coverage provider for Vitest",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -37,18 +37,18 @@
37
37
  "dist"
38
38
  ],
39
39
  "peerDependencies": {
40
- "vitest": "2.0.0-beta.1"
40
+ "vitest": "2.0.0-beta.11"
41
41
  },
42
42
  "dependencies": {
43
- "debug": "^4.3.4",
43
+ "debug": "^4.3.5",
44
44
  "istanbul-lib-coverage": "^3.2.2",
45
45
  "istanbul-lib-instrument": "^6.0.2",
46
46
  "istanbul-lib-report": "^3.0.1",
47
47
  "istanbul-lib-source-maps": "^5.0.4",
48
48
  "istanbul-reports": "^3.1.7",
49
49
  "magicast": "^0.3.4",
50
- "picocolors": "^1.0.0",
51
- "test-exclude": "^6.0.0"
50
+ "picocolors": "^1.0.1",
51
+ "test-exclude": "^7.0.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/debug": "^4.1.12",
@@ -58,7 +58,7 @@
58
58
  "@types/istanbul-lib-source-maps": "^4.0.4",
59
59
  "@types/istanbul-reports": "^3.0.4",
60
60
  "pathe": "^1.1.2",
61
- "vitest": "2.0.0-beta.1"
61
+ "vitest": "2.0.0-beta.11"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "rimraf dist && rollup -c",