@vitest/coverage-v8 4.0.0-beta.8 → 4.0.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 +1 -1
- package/dist/index.js +2 -1
- package/dist/pathe.M-eThtNZ-BTaAGrLg.js +104 -0
- package/dist/provider.js +19 -139
- package/package.json +11 -11
package/dist/browser.js
CHANGED
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
|
|
14
|
+
import { parseAstAsync } from 'vitest/node';
|
|
15
|
+
import { n as normalize } from './pathe.M-eThtNZ-BTaAGrLg.js';
|
|
16
16
|
|
|
17
|
-
|
|
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.8";
|
|
17
|
+
var version = "4.0.0";
|
|
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;
|
|
@@ -216,8 +112,8 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
216
112
|
timeout = setTimeout(() => debug(c.bgRed(`File "${filename}" is taking longer than 3s`)), 3e3);
|
|
217
113
|
}
|
|
218
114
|
// Do not use pathToFileURL to avoid encoding filename parts
|
|
219
|
-
const url = `file://${filename
|
|
220
|
-
const sources = await this.getSources(url,
|
|
115
|
+
const url = `file://${filename[0] === "/" ? "" : "/"}${filename}`;
|
|
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);
|
|
@@ -260,6 +156,11 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
260
156
|
if (type === "statement" && node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.id.name === "__vite_ssr_export_default__") {
|
|
261
157
|
return true;
|
|
262
158
|
}
|
|
159
|
+
// CJS imports as ternaries - e.g.
|
|
160
|
+
// const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react;
|
|
161
|
+
if (type === "branch" && node.type === "ConditionalExpression" && node.test.type === "MemberExpression" && node.test.object.type === "Identifier" && node.test.object.name.startsWith("__vite__cjsImport") && node.test.property.type === "Identifier" && node.test.property.name === "__esModule") {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
263
164
|
// in-source test with "if (import.meta.vitest)"
|
|
264
165
|
if ((type === "branch" || type === "statement") && node.type === "IfStatement" && node.test.type === "MemberExpression" && node.test.property.type === "Identifier" && node.test.property.name === "vitest") {
|
|
265
166
|
// SSR
|
|
@@ -286,15 +187,12 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
286
187
|
}
|
|
287
188
|
});
|
|
288
189
|
}
|
|
289
|
-
async getSources(url,
|
|
290
|
-
const
|
|
291
|
-
let transformResult = transformResults.get(filePath);
|
|
292
|
-
if (!transformResult) {
|
|
293
|
-
transformResult = await onTransform(removeStartsWith(url, FILE_PROTOCOL)).catch(() => undefined);
|
|
294
|
-
}
|
|
190
|
+
async getSources(url, onTransform, functions = []) {
|
|
191
|
+
const transformResult = await onTransform(removeStartsWith(url, FILE_PROTOCOL)).catch(() => undefined);
|
|
295
192
|
const map = transformResult?.map;
|
|
296
193
|
const code = transformResult?.code;
|
|
297
194
|
if (code == null) {
|
|
195
|
+
const filePath = normalize(fileURLToPath(url));
|
|
298
196
|
const original = await promises.readFile(filePath, "utf-8").catch(() => {
|
|
299
197
|
// If file does not exist construct a dummy source for it.
|
|
300
198
|
// These can be files that were generated dynamically during the test run and were removed after it.
|
|
@@ -320,11 +218,6 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
320
218
|
if (environment === "__browser__" && !project.browser) {
|
|
321
219
|
throw new Error(`Cannot access browser module graph because it was torn down.`);
|
|
322
220
|
}
|
|
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
221
|
async function onTransform(filepath) {
|
|
329
222
|
if (environment === "__browser__" && project.browser) {
|
|
330
223
|
const result = await project.browser.vite.transformRequest(removeStartsWith(filepath, project.config.root));
|
|
@@ -348,11 +241,11 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
348
241
|
result.url = `${FILE_PROTOCOL}${project.config.root}${result.url}`;
|
|
349
242
|
}
|
|
350
243
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
244
|
+
if (this.isIncluded(fileURLToPath(result.url))) {
|
|
245
|
+
scriptCoverages.push({
|
|
246
|
+
...result,
|
|
247
|
+
url: decodeURIComponent(result.url)
|
|
248
|
+
});
|
|
356
249
|
}
|
|
357
250
|
}
|
|
358
251
|
const coverageMap = this.createCoverageMap();
|
|
@@ -369,7 +262,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
|
369
262
|
start = performance.now();
|
|
370
263
|
timeout = setTimeout(() => debug(c.bgRed(`File "${fileURLToPath(url)}" is taking longer than 3s`)), 3e3);
|
|
371
264
|
}
|
|
372
|
-
const sources = await this.getSources(url,
|
|
265
|
+
const sources = await this.getSources(url, onTransform, functions);
|
|
373
266
|
coverageMap.merge(await this.remapCoverage(url, startOffset, sources, functions));
|
|
374
267
|
if (debug.enabled) {
|
|
375
268
|
clearTimeout(timeout);
|
|
@@ -395,19 +288,6 @@ function findLongestFunctionLength(functions) {
|
|
|
395
288
|
return Math.max(previous, maxEndOffset);
|
|
396
289
|
}, 0);
|
|
397
290
|
}
|
|
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
291
|
function removeStartsWith(filepath, start) {
|
|
412
292
|
if (filepath.startsWith(start)) {
|
|
413
293
|
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
|
|
4
|
+
"version": "4.0.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": "4.0.0
|
|
45
|
-
"vitest": "4.0.0
|
|
44
|
+
"@vitest/browser": "4.0.0",
|
|
45
|
+
"vitest": "4.0.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@vitest/browser": {
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@bcoe/v8-coverage": "^1.0.2",
|
|
54
|
-
"ast-v8-to-istanbul": "^0.3.
|
|
55
|
-
"debug": "^4.4.
|
|
54
|
+
"ast-v8-to-istanbul": "^0.3.5",
|
|
55
|
+
"debug": "^4.4.3",
|
|
56
56
|
"istanbul-lib-coverage": "^3.2.2",
|
|
57
57
|
"istanbul-lib-report": "^3.0.1",
|
|
58
58
|
"istanbul-lib-source-maps": "^5.0.6",
|
|
59
|
-
"istanbul-reports": "^3.
|
|
59
|
+
"istanbul-reports": "^3.2.0",
|
|
60
60
|
"magicast": "^0.3.5",
|
|
61
61
|
"std-env": "^3.9.0",
|
|
62
|
-
"tinyrainbow": "^
|
|
63
|
-
"@vitest/utils": "4.0.0
|
|
62
|
+
"tinyrainbow": "^3.0.3",
|
|
63
|
+
"@vitest/utils": "4.0.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/debug": "^4.1.12",
|
|
@@ -69,11 +69,11 @@
|
|
|
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/browser": "4.0.0
|
|
73
|
-
"vitest": "4.0.0
|
|
72
|
+
"@vitest/browser": "4.0.0",
|
|
73
|
+
"vitest": "4.0.0"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
|
-
"build": "
|
|
76
|
+
"build": "premove dist && rollup -c",
|
|
77
77
|
"dev": "rollup -c --watch --watch.include 'src/**'"
|
|
78
78
|
}
|
|
79
79
|
}
|