@vitest/coverage-v8 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/dist/browser.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { V8CoverageProvider } from './provider.js';
2
+ import 'magicast';
2
3
  import 'istanbul-lib-coverage';
4
+ import 'test-exclude';
3
5
  import 'vitest/coverage';
4
6
  import 'vitest/node';
5
- import 'vitest';
6
7
 
7
8
  declare const _default: {
8
9
  startCoverage(): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { Profiler } from 'node:inspector';
2
2
  import { V8CoverageProvider } from './provider.js';
3
+ import 'magicast';
3
4
  import 'istanbul-lib-coverage';
5
+ import 'test-exclude';
4
6
  import 'vitest/coverage';
5
7
  import 'vitest/node';
6
- import 'vitest';
7
8
 
8
9
  declare const _default: {
9
10
  startCoverage(): void;
@@ -1,60 +1,18 @@
1
- import { CoverageMap } from 'istanbul-lib-coverage';
1
+ import * as magicast from 'magicast';
2
+ import libCoverage, { CoverageMap } from 'istanbul-lib-coverage';
3
+ import TestExclude from 'test-exclude';
2
4
  import { BaseCoverageProvider } from 'vitest/coverage';
3
- import { Vitest } from 'vitest/node';
4
- import { CoverageProvider, AfterSuiteRunMeta, ReportContext, ResolvedCoverageOptions } from 'vitest';
5
+ import { ResolvedCoverageOptions, CoverageProvider, Vitest, ReportContext } from 'vitest/node';
5
6
 
6
- interface TestExclude {
7
- new (opts: {
8
- cwd?: string | string[];
9
- include?: string | string[];
10
- exclude?: string | string[];
11
- extension?: string | string[];
12
- excludeNodeModules?: boolean;
13
- relativePath?: boolean;
14
- }): {
15
- shouldInstrument: (filePath: string) => boolean;
16
- glob: (cwd: string) => Promise<string[]>;
17
- };
18
- }
19
- type Options = ResolvedCoverageOptions<'v8'>;
20
- /**
21
- * Holds info about raw coverage results that are stored on file system:
22
- *
23
- * ```json
24
- * "project-a": {
25
- * "web": {
26
- * "tests/math.test.ts": "coverage-1.json",
27
- * "tests/utils.test.ts": "coverage-2.json",
28
- * // ^^^^^^^^^^^^^^^ Raw coverage on file system
29
- * },
30
- * "ssr": { ... },
31
- * "browser": { ... },
32
- * },
33
- * "project-b": ...
34
- * ```
35
- */
36
- type CoverageFiles = Map<NonNullable<AfterSuiteRunMeta['projectName']> | typeof DEFAULT_PROJECT, Record<AfterSuiteRunMeta['transformMode'], {
37
- [TestFilenames: string]: string;
38
- }>>;
39
- declare const DEFAULT_PROJECT: unique symbol;
40
- declare class V8CoverageProvider extends BaseCoverageProvider implements CoverageProvider {
41
- name: string;
42
- ctx: Vitest;
43
- options: Options;
44
- testExclude: InstanceType<TestExclude>;
45
- coverageFiles: CoverageFiles;
46
- coverageFilesDirectory: string;
47
- pendingPromises: Promise<void>[];
7
+ declare class V8CoverageProvider extends BaseCoverageProvider<ResolvedCoverageOptions<'v8'>> implements CoverageProvider {
8
+ name: "v8";
9
+ version: string;
10
+ testExclude: InstanceType<typeof TestExclude>;
48
11
  initialize(ctx: Vitest): void;
49
- resolveOptions(): Options;
50
- clean(clean?: boolean): Promise<void>;
51
- onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }: AfterSuiteRunMeta): void;
12
+ createCoverageMap(): libCoverage.CoverageMap;
52
13
  generateCoverage({ allTestsRun }: ReportContext): Promise<CoverageMap>;
53
- reportCoverage(coverageMap: unknown, { allTestsRun }: ReportContext): Promise<void>;
54
- private cleanAfterRun;
55
- onTestFailure(): Promise<void>;
56
14
  generateReports(coverageMap: CoverageMap, allTestsRun?: boolean): Promise<void>;
57
- mergeReports(coverageMaps: unknown[]): Promise<void>;
15
+ parseConfigModule(configFilePath: string): Promise<magicast.ProxifiedModule<any>>;
58
16
  private getUntestedFiles;
59
17
  private getSources;
60
18
  private convertCoverage;
package/dist/provider.js CHANGED
@@ -1,5 +1,5 @@
1
- import { existsSync, promises, readdirSync, writeFileSync } from 'node:fs';
2
1
  import { pathToFileURL, fileURLToPath } from 'node:url';
2
+ import { promises } from 'node:fs';
3
3
  import require$$0 from 'assert';
4
4
  import require$$2 from 'util';
5
5
  import require$$3 from 'path';
@@ -7,20 +7,19 @@ import require$$4 from 'url';
7
7
  import require$$9 from 'fs';
8
8
  import require$$11 from 'module';
9
9
  import { mergeProcessCovs } from '@bcoe/v8-coverage';
10
- import libReport from 'istanbul-lib-report';
11
- import reports from 'istanbul-reports';
12
10
  import libCoverage from 'istanbul-lib-coverage';
11
+ import libReport from 'istanbul-lib-report';
13
12
  import libSourceMaps from 'istanbul-lib-source-maps';
14
- import MagicString from 'magic-string';
15
- import { parseModule } from 'magicast';
16
- import remapping from '@ampproject/remapping';
17
- import c from 'tinyrainbow';
13
+ import reports from 'istanbul-reports';
18
14
  import { provider } from 'std-env';
15
+ import c from 'tinyrainbow';
19
16
  import createDebug from 'debug';
20
- import { builtinModules } from 'node:module';
21
- import { coverageConfigDefaults } from 'vitest/config';
17
+ import MagicString from 'magic-string';
18
+ import TestExclude from 'test-exclude';
19
+ import remapping from '@ampproject/remapping';
22
20
  import { BaseCoverageProvider } from 'vitest/coverage';
23
- import _TestExclude from 'test-exclude';
21
+ import { builtinModules } from 'node:module';
22
+ import { parseModule } from 'magicast';
24
23
 
25
24
  function getDefaultExportFromCjs (x) {
26
25
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -2540,57 +2539,20 @@ function cleanUrl(url) {
2540
2539
  "wasi"
2541
2540
  ]);
2542
2541
 
2543
- var version = "2.1.2";
2542
+ var version = "2.1.3";
2544
2543
 
2545
2544
  const WRAPPER_LENGTH = 185;
2546
2545
  const VITE_EXPORTS_LINE_PATTERN = /Object\.defineProperty\(__vite_ssr_exports__.*\n/g;
2547
2546
  const DECORATOR_METADATA_PATTERN = /_ts_metadata\("design:paramtypes", \[[^\]]*\]\),*/g;
2548
- const DEFAULT_PROJECT = Symbol.for("default-project");
2549
2547
  const FILE_PROTOCOL = "file://";
2550
2548
  const debug = createDebug("vitest:coverage");
2551
- let uniqueId = 0;
2552
2549
  class V8CoverageProvider extends BaseCoverageProvider {
2553
2550
  name = "v8";
2554
- ctx;
2555
- options;
2551
+ version = version;
2556
2552
  testExclude;
2557
- coverageFiles = /* @__PURE__ */ new Map();
2558
- coverageFilesDirectory;
2559
- pendingPromises = [];
2560
2553
  initialize(ctx) {
2561
- const config = ctx.config.coverage;
2562
- if (ctx.version !== version) {
2563
- ctx.logger.warn(
2564
- c.yellow(
2565
- `Loaded ${c.inverse(c.yellow(` vitest@${ctx.version} `))} and ${c.inverse(c.yellow(` @vitest/coverage-v8@${version} `))}.
2566
- Running mixed versions is not supported and may lead into bugs
2567
- Update your dependencies and make sure the versions match.`
2568
- )
2569
- );
2570
- }
2571
- this.ctx = ctx;
2572
- this.options = {
2573
- ...coverageConfigDefaults,
2574
- // User's options
2575
- ...config,
2576
- // Resolved fields
2577
- provider: "v8",
2578
- reporter: this.resolveReporters(
2579
- config.reporter || coverageConfigDefaults.reporter
2580
- ),
2581
- reportsDirectory: resolve(
2582
- ctx.config.root,
2583
- config.reportsDirectory || coverageConfigDefaults.reportsDirectory
2584
- ),
2585
- thresholds: config.thresholds && {
2586
- ...config.thresholds,
2587
- lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
2588
- branches: config.thresholds["100"] ? 100 : config.thresholds.branches,
2589
- functions: config.thresholds["100"] ? 100 : config.thresholds.functions,
2590
- statements: config.thresholds["100"] ? 100 : config.thresholds.statements
2591
- }
2592
- };
2593
- this.testExclude = new _TestExclude({
2554
+ this._initialize(ctx);
2555
+ this.testExclude = new TestExclude({
2594
2556
  cwd: ctx.config.root,
2595
2557
  include: this.options.include,
2596
2558
  exclude: this.options.exclude,
@@ -2598,82 +2560,18 @@ Update your dependencies and make sure the versions match.`
2598
2560
  extension: this.options.extension,
2599
2561
  relativePath: !this.options.allowExternal
2600
2562
  });
2601
- const shard = this.ctx.config.shard;
2602
- const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
2603
- this.coverageFilesDirectory = resolve(
2604
- this.options.reportsDirectory,
2605
- tempDirectory
2606
- );
2607
- }
2608
- resolveOptions() {
2609
- return this.options;
2610
2563
  }
2611
- async clean(clean = true) {
2612
- if (clean && existsSync(this.options.reportsDirectory)) {
2613
- await promises.rm(this.options.reportsDirectory, {
2614
- recursive: true,
2615
- force: true,
2616
- maxRetries: 10
2617
- });
2618
- }
2619
- if (existsSync(this.coverageFilesDirectory)) {
2620
- await promises.rm(this.coverageFilesDirectory, {
2621
- recursive: true,
2622
- force: true,
2623
- maxRetries: 10
2624
- });
2625
- }
2626
- await promises.mkdir(this.coverageFilesDirectory, { recursive: true });
2627
- this.coverageFiles = /* @__PURE__ */ new Map();
2628
- this.pendingPromises = [];
2629
- }
2630
- /*
2631
- * Coverage and meta information passed from Vitest runners.
2632
- * Note that adding new entries here and requiring on those without
2633
- * backwards compatibility is a breaking change.
2634
- */
2635
- onAfterSuiteRun({ coverage, transformMode, projectName, testFiles }) {
2636
- if (transformMode !== "web" && transformMode !== "ssr" && transformMode !== "browser") {
2637
- throw new Error(`Invalid transform mode: ${transformMode}`);
2638
- }
2639
- let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
2640
- if (!entry) {
2641
- entry = { web: {}, ssr: {}, browser: {} };
2642
- this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
2643
- }
2644
- const testFilenames = testFiles.join();
2645
- const filename = resolve(
2646
- this.coverageFilesDirectory,
2647
- `coverage-${uniqueId++}.json`
2648
- );
2649
- entry[transformMode][testFilenames] = filename;
2650
- const promise = promises.writeFile(filename, JSON.stringify(coverage), "utf-8");
2651
- this.pendingPromises.push(promise);
2564
+ createCoverageMap() {
2565
+ return libCoverage.createCoverageMap({});
2652
2566
  }
2653
2567
  async generateCoverage({ allTestsRun }) {
2654
- const coverageMap = libCoverage.createCoverageMap({});
2655
- let index = 0;
2656
- const total = this.pendingPromises.length;
2657
- await Promise.all(this.pendingPromises);
2658
- this.pendingPromises = [];
2659
- for (const [projectName, coveragePerProject] of this.coverageFiles.entries()) {
2660
- for (const [transformMode, coverageByTestfiles] of Object.entries(coveragePerProject)) {
2661
- let merged = { result: [] };
2662
- const filenames = Object.values(coverageByTestfiles);
2663
- const project = this.ctx.projects.find((p) => p.getName() === projectName) || this.ctx.getCoreWorkspaceProject();
2664
- for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
2665
- if (debug.enabled) {
2666
- index += chunk.length;
2667
- debug("Covered files %d/%d", index, total);
2668
- }
2669
- await Promise.all(
2670
- chunk.map(async (filename) => {
2671
- const contents = await promises.readFile(filename, "utf-8");
2672
- const coverage = JSON.parse(contents);
2673
- merged = mergeProcessCovs([merged, coverage]);
2674
- })
2675
- );
2676
- }
2568
+ const coverageMap = this.createCoverageMap();
2569
+ let merged = { result: [] };
2570
+ await this.readCoverageFiles({
2571
+ onFileRead(coverage) {
2572
+ merged = mergeProcessCovs([merged, coverage]);
2573
+ },
2574
+ onFinished: async (project, transformMode) => {
2677
2575
  const converted = await this.convertCoverage(
2678
2576
  merged,
2679
2577
  project,
@@ -2681,8 +2579,10 @@ Update your dependencies and make sure the versions match.`
2681
2579
  );
2682
2580
  const transformedCoverage = await transformCoverage(converted);
2683
2581
  coverageMap.merge(transformedCoverage);
2684
- }
2685
- }
2582
+ merged = { result: [] };
2583
+ },
2584
+ onDebug: debug
2585
+ });
2686
2586
  if (this.options.all && (allTestsRun || !this.options.cleanOnRerun)) {
2687
2587
  const coveredFiles = coverageMap.files();
2688
2588
  const untestedCoverage = await this.getUntestedFiles(coveredFiles);
@@ -2694,7 +2594,7 @@ Update your dependencies and make sure the versions match.`
2694
2594
  }
2695
2595
  return coverageMap;
2696
2596
  }
2697
- async reportCoverage(coverageMap, { allTestsRun }) {
2597
+ async generateReports(coverageMap, allTestsRun) {
2698
2598
  if (provider === "stackblitz") {
2699
2599
  this.ctx.logger.log(
2700
2600
  c.blue(" % ") + c.yellow(
@@ -2702,28 +2602,6 @@ Update your dependencies and make sure the versions match.`
2702
2602
  )
2703
2603
  );
2704
2604
  }
