@vitest/coverage-v8 4.0.0-beta.7 → 4.0.0-beta.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.
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import inspector from 'node:inspector/promises';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { provider } from 'std-env';
4
4
  import { l as loadProvider } from './load-provider-CdgAx3rL.js';
5
+ import { n as normalize } from './pathe.M-eThtNZ-BTaAGrLg.js';
5
6
 
6
7
  const session = new inspector.Session();
7
8
  let enabled = false;
@@ -29,7 +30,7 @@ const mod = {
29
30
  if (filterResult(entry)) {
30
31
  result.push({
31
32
  ...entry,
32
- startOffset: options?.moduleExecutionInfo?.get(fileURLToPath(entry.url))?.startOffset || 0
33
+ startOffset: options?.moduleExecutionInfo?.get(normalize(fileURLToPath(entry.url)))?.startOffset || 0
33
34
  });
34
35
  }
35
36
  }
@@ -0,0 +1,104 @@
1
+ const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
2
+ function normalizeWindowsPath(input = "") {
3
+ if (!input) {
4
+ return input;
5
+ }
6
+ return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
7
+ }
8
+
9
+ const _UNC_REGEX = /^[/\\]{2}/;
10
+ const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
11
+ const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
12
+ const normalize = function(path) {
13
+ if (path.length === 0) {
14
+ return ".";
15
+ }
16
+ path = normalizeWindowsPath(path);
17
+ const isUNCPath = path.match(_UNC_REGEX);
18
+ const isPathAbsolute = isAbsolute(path);
19
+ const trailingSeparator = path[path.length - 1] === "/";
20
+ path = normalizeString(path, !isPathAbsolute);
21
+ if (path.length === 0) {
22
+ if (isPathAbsolute) {
23
+ return "/";
24
+ }
25
+ return trailingSeparator ? "./" : ".";
26
+ }
27
+ if (trailingSeparator) {
28
+ path += "/";
29
+ }
30
+ if (_DRIVE_LETTER_RE.test(path)) {
31
+ path += "/";
32
+ }
33
+ if (isUNCPath) {
34
+ if (!isPathAbsolute) {
35
+ return `//./${path}`;
36
+ }
37
+ return `//${path}`;
38
+ }
39
+ return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
40
+ };
41
+ function normalizeString(path, allowAboveRoot) {
42
+ let res = "";
43
+ let lastSegmentLength = 0;
44
+ let lastSlash = -1;
45
+ let dots = 0;
46
+ let char = null;
47
+ for (let index = 0; index <= path.length; ++index) {
48
+ if (index < path.length) {
49
+ char = path[index];
50
+ } else if (char === "/") {
51
+ break;
52
+ } else {
53
+ char = "/";
54
+ }
55
+ if (char === "/") {
56
+ if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) {
57
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
58
+ if (res.length > 2) {
59
+ const lastSlashIndex = res.lastIndexOf("/");
60
+ if (lastSlashIndex === -1) {
61
+ res = "";
62
+ lastSegmentLength = 0;
63
+ } else {
64
+ res = res.slice(0, lastSlashIndex);
65
+ lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
66
+ }
67
+ lastSlash = index;
68
+ dots = 0;
69
+ continue;
70
+ } else if (res.length > 0) {
71
+ res = "";
72
+ lastSegmentLength = 0;
73
+ lastSlash = index;
74
+ dots = 0;
75
+ continue;
76
+ }
77
+ }
78
+ if (allowAboveRoot) {
79
+ res += res.length > 0 ? "/.." : "..";
80
+ lastSegmentLength = 2;
81
+ }
82
+ } else {
83
+ if (res.length > 0) {
84
+ res += `/${path.slice(lastSlash + 1, index)}`;
85
+ } else {
86
+ res = path.slice(lastSlash + 1, index);
87
+ }
88
+ lastSegmentLength = index - lastSlash - 1;
89
+ }
90
+ lastSlash = index;
91
+ dots = 0;
92
+ } else if (char === "." && dots !== -1) {
93
+ ++dots;
94
+ } else {
95
+ dots = -1;
96
+ }
97
+ }
98
+ return res;
99
+ }
100
+ const isAbsolute = function(p) {
101
+ return _IS_ABSOLUTE_RE.test(p);
102
+ };
103
+
104
+ export { normalize as n };
package/dist/provider.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { promises } from 'node:fs';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { mergeProcessCovs } from '@bcoe/v8-coverage';
4
- import { cleanUrl } from '@vitest/utils';
5
4
  import astV8ToIstanbul from 'ast-v8-to-istanbul';
6
5
  import createDebug from 'debug';
7
6
  import libCoverage from 'istanbul-lib-coverage';
@@ -12,112 +11,10 @@ import { parseModule } from 'magicast';
12
11
  import { provider } from 'std-env';
13
12
  import c from 'tinyrainbow';
14
13
  import { BaseCoverageProvider } from 'vitest/coverage';
