@vitest/coverage-v8 3.2.0-beta.2 → 3.2.0

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { cdp } from '@vitest/browser/context';
2
- import { l as loadProvider } from './load-provider-pEnu7lco.js';
2
+ import { l as loadProvider } from './load-provider-CdgAx3rL.js';
3
3
 
4
4
  const session = cdp();
5
5
  let enabled = false;
@@ -18,6 +18,7 @@ const mod = {
18
18
  async takeCoverage() {
19
19
  const coverage = await session.send("Profiler.takePreciseCoverage");
20
20
  const result = [];
21
+ // Reduce amount of data sent over rpc by doing some early result filtering
21
22
  for (const entry of coverage.result) {
22
23
  if (filterResult(entry)) {
23
24
  result.push({
@@ -28,7 +29,9 @@ const mod = {
28
29
  }
29
30
  return { result };
30
31
  },
31
- stopCoverage() {},
32
+ stopCoverage() {
33
+ // Browser mode should not stop coverage as same V8 instance is shared between tests
34
+ },
32
35
  async getProvider() {
33
36
  return loadProvider();
34
37
  }
@@ -49,9 +52,6 @@ function filterResult(coverage) {
49
52
  if (coverage.url === window.location.href) {
50
53
  return false;
51
54
  }
52
- if (coverage.url.includes("?browserv=") || coverage.url.includes("&browserv=")) {
53
- return false;
54
- }
55
55
  return true;
56
56
  }
57
57
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import inspector from 'node:inspector';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { provider } from 'std-env';
4
- import { l as loadProvider } from './load-provider-pEnu7lco.js';
4
+ import { l as loadProvider } from './load-provider-CdgAx3rL.js';
5
5
 
6
6
  const session = new inspector.Session();
7
7
  let enabled = false;
@@ -1,3 +1,4 @@
1
+ // to not bundle the provider
1
2
  const name = "./provider.js";
2
3
  async function loadProvider() {
3
4
  const { V8CoverageProvider } = await import(
package/dist/provider.js CHANGED
@@ -2541,8 +2541,9 @@ new Set([
2541
2541
  "wasi"
2542
2542
  ]);
2543
2543
 
2544
- var version = "3.2.0-beta.2";
2544
+ var version = "3.2.0";
2545
2545
 
2546
+ // Note that this needs to match the line ending as well
2546
2547
  const VITE_EXPORTS_LINE_PATTERN = /Object\.defineProperty\(__vite_ssr_exports__.*\n/g;
2547
2548
  const DECORATOR_METADATA_PATTERN = /_ts_metadata\("design:paramtypes", \[[^\]]*\]\),*/g;
2548
2549
  const FILE_PROTOCOL = "file://";
@@ -2572,6 +2573,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
2572
2573
  await this.readCoverageFiles({
2573
2574
  onFileRead(coverage) {
2574
2575
  merged = mergeProcessCovs([merged, coverage]);
2576
+ // mergeProcessCovs sometimes loses startOffset, e.g. in vue
2575
2577
  merged.result.forEach((result) => {
2576
2578
  if (!result.startOffset) {
2577
2579
  const original = coverage.result.find((r) => r.url === result.url);
@@ -2581,12 +2583,16 @@ class V8CoverageProvider extends BaseCoverageProvider {
2581
2583
  },
2582
2584
  onFinished: async (project, transformMode) => {
2583
2585
  const converted = await this.convertCoverage(merged, project, transformMode);
2586
+ // Source maps can change based on projectName and transform mode.
2587
+ // Coverage transform re-uses source maps so we need to separate transforms from each other.
2584
2588
  const transformedCoverage = await transformCoverage(converted);
2585
2589
  coverageMap.merge(transformedCoverage);
2586
2590
  merged = { result: [] };
2587
2591
  },
2588
2592
  onDebug: debug
2589
2593
  });
2594
+ // Include untested files when all tests were run (not a single file re-run)
2595
+ // or if previous results are preserved by "cleanOnRerun: false"
2590
2596
  if (this.options.all && (allTestsRun || !this.options.cleanOnRerun)) {
2591
2597
  const coveredFiles = coverageMap.files();
2592
2598
  const untestedCoverage = await this.getUntestedFiles(coveredFiles);
@@ -2613,6 +2619,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
2613
2619
  this.ctx.logger.log(c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name));
2614
2620
  }
2615
2621
  for (const reporter of this.options.reporter) {
2622
+ // Type assertion required for custom reporters
2616
2623
  reports.create(reporter[0], {
2617
2624
  skipFull: this.options.skipFull,
2618
2625
  projectRoot: this.ctx.config.root,
@@ -2689,12 +2696,33 @@ class V8CoverageProvider extends BaseCoverageProvider {
2689
2696
  ignoreClassMethods: this.options.ignoreClassMethods,
2690
2697
  wrapperLength,
2691
2698
  ignoreNode: (node, type) => {
2692
- if (type === "statement" && node.type === "AwaitExpression" && node.argument.type === "CallExpression" && node.argument.callee.type === "Identifier" && node.argument.callee.name === "__vite_ssr_import__") {
2699
+ // SSR transformed imports
2700
+ if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name.startsWith("__vite_ssr_import_")) {
2693
2701
  return true;
2694
2702
  }
2703
+ // SSR transformed exports vite@>6.3.5
2695
2704
  if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "Identifier" && node.expression.left.object.name === "__vite_ssr_exports__") {
2696
2705
  return true;
2697
2706
  }
2707
+ // SSR transformed exports vite@^6.3.5
2708
+ if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name === "__vite_ssr_export_default__") {
2709
+ return true;
2710
+ }
2711
+ // in-source test with "if (import.meta.vitest)"
2712
+ if ((type === "branch" || type === "statement") && node.type === "IfStatement" && node.test.type === "MemberExpression" && node.test.property.type === "Identifier" && node.test.property.name === "vitest") {
2713
+ // SSR
2714
+ if (node.test.object.type === "Identifier" && node.test.object.name === "__vite_ssr_import_meta__") {
2715
+ return "ignore-this-and-nested-nodes";
2716
+ }
2717
+ // Web
2718
+ if (node.test.object.type === "MetaProperty" && node.test.object.meta.name === "import" && node.test.object.property.name === "meta") {
2719
+ return "ignore-this-and-nested-nodes";
2720
+ }
2721
+ }
2722
+ // Browser mode's "import.meta.env ="
2723
+ if (type === "statement" && node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" && node.expression.left.type === "MemberExpression" && node.expression.left.object.type === "MetaProperty" && node.expression.left.object.meta.name === "import" && node.expression.left.object.property.name === "meta" && node.expression.left.property.type === "Identifier" && node.expression.left.property.name === "env") {
2724
+ return true;
2725
+ }
2698
2726
  }
2699
2727
  });
2700
2728
  }
@@ -2718,10 +2746,13 @@ class V8CoverageProvider extends BaseCoverageProvider {
2718
2746
  const sourcesContent = map?.sourcesContent || [];
2719
2747
  if (!sourcesContent[0]) {
2720
2748
  sourcesContent[0] = await promises.readFile(filePath, "utf-8").catch(() => {
2749
+ // If file does not exist construct a dummy source for it.
2750
+ // These can be files that were generated dynamically during the test run and were removed after it.
2721
2751
  const length = findLongestFunctionLength(functions);
2722
2752
  return "/".repeat(length);
2723
2753
  });
2724
2754
  }
2755
+ // These can be uncovered files included by "all: true" or files that are loaded outside vite-node
2725
2756
  if (!map) {
2726
2757
  return {
2727
2758
  source: code || sourcesContent[0],
@@ -2766,6 +2797,8 @@ class V8CoverageProvider extends BaseCoverageProvider {
2766
2797
  if (transformMode === "browser") {
2767
2798
  if (result.url.startsWith("/@fs")) {
2768
2799
  result.url = `${FILE_PROTOCOL}${removeStartsWith(result.url, "/@fs")}`;
2800
+ } else if (result.url.startsWith(project.config.root)) {
2801
+ result.url = `${FILE_PROTOCOL}${result.url}`;
2769
2802
  } else {
2770
2803
  result.url = `${FILE_PROTOCOL}${project.config.root}${result.url}`;
2771
2804
  }
@@ -2821,6 +2854,7 @@ function excludeGeneratedCode(source, map) {
2821
2854
  trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, "\n");
2822
2855
  trimmed.replaceAll(DECORATOR_METADATA_PATTERN, (match) => "\n".repeat(match.split("\n").length - 1));
2823
2856
  const trimmedMap = trimmed.generateMap({ hires: "boundary" });
2857
+ // A merged source map where the first one excludes generated parts
2824
2858
  const combinedMap = remapping([{
2825
2859
  ...trimmedMap,
2826
2860
  version: 3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/coverage-v8",
3
3
  "type": "module",
4
- "version": "3.2.0-beta.2",
4
+ "version": "3.2.0",
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": "3.2.0-beta.2",
45
- "vitest": "3.2.0-beta.2"
44
+ "@vitest/browser": "3.2.0",
45
+ "vitest": "3.2.0"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "@vitest/browser": {
@@ -52,8 +52,8 @@
52
52
  "dependencies": {
53
53
  "@ampproject/remapping": "^2.3.0",
54
54
  "@bcoe/v8-coverage": "^1.0.2",
55
- "ast-v8-to-istanbul": "^0.3.1",
56
- "debug": "^4.4.0",
55
+ "ast-v8-to-istanbul": "^0.3.3",
56
+ "debug": "^4.4.1",
57
57
  "istanbul-lib-coverage": "^3.2.2",
58
58
  "istanbul-lib-report": "^3.0.1",
59
59
  "istanbul-lib-source-maps": "^5.0.6",
@@ -73,9 +73,9 @@
73
73
  "@types/test-exclude": "^6.0.2",
74
74
  "pathe": "^2.0.3",
75
75
  "v8-to-istanbul": "^9.3.0",
76
- "vite-node": "3.2.0-beta.2",
77
- "vitest": "3.2.0-beta.2",
78
- "@vitest/browser": "3.2.0-beta.2"
76
+ "@vitest/browser": "3.2.0",
77
+ "vite-node": "3.2.0",
78
+ "vitest": "3.2.0"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "rimraf dist && rollup -c",