@vitest/coverage-v8 1.3.0 → 1.4.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/LICENSE +1 -2
- package/dist/provider.js +43 -56
- package/package.json +6 -5
package/LICENSE
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2021-Present
|
4
|
-
Copyright (c) 2021-Present Matias Capeletto <https://github.com/patak-dev>
|
3
|
+
Copyright (c) 2021-Present Vitest Team
|
5
4
|
|
6
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/provider.js
CHANGED
@@ -11,6 +11,7 @@ import { parseModule } from 'magicast';
|
|
11
11
|
import remapping from '@ampproject/remapping';
|
12
12
|
import c from 'picocolors';
|
13
13
|
import { provider } from 'std-env';
|
14
|
+
import { stripLiteral } from 'strip-literal';
|
14
15
|
import createDebug from 'debug';
|
15
16
|
import { builtinModules } from 'node:module';
|
16
17
|
import { coverageConfigDefaults, defaultExclude, defaultInclude } from 'vitest/config';
|
@@ -170,6 +171,7 @@ function cleanUrl(url) {
|
|
170
171
|
|
171
172
|
const WRAPPER_LENGTH = 185;
|
172
173
|
const VITE_EXPORTS_LINE_PATTERN = /Object\.defineProperty\(__vite_ssr_exports__.*\n/g;
|
174
|
+
const DECORATOR_METADATA_PATTERN = /_ts_metadata\("design:paramtypes", \[[^\]]*?\]\),*/g;
|
173
175
|
const DEFAULT_PROJECT = Symbol.for("default-project");
|
174
176
|
const debug = createDebug("vitest:coverage");
|
175
177
|
let uniqueId = 0;
|
@@ -253,7 +255,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
253
255
|
for (const [projectName, coveragePerProject] of this.coverageFiles.entries()) {
|
254
256
|
for (const [transformMode, filenames] of Object.entries(coveragePerProject)) {
|
255
257
|
let merged = { result: [] };
|
256
|
-
for (const chunk of toSlices(filenames, this.options.processingConcurrency)) {
|
258
|
+
for (const chunk of this.toSlices(filenames, this.options.processingConcurrency)) {
|
257
259
|
if (debug.enabled) {
|
258
260
|
index += chunk.length;
|
259
261
|
debug("Covered files %d/%d", index, total);
|
@@ -280,7 +282,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
280
282
|
coverageMap,
|
281
283
|
watermarks: this.options.watermarks
|
282
284
|
});
|
283
|
-
if (hasTerminalReporter(this.options.reporter))
|
285
|
+
if (this.hasTerminalReporter(this.options.reporter))
|
284
286
|
this.ctx.logger.log(c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name));
|
285
287
|
for (const reporter of this.options.reporter) {
|
286
288
|
reports.create(reporter[0], {
|
@@ -307,10 +309,8 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
307
309
|
this.updateThresholds({
|
308
310
|
thresholds: resolvedThresholds,
|
309
311
|
perFile: this.options.thresholds.perFile,
|
310
|
-
configurationFile:
|
311
|
-
|
312
|
-
read: () => resolveConfig(configModule)
|
313
|
-
}
|
312
|
+
configurationFile: configModule,
|
313
|
+
onUpdate: () => writeFileSync(configFilePath, configModule.generate().code, "utf-8")
|
314
314
|
});
|
315
315
|
}
|
316
316
|
}
|
@@ -319,17 +319,24 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
319
319
|
}
|
320
320
|
async getUntestedFiles(testedFiles) {
|
321
321
|
const transformResults = normalizeTransformResults(this.ctx.vitenode.fetchCache);
|
322
|
-
const
|
323
|
-
|
322
|
+
const allFiles = await this.testExclude.glob(this.ctx.config.root);
|
323
|
+
let includedFiles = allFiles.map((file) => resolve(this.ctx.config.root, file));
|
324
|
+
if (this.ctx.config.changed)
|
325
|
+
includedFiles = (this.ctx.config.related || []).filter((file) => includedFiles.includes(file));
|
326
|
+
const uncoveredFiles = includedFiles.map((file) => pathToFileURL(file)).filter((file) => !testedFiles.includes(file.pathname));
|
324
327
|
let merged = { result: [] };
|
325
328
|
let index = 0;
|
326
|
-
for (const chunk of toSlices(uncoveredFiles, this.options.processingConcurrency)) {
|
329
|
+
for (const chunk of this.toSlices(uncoveredFiles, this.options.processingConcurrency)) {
|
327
330
|
if (debug.enabled) {
|
328
331
|
index += chunk.length;
|
329
332
|
debug("Uncovered files %d/%d", index, uncoveredFiles.length);
|
330
333
|
}
|
331
334
|
const coverages = await Promise.all(chunk.map(async (filename) => {
|
332
|
-
const
|
335
|
+
const transformResult = await this.ctx.vitenode.transformRequest(filename.pathname).catch(() => {
|
336
|
+
});
|
337
|
+
if (transformResult && stripLiteral(transformResult.code).trim() === "")
|
338
|
+
return null;
|
339
|
+
const { originalSource } = await this.getSources(filename.href, transformResults);
|
333
340
|
const coverage = {
|
334
341
|
url: filename.href,
|
335
342
|
scriptId: "0",
|
@@ -337,7 +344,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
337
344
|
functions: [{
|
338
345
|
ranges: [{
|
339
346
|
startOffset: 0,
|
340
|
-
endOffset:
|
347
|
+
endOffset: originalSource.length,
|
341
348
|
count: 0
|
342
349
|
}],
|
343
350
|
isBlockCoverage: true,
|
@@ -347,7 +354,10 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
347
354
|
};
|
348
355
|
return { result: [coverage] };
|
349
356
|
}));
|
350
|
-
merged = mergeProcessCovs([
|
357
|
+
merged = mergeProcessCovs([
|
358
|
+
merged,
|
359
|
+
...coverages.filter((cov) => cov != null)
|
360
|
+
]);
|
351
361
|
}
|
352
362
|
return merged;
|
353
363
|
}
|
@@ -360,16 +370,23 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
360
370
|
const length = findLongestFunctionLength(functions);
|
361
371
|
return ".".repeat(length);
|
362
372
|
});
|
363
|
-
if (!map)
|
364
|
-
return {
|
373
|
+
if (!map) {
|
374
|
+
return {
|
375
|
+
source: code || sourcesContent,
|
376
|
+
originalSource: sourcesContent
|
377
|
+
};
|
378
|
+
}
|
379
|
+
const sources = [url];
|
380
|
+
if (map.sources && map.sources[0] && !url.endsWith(map.sources[0]))
|
381
|
+
sources[0] = new URL(map.sources[0], url).href;
|
365
382
|
return {
|
366
383
|
originalSource: sourcesContent,
|
367
384
|
source: code || sourcesContent,
|
368
385
|
sourceMap: {
|
369
|
-
sourcemap:
|
386
|
+
sourcemap: excludeGeneratedCode(code, {
|
370
387
|
...map,
|
371
388
|
version: 3,
|
372
|
-
sources
|
389
|
+
sources,
|
373
390
|
sourcesContent: [sourcesContent]
|
374
391
|
})
|
375
392
|
}
|
@@ -382,7 +399,7 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
382
399
|
const scriptCoverages = coverage.result.filter((result) => this.testExclude.shouldInstrument(fileURLToPath(result.url)));
|
383
400
|
const coverageMap = libCoverage.createCoverageMap({});
|
384
401
|
let index = 0;
|
385
|
-
for (const chunk of toSlices(scriptCoverages, this.options.processingConcurrency)) {
|
402
|
+
for (const chunk of this.toSlices(scriptCoverages, this.options.processingConcurrency)) {
|
386
403
|
if (debug.enabled) {
|
387
404
|
index += chunk.length;
|
388
405
|
debug("Converting %d/%d", index, scriptCoverages.length);
|
@@ -403,16 +420,17 @@ async function transformCoverage(coverageMap) {
|
|
403
420
|
const sourceMapStore = libSourceMaps.createSourceMapStore();
|
404
421
|
return await sourceMapStore.transformCoverage(coverageMap);
|
405
422
|
}
|
406
|
-
function
|
407
|
-
if (!source
|
423
|
+
function excludeGeneratedCode(source, map) {
|
424
|
+
if (!source)
|
408
425
|
return map;
|
409
|
-
|
410
|
-
|
411
|
-
const
|
412
|
-
|
413
|
-
|
426
|
+
if (!source.match(VITE_EXPORTS_LINE_PATTERN) && !source.match(DECORATOR_METADATA_PATTERN))
|
427
|
+
return map;
|
428
|
+
const trimmed = new MagicString(source);
|
429
|
+
trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, "\n");
|
430
|
+
trimmed.replaceAll(DECORATOR_METADATA_PATTERN, (match) => "\n".repeat(match.split("\n").length - 1));
|
431
|
+
const trimmedMap = trimmed.generateMap({ hires: "boundary" });
|
414
432
|
const combinedMap = remapping(
|
415
|
-
[{ ...
|
433
|
+
[{ ...trimmedMap, version: 3 }, map],
|
416
434
|
() => null
|
417
435
|
);
|
418
436
|
return combinedMap;
|
@@ -432,36 +450,5 @@ function normalizeTransformResults(fetchCache) {
|
|
432
450
|
}
|
433
451
|
return normalized;
|
434
452
|
}
|
435
|
-
function hasTerminalReporter(reporters) {
|
436
|
-
return reporters.some(([reporter]) => reporter === "text" || reporter === "text-summary" || reporter === "text-lcov" || reporter === "teamcity");
|
437
|
-
}
|
438
|
-
function toSlices(array, size) {
|
439
|
-
return array.reduce((chunks, item) => {
|
440
|
-
const index = Math.max(0, chunks.length - 1);
|
441
|
-
const lastChunk = chunks[index] || [];
|
442
|
-
chunks[index] = lastChunk;
|
443
|
-
if (lastChunk.length >= size)
|
444
|
-
chunks.push([item]);
|
445
|
-
else
|
446
|
-
lastChunk.push(item);
|
447
|
-
return chunks;
|
448
|
-
}, []);
|
449
|
-
}
|
450
|
-
function resolveConfig(configModule) {
|
451
|
-
const mod = configModule.exports.default;
|
452
|
-
try {
|
453
|
-
if (mod.$type === "object")
|
454
|
-
return mod;
|
455
|
-
if (mod.$type === "function-call") {
|
456
|
-
if (mod.$args[0].$type === "object")
|
457
|
-
return mod.$args[0];
|
458
|
-
if (mod.$args[0].$type === "arrow-function-expression" && mod.$args[0].$body.$type === "object")
|
459
|
-
return mod.$args[0].$body;
|
460
|
-
}
|
461
|
-
} catch (error) {
|
462
|
-
throw new Error(error instanceof Error ? error.message : String(error));
|
463
|
-
}
|
464
|
-
throw new Error("Failed to update coverage thresholds. Configuration file is too complex.");
|
465
|
-
}
|
466
453
|
|
467
454
|
export { V8CoverageProvider };
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitest/coverage-v8",
|
3
3
|
"type": "module",
|
4
|
-
"version": "1.
|
4
|
+
"version": "1.4.0",
|
5
5
|
"description": "V8 coverage provider for Vitest",
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
7
7
|
"license": "MIT",
|
@@ -37,7 +37,7 @@
|
|
37
37
|
"dist"
|
38
38
|
],
|
39
39
|
"peerDependencies": {
|
40
|
-
"vitest": "1.
|
40
|
+
"vitest": "1.4.0"
|
41
41
|
},
|
42
42
|
"dependencies": {
|
43
43
|
"@ampproject/remapping": "^2.2.1",
|
@@ -45,12 +45,13 @@
|
|
45
45
|
"debug": "^4.3.4",
|
46
46
|
"istanbul-lib-coverage": "^3.2.2",
|
47
47
|
"istanbul-lib-report": "^3.0.1",
|
48
|
-
"istanbul-lib-source-maps": "^
|
48
|
+
"istanbul-lib-source-maps": "^5.0.4",
|
49
49
|
"istanbul-reports": "^3.1.6",
|
50
50
|
"magic-string": "^0.30.5",
|
51
51
|
"magicast": "^0.3.3",
|
52
52
|
"picocolors": "^1.0.0",
|
53
53
|
"std-env": "^3.5.0",
|
54
|
+
"strip-literal": "^2.0.0",
|
54
55
|
"test-exclude": "^6.0.0",
|
55
56
|
"v8-to-istanbul": "^9.2.0"
|
56
57
|
},
|
@@ -61,8 +62,8 @@
|
|
61
62
|
"@types/istanbul-lib-source-maps": "^4.0.4",
|
62
63
|
"@types/istanbul-reports": "^3.0.4",
|
63
64
|
"pathe": "^1.1.1",
|
64
|
-
"vite-node": "1.
|
65
|
-
"vitest": "1.
|
65
|
+
"vite-node": "1.4.0",
|
66
|
+
"vitest": "1.4.0"
|
66
67
|
},
|
67
68
|
"scripts": {
|
68
69
|
"build": "rimraf dist && rollup -c",
|