15
- import { parseAstAsync, isCSSRequest } from 'vitest/node';
14
+ import { parseAstAsync } from 'vitest/node';
15
+ import { n as normalize } from './pathe.M-eThtNZ-BTaAGrLg.js';
16
16
 
17
- const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
18
- function normalizeWindowsPath(input = "") {
19
- if (!input) {
20
- return input;
21
- }
22
- return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
23
- }
24
-
25
- const _UNC_REGEX = /^[/\\]{2}/;
26
- const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
27
- const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
28
- const normalize = function(path) {
29
- if (path.length === 0) {
30
- return ".";
31
- }
32
- path = normalizeWindowsPath(path);
33
- const isUNCPath = path.match(_UNC_REGEX);
34
- const isPathAbsolute = isAbsolute(path);
35
- const trailingSeparator = path[path.length - 1] === "/";
36
- path = normalizeString(path, !isPathAbsolute);
37
- if (path.length === 0) {
38
- if (isPathAbsolute) {
39
- return "/";
40
- }
41
- return trailingSeparator ? "./" : ".";
42
- }
43
- if (trailingSeparator) {
44
- path += "/";
45
- }
46
- if (_DRIVE_LETTER_RE.test(path)) {
47
- path += "/";
48
- }
49
- if (isUNCPath) {
50
- if (!isPathAbsolute) {
51
- return `//./${path}`;
52
- }
53
- return `//${path}`;
54
- }
55
- return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
56
- };
57
- function normalizeString(path, allowAboveRoot) {
58
- let res = "";
59
- let lastSegmentLength = 0;
60
- let lastSlash = -1;
61
- let dots = 0;
62
- let char = null;
63
- for (let index = 0; index <= path.length; ++index) {
64
- if (index < path.length) {
65
- char = path[index];
66
- } else if (char === "/") {
67
- break;
68
- } else {
69
- char = "/";
70
- }
71
- if (char === "/") {
72
- if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) {
73
- if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
74
- if (res.length > 2) {
75
- const lastSlashIndex = res.lastIndexOf("/");
76
- if (lastSlashIndex === -1) {
77
- res = "";
78
- lastSegmentLength = 0;
79
- } else {
80
- res = res.slice(0, lastSlashIndex);
81
- lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
82
- }
83
- lastSlash = index;
84
- dots = 0;
85
- continue;
86
- } else if (res.length > 0) {
87
- res = "";
88
- lastSegmentLength = 0;
89
- lastSlash = index;
90
- dots = 0;
91
- continue;
92
- }
93
- }
94
- if (allowAboveRoot) {
95
- res += res.length > 0 ? "/.." : "..";
96
- lastSegmentLength = 2;
97
- }
98
- } else {
99
- if (res.length > 0) {
100
- res += `/${path.slice(lastSlash + 1, index)}`;
101
- } else {
102
- res = path.slice(lastSlash + 1, index);
103
- }
104
- lastSegmentLength = index - lastSlash - 1;
105
- }
106
- lastSlash = index;
107
- dots = 0;
108
- } else if (char === "." && dots !== -1) {
109
- ++dots;
110
- } else {
111
- dots = -1;
112
- }
113
- }
114
- return res;
115
- }
116
- const isAbsolute = function(p) {
117
- return _IS_ABSOLUTE_RE.test(p);
118
- };
119
-
120
- var version = "4.0.0-beta.7";
17
+ var version = "4.0.0-beta.9";
121
18
 
122
19
  const FILE_PROTOCOL = "file://";
123
20
  const debug = createDebug("vitest:coverage");
@@ -198,7 +95,6 @@ class V8CoverageProvider extends BaseCoverageProvider {
198
95
  return parseModule(await promises.readFile(configFilePath, "utf8"));
199
96
  }
200
97
  async getCoverageMapForUncoveredFiles(testedFiles) {
201
- const transformResults = normalizeTransformResults(this.ctx.vite.environments);
202
98
  const transform = this.createUncoveredFileTransformer(this.ctx);
203
99
  const uncoveredFiles = await this.getUntestedFiles(testedFiles);
204
100
  let index = 0;
@@ -217,7 +113,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
217
113
  }
218
114
  // Do not use pathToFileURL to avoid encoding filename parts
219
115
  const url = `file://${filename.startsWith("/") ? "" : "/"}${filename}`;
220
- const sources = await this.getSources(url, transformResults, transform);
116
+ const sources = await this.getSources(url, transform);
221
117
  coverageMap.merge(await this.remapCoverage(url, 0, sources, []));
222
118
  if (debug.enabled) {
223
119
  clearTimeout(timeout);
@@ -286,15 +182,12 @@ class V8CoverageProvider extends BaseCoverageProvider {
286
182
  }
287
183
  });
288
184
  }