2705
- await this.generateReports(
2706
- coverageMap || libCoverage.createCoverageMap({}),
2707
- allTestsRun
2708
- );
2709
- const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch;
2710
- if (!keepResults) {
2711
- await this.cleanAfterRun();
2712
- }
2713
- }
2714
- async cleanAfterRun() {
2715
- this.coverageFiles = /* @__PURE__ */ new Map();
2716
- await promises.rm(this.coverageFilesDirectory, { recursive: true });
2717
- if (readdirSync(this.options.reportsDirectory).length === 0) {
2718
- await promises.rm(this.options.reportsDirectory, { recursive: true });
2719
- }
2720
- }
2721
- async onTestFailure() {
2722
- if (!this.options.reportOnFailure) {
2723
- await this.cleanAfterRun();
2724
- }
2725
- }
2726
- async generateReports(coverageMap, allTestsRun) {
2727
2605
  const context = libReport.createContext({
2728
2606
  dir: this.options.reportsDirectory,
2729
2607
  coverageMap,
@@ -2742,46 +2620,13 @@ Update your dependencies and make sure the versions match.`
2742
2620
  }).execute(context);
2743
2621
  }
2744
2622
  if (this.options.thresholds) {
2745
- const resolvedThresholds = this.resolveThresholds({
2746
- coverageMap,
2747
- thresholds: this.options.thresholds,
2748
- createCoverageMap: () => libCoverage.createCoverageMap({}),
2749
- root: this.ctx.config.root
2750
- });
2751
- this.checkThresholds({
2752
- thresholds: resolvedThresholds,
2753
- perFile: this.options.thresholds.perFile,
2754
- onError: (error) => this.ctx.logger.error(error)
2755
- });
2756
- if (this.options.thresholds.autoUpdate && allTestsRun) {
2757
- if (!this.ctx.server.config.configFile) {
2758
- throw new Error(
2759
- 'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
2760
- );
2761
- }
2762
- const configFilePath = this.ctx.server.config.configFile;
2763
- const configModule = parseModule(
2764
- await promises.readFile(configFilePath, "utf8")
2765
- );
2766
- this.updateThresholds({
2767
- thresholds: resolvedThresholds,
2768
- perFile: this.options.thresholds.perFile,
2769
- configurationFile: configModule,
2770
- onUpdate: () => writeFileSync(
2771
- configFilePath,
2772
- configModule.generate().code,
2773
- "utf-8"
2774
- )
2775
- });
2776
- }
2623
+ await this.reportThresholds(coverageMap, allTestsRun);
2777
2624
  }
2778
2625
  }
2779
- async mergeReports(coverageMaps) {
2780
- const coverageMap = libCoverage.createCoverageMap({});
2781
- for (const coverage of coverageMaps) {
2782
- coverageMap.merge(coverage);
2783
- }
2784
- await this.generateReports(coverageMap, true);
2626
+ async parseConfigModule(configFilePath) {
2627
+ return parseModule(
2628
+ await promises.readFile(configFilePath, "utf8")
2629
+ );
2785
2630
  }
2786
2631
  async getUntestedFiles(testedFiles) {
2787
2632
  const transformResults = normalizeTransformResults(
@@ -2800,10 +2645,7 @@ Update your dependencies and make sure the versions match.`
2800
2645
  const uncoveredFiles = includedFiles.map((file) => pathToFileURL(file)).filter((file) => !testedFiles.includes(file.pathname));
2801
2646
  let merged = { result: [] };
2802
2647
  let index = 0;
2803
- for (const chunk of this.toSlices(
2804
- uncoveredFiles,
2805
- this.options.processingConcurrency
2806
- )) {
2648
+ for (const chunk of this.toSlices(uncoveredFiles, this.options.processingConcurrency)) {
2807
2649
  if (debug.enabled) {
2808
2650
  index += chunk.length;
2809
2651
  debug("Uncovered files %d/%d", index, uncoveredFiles.length);
@@ -2916,7 +2758,7 @@ Update your dependencies and make sure the versions match.`
2916
2758
  scriptCoverages.push(result);
2917
2759
  }
2918
2760
  }
2919
- const coverageMap = libCoverage.createCoverageMap({});
2761
+ const coverageMap = this.createCoverageMap();
2920
2762
  let index = 0;
2921
2763
  for (const chunk of this.toSlices(scriptCoverages, this.options.processingConcurrency)) {
2922
2764
  if (debug.enabled) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/coverage-v8",
3
3
  "type": "module",
4
- "version": "2.1.2",
4
+ "version": "2.1.3",
5
5
  "description": "V8 coverage provider for Vitest",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -41,8 +41,8 @@
41
41
  "dist"
42
42
  ],
43
43
  "peerDependencies": {
44
- "@vitest/browser": "2.1.2",
45
- "vitest": "2.1.2"
44
+ "@vitest/browser": "2.1.3",
45
+ "vitest": "2.1.3"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "@vitest/browser": {
@@ -69,11 +69,12 @@
69
69
  "@types/istanbul-lib-report": "^3.0.3",
70
70
  "@types/istanbul-lib-source-maps": "^4.0.4",
71
71
  "@types/istanbul-reports": "^3.0.4",
72
+ "@types/test-exclude": "^6.0.2",
72
73
  "pathe": "^1.1.2",
73
74
  "v8-to-istanbul": "^9.3.0",
74
- "@vitest/browser": "2.1.2",
75
- "vite-node": "2.1.2",
76
- "vitest": "2.1.2"
75
+ "@vitest/browser": "2.1.3",
76
+ "vite-node": "2.1.3",
77
+ "vitest": "2.1.3"
77
78
  },
78
79
  "scripts": {
79
80
  "build": "rimraf dist && rollup -c",