289
- async getSources(url, transformResults, onTransform, functions = []) {
290
- const filePath = normalize(fileURLToPath(url));
291
- let transformResult = transformResults.get(filePath);
292
- if (!transformResult) {
293
- transformResult = await onTransform(removeStartsWith(url, FILE_PROTOCOL)).catch(() => undefined);
294
- }
185
+ async getSources(url, onTransform, functions = []) {
186
+ const transformResult = await onTransform(removeStartsWith(url, FILE_PROTOCOL)).catch(() => undefined);
295
187
  const map = transformResult?.map;
296
188
  const code = transformResult?.code;
297
189
  if (code == null) {
190
+ const filePath = normalize(fileURLToPath(url));
298
191
  const original = await promises.readFile(filePath, "utf-8").catch(() => {
299
192
  // If file does not exist construct a dummy source for it.
300
193
  // These can be files that were generated dynamically during the test run and were removed after it.
@@ -320,11 +213,6 @@ class V8CoverageProvider extends BaseCoverageProvider {
320
213
  if (environment === "__browser__" && !project.browser) {
321
214
  throw new Error(`Cannot access browser module graph because it was torn down.`);
322
215
  }
323
- const moduleGraph = environment === "__browser__" ? project.browser.vite.environments.client.moduleGraph : project.vite.environments[environment]?.moduleGraph;
324
- if (!moduleGraph) {
325
- throw new Error(`Module graph for environment ${environment} was not defined.`);
326
- }
327
- const transformResults = normalizeTransformResults({ [environment]: { moduleGraph } });
328
216
  async function onTransform(filepath) {
329
217
  if (environment === "__browser__" && project.browser) {
330
218
  const result = await project.browser.vite.transformRequest(removeStartsWith(filepath, project.config.root));
@@ -348,11 +236,11 @@ class V8CoverageProvider extends BaseCoverageProvider {
348
236
  result.url = `${FILE_PROTOCOL}${project.config.root}${result.url}`;
349
237
  }
350
238
  }
351
- // Ignore all CSS requests, so we don't override the actual code coverage
352
- // In cases where CSS and JS are in the same file (.vue, .svelte)
353
- // The file has a `.vue` extension, but the URL has `lang.css` query
354
- if (!isCSSRequest(result.url) && this.isIncluded(fileURLToPath(result.url))) {
355
- scriptCoverages.push(result);
239
+ if (this.isIncluded(fileURLToPath(result.url))) {
240
+ scriptCoverages.push({
241
+ ...result,
242
+ url: decodeURIComponent(result.url)
243
+ });
356
244
  }
357
245
  }
358
246
  const coverageMap = this.createCoverageMap();
@@ -369,7 +257,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
369
257
  start = performance.now();
370
258
  timeout = setTimeout(() => debug(c.bgRed(`File "${fileURLToPath(url)}" is taking longer than 3s`)), 3e3);
371
259
  }
372
- const sources = await this.getSources(url, transformResults, onTransform, functions);
260
+ const sources = await this.getSources(url, onTransform, functions);
373
261
  coverageMap.merge(await this.remapCoverage(url, startOffset, sources, functions));
374
262
  if (debug.enabled) {
375
263
  clearTimeout(timeout);
@@ -395,19 +283,6 @@ function findLongestFunctionLength(functions) {
395
283
  return Math.max(previous, maxEndOffset);
396
284
  }, 0);
397
285
  }
398
- function normalizeTransformResults(environments) {
399
- const normalized = new Map();
400
- for (const environmentName in environments) {
401
- const moduleGraph = environments[environmentName].moduleGraph;
402
- for (const [key, value] of moduleGraph.idToModuleMap) {
403
- const cleanEntry = cleanUrl(key);
404
- if (value.transformResult && !normalized.has(cleanEntry)) {
405
- normalized.set(cleanEntry, value.transformResult);
406
- }
407
- }
408
- }
409
- return normalized;
410
- }
411
286
  function removeStartsWith(filepath, start) {
412
287
  if (filepath.startsWith(start)) {
413
288
  return filepath.slice(start.length);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/coverage-v8",
3
3
  "type": "module",
4
- "version": "4.0.0-beta.7",
4
+ "version": "4.0.0-beta.9",
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": "4.0.0-beta.7",
45
- "vitest": "4.0.0-beta.7"
44
+ "@vitest/browser": "4.0.0-beta.9",
45
+ "vitest": "4.0.0-beta.9"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "@vitest/browser": {
@@ -60,7 +60,7 @@
60
60
  "magicast": "^0.3.5",
61
61
  "std-env": "^3.9.0",
62
62
  "tinyrainbow": "^2.0.0",
63
- "@vitest/utils": "4.0.0-beta.7"
63
+ "@vitest/utils": "4.0.0-beta.9"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/debug": "^4.1.12",
@@ -69,8 +69,8 @@
69
69
  "@types/istanbul-lib-source-maps": "^4.0.4",
70
70
  "@types/istanbul-reports": "^3.0.4",
71
71
  "pathe": "^2.0.3",
72
- "vitest": "4.0.0-beta.7",
73
- "@vitest/browser": "4.0.0-beta.7"
72
+ "@vitest/browser": "4.0.0-beta.9",
73
+ "vitest": "4.0.0-beta.9"
74
74
  },
75
75
  "scripts": {
76
76
  "build": "rimraf dist && rollup -c",