@vitest/coverage-v8 2.0.0-beta.9 → 2.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/index.js +8 -4
- package/dist/provider.js +403 -259
- package/package.json +9 -9
package/dist/index.js
CHANGED
@@ -13,13 +13,15 @@ function startCoverage() {
|
|
13
13
|
async function takeCoverage() {
|
14
14
|
return new Promise((resolve, reject) => {
|
15
15
|
session.post("Profiler.takePreciseCoverage", async (error, coverage) => {
|
16
|
-
if (error)
|
16
|
+
if (error) {
|
17
17
|
return reject(error);
|
18
|
+
}
|
18
19
|
const result = coverage.result.filter(filterResult);
|
19
20
|
resolve({ result });
|
20
21
|
});
|
21
|
-
if (provider === "stackblitz")
|
22
|
+
if (provider === "stackblitz") {
|
22
23
|
resolve({ result: [] });
|
24
|
+
}
|
23
25
|
});
|
24
26
|
}
|
25
27
|
function stopCoverage() {
|
@@ -28,10 +30,12 @@ function stopCoverage() {
|
|
28
30
|
session.disconnect();
|
29
31
|
}
|
30
32
|
function filterResult(coverage) {
|
31
|
-
if (!coverage.url.startsWith("file://"))
|
33
|
+
if (!coverage.url.startsWith("file://")) {
|
32
34
|
return false;
|
33
|
-
|
35
|
+
}
|
36
|
+
if (coverage.url.includes("/node_modules/")) {
|
34
37
|
return false;
|
38
|
+
}
|
35
39
|
return true;
|
36
40
|
}
|
37
41
|
|
package/dist/provider.js
CHANGED
@@ -19,7 +19,7 @@ import { provider } from 'std-env';
|
|
19
19
|
import { stripLiteral } from 'strip-literal';
|
20
20
|
import createDebug from 'debug';
|
21
21
|
import { builtinModules } from 'node:module';
|
22
|
-
import { coverageConfigDefaults
|
22
|
+
import { coverageConfigDefaults } from 'vitest/config';
|
23
23
|
import { BaseCoverageProvider } from 'vitest/coverage';
|
24
24
|
import _TestExclude from 'test-exclude';
|
25
25
|
|
@@ -884,17 +884,13 @@ function requireTraceMapping_umd () {
|
|
884
884
|
(function (global, factory) {
|
885
885
|
factory(exports, requireSourcemapCodec_umd(), requireResolveUri_umd()) ;
|
886
886
|
})(commonjsGlobal, (function (exports, sourcemapCodec, resolveUri) {
|
887
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
888
|
-
|
889
|
-
var resolveUri__default = /*#__PURE__*/_interopDefaultLegacy(resolveUri);
|
890
|
-
|
891
887
|
function resolve(input, base) {
|
892
888
|
// The base is always treated as a directory, if it's not empty.
|
893
889
|
// https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327
|
894
890
|
// https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401
|
895
891
|
if (base && !base.endsWith('/'))
|
896
892
|
base += '/';
|
897
|
-
return
|
893
|
+
return resolveUri(input, base);
|
898
894
|
}
|
899
895
|
|
900
896
|
/**
|
@@ -1054,8 +1050,9 @@ function requireTraceMapping_umd () {
|
|
1054
1050
|
// segment should go. Either way, we want to insert after that. And there may be multiple
|
1055
1051
|
// generated segments associated with an original location, so there may need to move several
|
1056
1052
|
// indexes before we find where we need to insert.
|
1057
|
-
|
1058
|
-
|
1053
|
+
let index = upperBound(originalLine, sourceColumn, memoizedBinarySearch(originalLine, sourceColumn, memo, sourceLine));
|
1054
|
+
memo.lastIndex = ++index;
|
1055
|
+
insert(originalLine, index, [sourceColumn, i, seg[COLUMN]]);
|
1059
1056
|
}
|
1060
1057
|
}
|
1061
1058
|
return sources;
|
@@ -1076,14 +1073,16 @@ function requireTraceMapping_umd () {
|
|
1076
1073
|
}
|
1077
1074
|
|
1078
1075
|
const AnyMap = function (map, mapUrl) {
|
1079
|
-
const parsed =
|
1080
|
-
if (!('sections' in parsed))
|
1076
|
+
const parsed = parse(map);
|
1077
|
+
if (!('sections' in parsed)) {
|
1081
1078
|
return new TraceMap(parsed, mapUrl);
|
1079
|
+
}
|
1082
1080
|
const mappings = [];
|
1083
1081
|
const sources = [];
|
1084
1082
|
const sourcesContent = [];
|
1085
1083
|
const names = [];
|
1086
|
-
|
1084
|
+
const ignoreList = [];
|
1085
|
+
recurse(parsed, mapUrl, mappings, sources, sourcesContent, names, ignoreList, 0, 0, Infinity, Infinity);
|
1087
1086
|
const joined = {
|
1088
1087
|
version: 3,
|
1089
1088
|
file: parsed.file,
|
@@ -1091,10 +1090,14 @@ function requireTraceMapping_umd () {
|
|
1091
1090
|
sources,
|
1092
1091
|
sourcesContent,
|
1093
1092
|
mappings,
|
1093
|
+
ignoreList,
|
1094
1094
|
};
|
1095
|
-
return
|
1095
|
+
return presortedDecodedMap(joined);
|
1096
1096
|
};
|
1097
|
-
function
|
1097
|
+
function parse(map) {
|
1098
|
+
return typeof map === 'string' ? JSON.parse(map) : map;
|
1099
|
+
}
|
1100
|
+
function recurse(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) {
|
1098
1101
|
const { sections } = input;
|
1099
1102
|
for (let i = 0; i < sections.length; i++) {
|
1100
1103
|
const { map, offset } = sections[i];
|
@@ -1110,17 +1113,18 @@ function requireTraceMapping_umd () {
|
|
1110
1113
|
sc = columnOffset + nextOffset.column;
|
1111
1114
|
}
|
1112
1115
|
}
|
1113
|
-
addSection(map, mapUrl, mappings, sources, sourcesContent, names, lineOffset + offset.line, columnOffset + offset.column, sl, sc);
|
1116
|
+
addSection(map, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset + offset.line, columnOffset + offset.column, sl, sc);
|
1114
1117
|
}
|
1115
1118
|
}
|
1116
|
-
function addSection(input, mapUrl, mappings, sources, sourcesContent, names, lineOffset, columnOffset, stopLine, stopColumn) {
|
1117
|
-
|
1119
|
+
function addSection(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) {
|
1120
|
+
const parsed = parse(input);
|
1121
|
+
if ('sections' in parsed)
|
1118
1122
|
return recurse(...arguments);
|
1119
|
-
const map = new TraceMap(
|
1123
|
+
const map = new TraceMap(parsed, mapUrl);
|
1120
1124
|
const sourcesOffset = sources.length;
|
1121
1125
|
const namesOffset = names.length;
|
1122
|
-
const decoded =
|
1123
|
-
const { resolvedSources, sourcesContent: contents } = map;
|
1126
|
+
const decoded = decodedMappings(map);
|
1127
|
+
const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map;
|
1124
1128
|
append(sources, resolvedSources);
|
1125
1129
|
append(names, map.names);
|
1126
1130
|
if (contents)
|
@@ -1128,6 +1132,9 @@ function requireTraceMapping_umd () {
|
|
1128
1132
|
else
|
1129
1133
|
for (let i = 0; i < resolvedSources.length; i++)
|
1130
1134
|
sourcesContent.push(null);
|
1135
|
+
if (ignores)
|
1136
|
+
for (let i = 0; i < ignores.length; i++)
|
1137
|
+
ignoreList.push(ignores[i] + sourcesOffset);
|
1131
1138
|
for (let i = 0; i < decoded.length; i++) {
|
1132
1139
|
const lineI = lineOffset + i;
|
1133
1140
|
// We can only add so many lines before we step into the range that the next section's map
|
@@ -1177,208 +1184,198 @@ function requireTraceMapping_umd () {
|
|
1177
1184
|
const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)';
|
1178
1185
|
const LEAST_UPPER_BOUND = -1;
|
1179
1186
|
const GREATEST_LOWER_BOUND = 1;
|
1187
|
+
class TraceMap {
|
1188
|
+
constructor(map, mapUrl) {
|
1189
|
+
const isString = typeof map === 'string';
|
1190
|
+
if (!isString && map._decodedMemo)
|
1191
|
+
return map;
|
1192
|
+
const parsed = (isString ? JSON.parse(map) : map);
|
1193
|
+
const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
|
1194
|
+
this.version = version;
|
1195
|
+
this.file = file;
|
1196
|
+
this.names = names || [];
|
1197
|
+
this.sourceRoot = sourceRoot;
|
1198
|
+
this.sources = sources;
|
1199
|
+
this.sourcesContent = sourcesContent;
|
1200
|
+
this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || undefined;
|
1201
|
+
const from = resolve(sourceRoot || '', stripFilename(mapUrl));
|
1202
|
+
this.resolvedSources = sources.map((s) => resolve(s || '', from));
|
1203
|
+
const { mappings } = parsed;
|
1204
|
+
if (typeof mappings === 'string') {
|
1205
|
+
this._encoded = mappings;
|
1206
|
+
this._decoded = undefined;
|
1207
|
+
}
|
1208
|
+
else {
|
1209
|
+
this._encoded = undefined;
|
1210
|
+
this._decoded = maybeSort(mappings, isString);
|
1211
|
+
}
|
1212
|
+
this._decodedMemo = memoizedState();
|
1213
|
+
this._bySources = undefined;
|
1214
|
+
this._bySourceMemos = undefined;
|
1215
|
+
}
|
1216
|
+
}
|
1217
|
+
/**
|
1218
|
+
* Typescript doesn't allow friend access to private fields, so this just casts the map into a type
|
1219
|
+
* with public access modifiers.
|
1220
|
+
*/
|
1221
|
+
function cast(map) {
|
1222
|
+
return map;
|
1223
|
+
}
|
1180
1224
|
/**
|
1181
1225
|
* Returns the encoded (VLQ string) form of the SourceMap's mappings field.
|
1182
1226
|
*/
|
1183
|
-
|
1227
|
+
function encodedMappings(map) {
|
1228
|
+
var _a;
|
1229
|
+
var _b;
|
1230
|
+
return ((_a = (_b = cast(map))._encoded) !== null && _a !== void 0 ? _a : (_b._encoded = sourcemapCodec.encode(cast(map)._decoded)));
|
1231
|
+
}
|
1184
1232
|
/**
|
1185
1233
|
* Returns the decoded (array of lines of segments) form of the SourceMap's mappings field.
|
1186
1234
|
*/
|
1187
|
-
|
1235
|
+
function decodedMappings(map) {
|
1236
|
+
var _a;
|
1237
|
+
return ((_a = cast(map))._decoded || (_a._decoded = sourcemapCodec.decode(cast(map)._encoded)));
|
1238
|
+
}
|
1188
1239
|
/**
|
1189
1240
|
* A low-level API to find the segment associated with a generated line/column (think, from a
|
1190
1241
|
* stack trace). Line and column here are 0-based, unlike `originalPositionFor`.
|
1191
1242
|
*/
|
1192
|
-
|
1243
|
+
function traceSegment(map, line, column) {
|
1244
|
+
const decoded = decodedMappings(map);
|
1245
|
+
// It's common for parent source maps to have pointers to lines that have no
|
1246
|
+
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1247
|
+
if (line >= decoded.length)
|
1248
|
+
return null;
|
1249
|
+
const segments = decoded[line];
|
1250
|
+
const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, GREATEST_LOWER_BOUND);
|
1251
|
+
return index === -1 ? null : segments[index];
|
1252
|
+
}
|
1193
1253
|
/**
|
1194
1254
|
* A higher-level API to find the source/line/column associated with a generated line/column
|
1195
1255
|
* (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in
|
1196
1256
|
* `source-map` library.
|
1197
1257
|
*/
|
1198
|
-
|
1258
|
+
function originalPositionFor(map, needle) {
|
1259
|
+
let { line, column, bias } = needle;
|
1260
|
+
line--;
|
1261
|
+
if (line < 0)
|
1262
|
+
throw new Error(LINE_GTR_ZERO);
|
1263
|
+
if (column < 0)
|
1264
|
+
throw new Error(COL_GTR_EQ_ZERO);
|
1265
|
+
const decoded = decodedMappings(map);
|
1266
|
+
// It's common for parent source maps to have pointers to lines that have no
|
1267
|
+
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1268
|
+
if (line >= decoded.length)
|
1269
|
+
return OMapping(null, null, null, null);
|
1270
|
+
const segments = decoded[line];
|
1271
|
+
const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
|
1272
|
+
if (index === -1)
|
1273
|
+
return OMapping(null, null, null, null);
|
1274
|
+
const segment = segments[index];
|
1275
|
+
if (segment.length === 1)
|
1276
|
+
return OMapping(null, null, null, null);
|
1277
|
+
const { names, resolvedSources } = map;
|
1278
|
+
return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
|
1279
|
+
}
|
1199
1280
|
/**
|
1200
1281
|
* Finds the generated line/column position of the provided source/line/column source position.
|
1201
1282
|
*/
|
1202
|
-
|
1283
|
+
function generatedPositionFor(map, needle) {
|
1284
|
+
const { source, line, column, bias } = needle;
|
1285
|
+
return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false);
|
1286
|
+
}
|
1203
1287
|
/**
|
1204
1288
|
* Finds all generated line/column positions of the provided source/line/column source position.
|
1205
1289
|
*/
|
1206
|
-
|
1290
|
+
function allGeneratedPositionsFor(map, needle) {
|
1291
|
+
const { source, line, column, bias } = needle;
|
1292
|
+
// SourceMapConsumer uses LEAST_UPPER_BOUND for some reason, so we follow suit.
|
1293
|
+
return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true);
|
1294
|
+
}
|
1207
1295
|
/**
|
1208
1296
|
* Iterates each mapping in generated position order.
|
1209
1297
|
*/
|
1210
|
-
|
1298
|
+
function eachMapping(map, cb) {
|
1299
|
+
const decoded = decodedMappings(map);
|
1300
|
+
const { names, resolvedSources } = map;
|
1301
|
+
for (let i = 0; i < decoded.length; i++) {
|
1302
|
+
const line = decoded[i];
|
1303
|
+
for (let j = 0; j < line.length; j++) {
|
1304
|
+
const seg = line[j];
|
1305
|
+
const generatedLine = i + 1;
|
1306
|
+
const generatedColumn = seg[0];
|
1307
|
+
let source = null;
|
1308
|
+
let originalLine = null;
|
1309
|
+
let originalColumn = null;
|
1310
|
+
let name = null;
|
1311
|
+
if (seg.length !== 1) {
|
1312
|
+
source = resolvedSources[seg[1]];
|
1313
|
+
originalLine = seg[2] + 1;
|
1314
|
+
originalColumn = seg[3];
|
1315
|
+
}
|
1316
|
+
if (seg.length === 5)
|
1317
|
+
name = names[seg[4]];
|
1318
|
+
cb({
|
1319
|
+
generatedLine,
|
1320
|
+
generatedColumn,
|
1321
|
+
source,
|
1322
|
+
originalLine,
|
1323
|
+
originalColumn,
|
1324
|
+
name,
|
1325
|
+
});
|
1326
|
+
}
|
1327
|
+
}
|
1328
|
+
}
|
1329
|
+
function sourceIndex(map, source) {
|
1330
|
+
const { sources, resolvedSources } = map;
|
1331
|
+
let index = sources.indexOf(source);
|
1332
|
+
if (index === -1)
|
1333
|
+
index = resolvedSources.indexOf(source);
|
1334
|
+
return index;
|
1335
|
+
}
|
1211
1336
|
/**
|
1212
1337
|
* Retrieves the source content for a particular source, if its found. Returns null if not.
|
1213
1338
|
*/
|
1214
|
-
|
1339
|
+
function sourceContentFor(map, source) {
|
1340
|
+
const { sourcesContent } = map;
|
1341
|
+
if (sourcesContent == null)
|
1342
|
+
return null;
|
1343
|
+
const index = sourceIndex(map, source);
|
1344
|
+
return index === -1 ? null : sourcesContent[index];
|
1345
|
+
}
|
1346
|
+
/**
|
1347
|
+
* Determines if the source is marked to ignore by the source map.
|
1348
|
+
*/
|
1349
|
+
function isIgnored(map, source) {
|
1350
|
+
const { ignoreList } = map;
|
1351
|
+
if (ignoreList == null)
|
1352
|
+
return false;
|
1353
|
+
const index = sourceIndex(map, source);
|
1354
|
+
return index === -1 ? false : ignoreList.includes(index);
|
1355
|
+
}
|
1215
1356
|
/**
|
1216
1357
|
* A helper that skips sorting of the input map's mappings array, which can be expensive for larger
|
1217
1358
|
* maps.
|
1218
1359
|
*/
|
1219
|
-
|
1360
|
+
function presortedDecodedMap(map, mapUrl) {
|
1361
|
+
const tracer = new TraceMap(clone(map, []), mapUrl);
|
1362
|
+
cast(tracer)._decoded = map.mappings;
|
1363
|
+
return tracer;
|
1364
|
+
}
|
1220
1365
|
/**
|
1221
1366
|
* Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects
|
1222
1367
|
* a sourcemap, or to JSON.stringify.
|
1223
1368
|
*/
|
1224
|
-
|
1369
|
+
function decodedMap(map) {
|
1370
|
+
return clone(map, decodedMappings(map));
|
1371
|
+
}
|
1225
1372
|
/**
|
1226
1373
|
* Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects
|
1227
1374
|
* a sourcemap, or to JSON.stringify.
|
1228
1375
|
*/
|
1229
|
-
|
1230
|
-
|
1231
|
-
constructor(map, mapUrl) {
|
1232
|
-
const isString = typeof map === 'string';
|
1233
|
-
if (!isString && map._decodedMemo)
|
1234
|
-
return map;
|
1235
|
-
const parsed = (isString ? JSON.parse(map) : map);
|
1236
|
-
const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
|
1237
|
-
this.version = version;
|
1238
|
-
this.file = file;
|
1239
|
-
this.names = names || [];
|
1240
|
-
this.sourceRoot = sourceRoot;
|
1241
|
-
this.sources = sources;
|
1242
|
-
this.sourcesContent = sourcesContent;
|
1243
|
-
const from = resolve(sourceRoot || '', stripFilename(mapUrl));
|
1244
|
-
this.resolvedSources = sources.map((s) => resolve(s || '', from));
|
1245
|
-
const { mappings } = parsed;
|
1246
|
-
if (typeof mappings === 'string') {
|
1247
|
-
this._encoded = mappings;
|
1248
|
-
this._decoded = undefined;
|
1249
|
-
}
|
1250
|
-
else {
|
1251
|
-
this._encoded = undefined;
|
1252
|
-
this._decoded = maybeSort(mappings, isString);
|
1253
|
-
}
|
1254
|
-
this._decodedMemo = memoizedState();
|
1255
|
-
this._bySources = undefined;
|
1256
|
-
this._bySourceMemos = undefined;
|
1257
|
-
}
|
1376
|
+
function encodedMap(map) {
|
1377
|
+
return clone(map, encodedMappings(map));
|
1258
1378
|
}
|
1259
|
-
(() => {
|
1260
|
-
exports.encodedMappings = (map) => {
|
1261
|
-
var _a;
|
1262
|
-
return ((_a = map._encoded) !== null && _a !== void 0 ? _a : (map._encoded = sourcemapCodec.encode(map._decoded)));
|
1263
|
-
};
|
1264
|
-
exports.decodedMappings = (map) => {
|
1265
|
-
return (map._decoded || (map._decoded = sourcemapCodec.decode(map._encoded)));
|
1266
|
-
};
|
1267
|
-
exports.traceSegment = (map, line, column) => {
|
1268
|
-
const decoded = exports.decodedMappings(map);
|
1269
|
-
// It's common for parent source maps to have pointers to lines that have no
|
1270
|
-
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1271
|
-
if (line >= decoded.length)
|
1272
|
-
return null;
|
1273
|
-
const segments = decoded[line];
|
1274
|
-
const index = traceSegmentInternal(segments, map._decodedMemo, line, column, GREATEST_LOWER_BOUND);
|
1275
|
-
return index === -1 ? null : segments[index];
|
1276
|
-
};
|
1277
|
-
exports.originalPositionFor = (map, { line, column, bias }) => {
|
1278
|
-
line--;
|
1279
|
-
if (line < 0)
|
1280
|
-
throw new Error(LINE_GTR_ZERO);
|
1281
|
-
if (column < 0)
|
1282
|
-
throw new Error(COL_GTR_EQ_ZERO);
|
1283
|
-
const decoded = exports.decodedMappings(map);
|
1284
|
-
// It's common for parent source maps to have pointers to lines that have no
|
1285
|
-
// mapping (like a "//# sourceMappingURL=") at the end of the child file.
|
1286
|
-
if (line >= decoded.length)
|
1287
|
-
return OMapping(null, null, null, null);
|
1288
|
-
const segments = decoded[line];
|
1289
|
-
const index = traceSegmentInternal(segments, map._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
|
1290
|
-
if (index === -1)
|
1291
|
-
return OMapping(null, null, null, null);
|
1292
|
-
const segment = segments[index];
|
1293
|
-
if (segment.length === 1)
|
1294
|
-
return OMapping(null, null, null, null);
|
1295
|
-
const { names, resolvedSources } = map;
|
1296
|
-
return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
|
1297
|
-
};
|
1298
|
-
exports.allGeneratedPositionsFor = (map, { source, line, column, bias }) => {
|
1299
|
-
// SourceMapConsumer uses LEAST_UPPER_BOUND for some reason, so we follow suit.
|
1300
|
-
return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true);
|
1301
|
-
};
|
1302
|
-
exports.generatedPositionFor = (map, { source, line, column, bias }) => {
|
1303
|
-
return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false);
|
1304
|
-
};
|
1305
|
-
exports.eachMapping = (map, cb) => {
|
1306
|
-
const decoded = exports.decodedMappings(map);
|
1307
|
-
const { names, resolvedSources } = map;
|
1308
|
-
for (let i = 0; i < decoded.length; i++) {
|
1309
|
-
const line = decoded[i];
|
1310
|
-
for (let j = 0; j < line.length; j++) {
|
1311
|
-
const seg = line[j];
|
1312
|
-
const generatedLine = i + 1;
|
1313
|
-
const generatedColumn = seg[0];
|
1314
|
-
let source = null;
|
1315
|
-
let originalLine = null;
|
1316
|
-
let originalColumn = null;
|
1317
|
-
let name = null;
|
1318
|
-
if (seg.length !== 1) {
|
1319
|
-
source = resolvedSources[seg[1]];
|
1320
|
-
originalLine = seg[2] + 1;
|
1321
|
-
originalColumn = seg[3];
|
1322
|
-
}
|
1323
|
-
if (seg.length === 5)
|
1324
|
-
name = names[seg[4]];
|
1325
|
-
cb({
|
1326
|
-
generatedLine,
|
1327
|
-
generatedColumn,
|
1328
|
-
source,
|
1329
|
-
originalLine,
|
1330
|
-
originalColumn,
|
1331
|
-
name,
|
1332
|
-
});
|
1333
|
-
}
|
1334
|
-
}
|
1335
|
-
};
|
1336
|
-
exports.sourceContentFor = (map, source) => {
|
1337
|
-
const { sources, resolvedSources, sourcesContent } = map;
|
1338
|
-
if (sourcesContent == null)
|
1339
|
-
return null;
|
1340
|
-
let index = sources.indexOf(source);
|
1341
|
-
if (index === -1)
|
1342
|
-
index = resolvedSources.indexOf(source);
|
1343
|
-
return index === -1 ? null : sourcesContent[index];
|
1344
|
-
};
|
1345
|
-
exports.presortedDecodedMap = (map, mapUrl) => {
|
1346
|
-
const tracer = new TraceMap(clone(map, []), mapUrl);
|
1347
|
-
tracer._decoded = map.mappings;
|
1348
|
-
return tracer;
|
1349
|
-
};
|
1350
|
-
exports.decodedMap = (map) => {
|
1351
|
-
return clone(map, exports.decodedMappings(map));
|
1352
|
-
};
|
1353
|
-
exports.encodedMap = (map) => {
|
1354
|
-
return clone(map, exports.encodedMappings(map));
|
1355
|
-
};
|
1356
|
-
function generatedPosition(map, source, line, column, bias, all) {
|
1357
|
-
line--;
|
1358
|
-
if (line < 0)
|
1359
|
-
throw new Error(LINE_GTR_ZERO);
|
1360
|
-
if (column < 0)
|
1361
|
-
throw new Error(COL_GTR_EQ_ZERO);
|
1362
|
-
const { sources, resolvedSources } = map;
|
1363
|
-
let sourceIndex = sources.indexOf(source);
|
1364
|
-
if (sourceIndex === -1)
|
1365
|
-
sourceIndex = resolvedSources.indexOf(source);
|
1366
|
-
if (sourceIndex === -1)
|
1367
|
-
return all ? [] : GMapping(null, null);
|
1368
|
-
const generated = (map._bySources || (map._bySources = buildBySources(exports.decodedMappings(map), (map._bySourceMemos = sources.map(memoizedState)))));
|
1369
|
-
const segments = generated[sourceIndex][line];
|
1370
|
-
if (segments == null)
|
1371
|
-
return all ? [] : GMapping(null, null);
|
1372
|
-
const memo = map._bySourceMemos[sourceIndex];
|
1373
|
-
if (all)
|
1374
|
-
return sliceGeneratedPositions(segments, memo, line, column, bias);
|
1375
|
-
const index = traceSegmentInternal(segments, memo, line, column, bias);
|
1376
|
-
if (index === -1)
|
1377
|
-
return GMapping(null, null);
|
1378
|
-
const segment = segments[index];
|
1379
|
-
return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]);
|
1380
|
-
}
|
1381
|
-
})();
|
1382
1379
|
function clone(map, mappings) {
|
1383
1380
|
return {
|
1384
1381
|
version: map.version,
|
@@ -1388,6 +1385,7 @@ function requireTraceMapping_umd () {
|
|
1388
1385
|
sources: map.sources,
|
1389
1386
|
sourcesContent: map.sourcesContent,
|
1390
1387
|
mappings,
|
1388
|
+
ignoreList: map.ignoreList || map.x_google_ignoreList,
|
1391
1389
|
};
|
1392
1390
|
}
|
1393
1391
|
function OMapping(source, line, column, name) {
|
@@ -1434,13 +1432,49 @@ function requireTraceMapping_umd () {
|
|
1434
1432
|
}
|
1435
1433
|
return result;
|
1436
1434
|
}
|
1435
|
+
function generatedPosition(map, source, line, column, bias, all) {
|
1436
|
+
var _a;
|
1437
|
+
line--;
|
1438
|
+
if (line < 0)
|
1439
|
+
throw new Error(LINE_GTR_ZERO);
|
1440
|
+
if (column < 0)
|
1441
|
+
throw new Error(COL_GTR_EQ_ZERO);
|
1442
|
+
const { sources, resolvedSources } = map;
|
1443
|
+
let sourceIndex = sources.indexOf(source);
|
1444
|
+
if (sourceIndex === -1)
|
1445
|
+
sourceIndex = resolvedSources.indexOf(source);
|
1446
|
+
if (sourceIndex === -1)
|
1447
|
+
return all ? [] : GMapping(null, null);
|
1448
|
+
const generated = ((_a = cast(map))._bySources || (_a._bySources = buildBySources(decodedMappings(map), (cast(map)._bySourceMemos = sources.map(memoizedState)))));
|
1449
|
+
const segments = generated[sourceIndex][line];
|
1450
|
+
if (segments == null)
|
1451
|
+
return all ? [] : GMapping(null, null);
|
1452
|
+
const memo = cast(map)._bySourceMemos[sourceIndex];
|
1453
|
+
if (all)
|
1454
|
+
return sliceGeneratedPositions(segments, memo, line, column, bias);
|
1455
|
+
const index = traceSegmentInternal(segments, memo, line, column, bias);
|
1456
|
+
if (index === -1)
|
1457
|
+
return GMapping(null, null);
|
1458
|
+
const segment = segments[index];
|
1459
|
+
return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]);
|
1460
|
+
}
|
1437
1461
|
|
1438
1462
|
exports.AnyMap = AnyMap;
|
1439
1463
|
exports.GREATEST_LOWER_BOUND = GREATEST_LOWER_BOUND;
|
1440
1464
|
exports.LEAST_UPPER_BOUND = LEAST_UPPER_BOUND;
|
1441
1465
|
exports.TraceMap = TraceMap;
|
1442
|
-
|
1443
|
-
|
1466
|
+
exports.allGeneratedPositionsFor = allGeneratedPositionsFor;
|
1467
|
+
exports.decodedMap = decodedMap;
|
1468
|
+
exports.decodedMappings = decodedMappings;
|
1469
|
+
exports.eachMapping = eachMapping;
|
1470
|
+
exports.encodedMap = encodedMap;
|
1471
|
+
exports.encodedMappings = encodedMappings;
|
1472
|
+
exports.generatedPositionFor = generatedPositionFor;
|
1473
|
+
exports.isIgnored = isIgnored;
|
1474
|
+
exports.originalPositionFor = originalPositionFor;
|
1475
|
+
exports.presortedDecodedMap = presortedDecodedMap;
|
1476
|
+
exports.sourceContentFor = sourceContentFor;
|
1477
|
+
exports.traceSegment = traceSegment;
|
1444
1478
|
|
1445
1479
|
}));
|
1446
1480
|
|
@@ -1517,17 +1551,17 @@ function requireSource () {
|
|
1517
1551
|
* @return {{count?: number, start?: boolean, stop?: boolean}|undefined}
|
1518
1552
|
*/
|
1519
1553
|
_parseIgnore (lineStr) {
|
1520
|
-
const testIgnoreNextLines = lineStr.match(/^\W*\/\* [
|
1554
|
+
const testIgnoreNextLines = lineStr.match(/^\W*\/\* (?:[cv]8|node:coverage) ignore next (?<count>[0-9]+)/);
|
1521
1555
|
if (testIgnoreNextLines) {
|
1522
1556
|
return { count: Number(testIgnoreNextLines.groups.count) }
|
1523
1557
|
}
|
1524
1558
|
|
1525
1559
|
// Check if comment is on its own line.
|
1526
|
-
if (lineStr.match(/^\W*\/\* [
|
1560
|
+
if (lineStr.match(/^\W*\/\* (?:[cv]8|node:coverage) ignore next/)) {
|
1527
1561
|
return { count: 1 }
|
1528
1562
|
}
|
1529
1563
|
|
1530
|
-
if (lineStr.match(/\/\* [
|
1564
|
+
if (lineStr.match(/\/\* ([cv]8|node:coverage) ignore next/)) {
|
1531
1565
|
// Won't ignore successive lines, but the current line will be ignored.
|
1532
1566
|
return { count: 0 }
|
1533
1567
|
}
|
@@ -1537,6 +1571,12 @@ function requireSource () {
|
|
1537
1571
|
if (testIgnoreStartStop.groups.mode === 'start') return { start: true }
|
1538
1572
|
if (testIgnoreStartStop.groups.mode === 'stop') return { stop: true }
|
1539
1573
|
}
|
1574
|
+
|
1575
|
+
const testNodeIgnoreStartStop = lineStr.match(/\/\* node:coverage (?<mode>enable|disable)/);
|
1576
|
+
if (testNodeIgnoreStartStop) {
|
1577
|
+
if (testNodeIgnoreStartStop.groups.mode === 'disable') return { start: true }
|
1578
|
+
if (testNodeIgnoreStartStop.groups.mode === 'enable') return { stop: true }
|
1579
|
+
}
|
1540
1580
|
}
|
1541
1581
|
|
1542
1582
|
// given a start column and end column in absolute offsets within
|
@@ -1712,12 +1752,14 @@ function requireSource () {
|
|
1712
1752
|
// Not required since Node 12, see: https://github.com/nodejs/node/pull/27375
|
1713
1753
|
const isPreNode12 = /^v1[0-1]\./u.test(process.version);
|
1714
1754
|
function getShebangLength (source) {
|
1755
|
+
/* c8 ignore start - platform-specific */
|
1715
1756
|
if (isPreNode12 && source.indexOf('#!') === 0) {
|
1716
1757
|
const match = source.match(/(?<shebang>#!.*)/);
|
1717
1758
|
if (match) {
|
1718
1759
|
return match.groups.shebang.length
|
1719
1760
|
}
|
1720
1761
|
} else {
|
1762
|
+
/* c8 ignore stop - platform-specific */
|
1721
1763
|
return 0
|
1722
1764
|
}
|
1723
1765
|
}
|
@@ -2230,8 +2272,13 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2230
2272
|
...config,
|
2231
2273
|
// Resolved fields
|
2232
2274
|
provider: "v8",
|
2233
|
-
reporter: this.resolveReporters(
|
2234
|
-
|
2275
|
+
reporter: this.resolveReporters(
|
2276
|
+
config.reporter || coverageConfigDefaults.reporter
|
2277
|
+
),
|
2278
|
+
reportsDirectory: resolve(
|
2279
|
+
ctx.config.root,
|
2280
|
+
config.reportsDirectory || coverageConfigDefaults.reportsDirectory
|
2281
|
+
),
|
2235
2282
|
thresholds: config.thresholds && {
|
2236
2283
|
...config.thresholds,
|
2237
2284
|
lines: config.thresholds["100"] ? 100 : config.thresholds.lines,
|
@@ -2242,24 +2289,37 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2242
2289
|
};
|
2243
2290
|
this.testExclude = new _TestExclude({
|
2244
2291
|
cwd: ctx.config.root,
|
2245
|
-
include:
|
2246
|
-
exclude:
|
2292
|
+
include: this.options.include,
|
2293
|
+
exclude: this.options.exclude,
|
2247
2294
|
excludeNodeModules: true,
|
2248
2295
|
extension: this.options.extension,
|
2249
2296
|
relativePath: !this.options.allowExternal
|
2250
2297
|
});
|
2251
2298
|
const shard = this.ctx.config.shard;
|
2252
2299
|
const tempDirectory = `.tmp${shard ? `-${shard.index}-${shard.count}` : ""}`;
|
2253
|
-
this.coverageFilesDirectory = resolve(
|
2300
|
+
this.coverageFilesDirectory = resolve(
|
2301
|
+
this.options.reportsDirectory,
|
2302
|
+
tempDirectory
|
2303
|
+
);
|
2254
2304
|
}
|
2255
2305
|
resolveOptions() {
|
2256
2306
|
return this.options;
|
2257
2307
|
}
|
2258
2308
|
async clean(clean = true) {
|
2259
|
-
if (clean && existsSync(this.options.reportsDirectory))
|
2260
|
-
await promises$1.rm(this.options.reportsDirectory, {
|
2261
|
-
|
2262
|
-
|
2309
|
+
if (clean && existsSync(this.options.reportsDirectory)) {
|
2310
|
+
await promises$1.rm(this.options.reportsDirectory, {
|
2311
|
+
recursive: true,
|
2312
|
+
force: true,
|
2313
|
+
maxRetries: 10
|
2314
|
+
});
|
2315
|
+
}
|
2316
|
+
if (existsSync(this.coverageFilesDirectory)) {
|
2317
|
+
await promises$1.rm(this.coverageFilesDirectory, {
|
2318
|
+
recursive: true,
|
2319
|
+
force: true,
|
2320
|
+
maxRetries: 10
|
2321
|
+
});
|
2322
|
+
}
|
2263
2323
|
await promises$1.mkdir(this.coverageFilesDirectory, { recursive: true });
|
2264
2324
|
this.coverageFiles = /* @__PURE__ */ new Map();
|
2265
2325
|
this.pendingPromises = [];
|
@@ -2270,14 +2330,18 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2270
2330
|
* backwards compatibility is a breaking change.
|
2271
2331
|
*/
|
2272
2332
|
onAfterSuiteRun({ coverage, transformMode, projectName }) {
|
2273
|
-
if (transformMode !== "web" && transformMode !== "ssr")
|
2333
|
+
if (transformMode !== "web" && transformMode !== "ssr") {
|
2274
2334
|
throw new Error(`Invalid transform mode: ${transformMode}`);
|
2335
|
+
}
|
2275
2336
|
let entry = this.coverageFiles.get(projectName || DEFAULT_PROJECT);
|
2276
2337
|
if (!entry) {
|
2277
2338
|
entry = { web: [], ssr: [] };
|
2278
2339
|
this.coverageFiles.set(projectName || DEFAULT_PROJECT, entry);
|
2279
2340
|
}
|
2280
|
-
const filename = resolve(
|
2341
|
+
const filename = resolve(
|
2342
|
+
this.coverageFilesDirectory,
|
2343
|
+
`coverage-${uniqueId++}.json`
|
2344
|
+
);
|
2281
2345
|
entry[transformMode].push(filename);
|
2282
2346
|
const promise = promises$1.writeFile(filename, JSON.stringify(coverage), "utf-8");
|
2283
2347
|
this.pendingPromises.push(promise);
|
@@ -2288,21 +2352,35 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2288
2352
|
const total = this.pendingPromises.length;
|
2289
2353
|
await Promise.all(this.pendingPromises);
|
2290
2354
|
this.pendingPromises = [];
|
2291
|
-
for (const [
|
2292
|
-
|
2355
|
+
for (const [
|
2356
|
+
projectName,
|
2357
|
+
coveragePerProject
|
2358
|
+
] of this.coverageFiles.entries()) {
|
2359
|
+
for (const [transformMode, filenames] of Object.entries(
|
2360
|
+
coveragePerProject
|
2361
|
+
)) {
|
2293
2362
|
let merged = { result: [] };
|
2294
|
-
for (const chunk of this.toSlices(
|
2363
|
+
for (const chunk of this.toSlices(
|
2364
|
+
filenames,
|
2365
|
+
this.options.processingConcurrency
|
2366
|
+
)) {
|
2295
2367
|
if (debug.enabled) {
|
2296
2368
|
index += chunk.length;
|
2297
2369
|
debug("Covered files %d/%d", index, total);
|
2298
2370
|
}
|
2299
|
-
await Promise.all(
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2371
|
+
await Promise.all(
|
2372
|
+
chunk.map(async (filename) => {
|
2373
|
+
const contents = await promises$1.readFile(filename, "utf-8");
|
2374
|
+
const coverage = JSON.parse(contents);
|
2375
|
+
merged = mergeProcessCovs([merged, coverage]);
|
2376
|
+
})
|
2377
|
+
);
|
2304
2378
|
}
|
2305
|
-
const converted = await this.convertCoverage(
|
2379
|
+
const converted = await this.convertCoverage(
|
2380
|
+
merged,
|
2381
|
+
projectName,
|
2382
|
+
transformMode
|
2383
|
+
);
|
2306
2384
|
const transformedCoverage = await transformCoverage(converted);
|
2307
2385
|
coverageMap.merge(transformedCoverage);
|
2308
2386
|
}
|
@@ -2316,8 +2394,13 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2316
2394
|
return coverageMap;
|
2317
2395
|
}
|
2318
2396
|
async reportCoverage(coverageMap, { allTestsRun }) {
|
2319
|
-
if (provider === "stackblitz")
|
2320
|
-
this.ctx.logger.log(
|
2397
|
+
if (provider === "stackblitz") {
|
2398
|
+
this.ctx.logger.log(
|
2399
|
+
c.blue(" % ") + c.yellow(
|
2400
|
+
"@vitest/coverage-v8 does not work on Stackblitz. Report will be empty."
|
2401
|
+
)
|
2402
|
+
);
|
2403
|
+
}
|
2321
2404
|
await this.generateReports(
|
2322
2405
|
coverageMap || libCoverage.createCoverageMap({}),
|
2323
2406
|
allTestsRun
|
@@ -2326,8 +2409,9 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2326
2409
|
if (!keepResults) {
|
2327
2410
|
this.coverageFiles = /* @__PURE__ */ new Map();
|
2328
2411
|
await promises$1.rm(this.coverageFilesDirectory, { recursive: true });
|
2329
|
-
if (readdirSync(this.options.reportsDirectory).length === 0)
|
2412
|
+
if (readdirSync(this.options.reportsDirectory).length === 0) {
|
2330
2413
|
await promises$1.rm(this.options.reportsDirectory, { recursive: true });
|
2414
|
+
}
|
2331
2415
|
}
|
2332
2416
|
}
|
2333
2417
|
async generateReports(coverageMap, allTestsRun) {
|
@@ -2336,8 +2420,11 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2336
2420
|
coverageMap,
|
2337
2421
|
watermarks: this.options.watermarks
|
2338
2422
|
});
|
2339
|
-
if (this.hasTerminalReporter(this.options.reporter))
|
2340
|
-
this.ctx.logger.log(
|
2423
|
+
if (this.hasTerminalReporter(this.options.reporter)) {
|
2424
|
+
this.ctx.logger.log(
|
2425
|
+
c.blue(" % ") + c.dim("Coverage report from ") + c.yellow(this.name)
|
2426
|
+
);
|
2427
|
+
}
|
2341
2428
|
for (const reporter of this.options.reporter) {
|
2342
2429
|
reports.create(reporter[0], {
|
2343
2430
|
skipFull: this.options.skipFull,
|
@@ -2354,66 +2441,99 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2354
2441
|
});
|
2355
2442
|
this.checkThresholds({
|
2356
2443
|
thresholds: resolvedThresholds,
|
2357
|
-
perFile: this.options.thresholds.perFile
|
2444
|
+
perFile: this.options.thresholds.perFile,
|
2445
|
+
onError: (error) => this.ctx.logger.error(error)
|
2358
2446
|
});
|
2359
2447
|
if (this.options.thresholds.autoUpdate && allTestsRun) {
|
2360
|
-
if (!this.ctx.server.config.configFile)
|
2361
|
-
throw new Error(
|
2448
|
+
if (!this.ctx.server.config.configFile) {
|
2449
|
+
throw new Error(
|
2450
|
+
'Missing configurationFile. The "coverage.thresholds.autoUpdate" can only be enabled when configuration file is used.'
|
2451
|
+
);
|
2452
|
+
}
|
2362
2453
|
const configFilePath = this.ctx.server.config.configFile;
|
2363
|
-
const configModule = parseModule(
|
2454
|
+
const configModule = parseModule(
|
2455
|
+
await promises$1.readFile(configFilePath, "utf8")
|
2456
|
+
);
|
2364
2457
|
this.updateThresholds({
|
2365
2458
|
thresholds: resolvedThresholds,
|
2366
2459
|
perFile: this.options.thresholds.perFile,
|
2367
2460
|
configurationFile: configModule,
|
2368
|
-
onUpdate: () => writeFileSync(
|
2461
|
+
onUpdate: () => writeFileSync(
|
2462
|
+
configFilePath,
|
2463
|
+
configModule.generate().code,
|
2464
|
+
"utf-8"
|
2465
|
+
)
|
2369
2466
|
});
|
2370
2467
|
}
|
2371
2468
|
}
|
2372
2469
|
}
|
2373
2470
|
async mergeReports(coverageMaps) {
|
2374
2471
|
const coverageMap = libCoverage.createCoverageMap({});
|
2375
|
-
for (const coverage of coverageMaps)
|
2472
|
+
for (const coverage of coverageMaps) {
|
2376
2473
|
coverageMap.merge(coverage);
|
2474
|
+
}
|
2377
2475
|
await this.generateReports(coverageMap, true);
|
2378
2476
|
}
|
2379
2477
|
async getUntestedFiles(testedFiles) {
|
2380
|
-
const transformResults = normalizeTransformResults(
|
2478
|
+
const transformResults = normalizeTransformResults(
|
2479
|
+
this.ctx.vitenode.fetchCache
|
2480
|
+
);
|
2381
2481
|
const allFiles = await this.testExclude.glob(this.ctx.config.root);
|
2382
|
-
let includedFiles = allFiles.map(
|
2383
|
-
|
2384
|
-
|
2482
|
+
let includedFiles = allFiles.map(
|
2483
|
+
(file) => resolve(this.ctx.config.root, file)
|
2484
|
+
);
|
2485
|
+
if (this.ctx.config.changed) {
|
2486
|
+
includedFiles = (this.ctx.config.related || []).filter(
|
2487
|
+
(file) => includedFiles.includes(file)
|
2488
|
+
);
|
2489
|
+
}
|
2385
2490
|
const uncoveredFiles = includedFiles.map((file) => pathToFileURL(file)).filter((file) => !testedFiles.includes(file.pathname));
|
2386
2491
|
let merged = { result: [] };
|
2387
2492
|
let index = 0;
|
2388
|
-
for (const chunk of this.toSlices(
|
2493
|
+
for (const chunk of this.toSlices(
|
2494
|
+
uncoveredFiles,
|
2495
|
+
this.options.processingConcurrency
|
2496
|
+
)) {
|
2389
2497
|
if (debug.enabled) {
|
2390
2498
|
index += chunk.length;
|
2391
2499
|
debug("Uncovered files %d/%d", index, uncoveredFiles.length);
|
2392
2500
|
}
|
2393
|
-
const coverages = await Promise.all(
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2397
|
-
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
|
2402
|
-
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
2409
|
-
|
2410
|
-
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2501
|
+
const coverages = await Promise.all(
|
2502
|
+
chunk.map(async (filename) => {
|
2503
|
+
const { originalSource, source } = await this.getSources(
|
2504
|
+
filename.href,
|
2505
|
+
transformResults
|
2506
|
+
);
|
2507
|
+
if (source && stripLiteral(source).trim() === "") {
|
2508
|
+
return null;
|
2509
|
+
}
|
2510
|
+
const coverage = {
|
2511
|
+
url: filename.href,
|
2512
|
+
scriptId: "0",
|
2513
|
+
// Create a made up function to mark whole file as uncovered. Note that this does not exist in source maps.
|
2514
|
+
functions: [
|
2515
|
+
{
|
2516
|
+
ranges: [
|
2517
|
+
{
|
2518
|
+
startOffset: 0,
|
2519
|
+
endOffset: originalSource.length,
|
2520
|
+
count: 0
|
2521
|
+
}
|
2522
|
+
],
|
2523
|
+
isBlockCoverage: true,
|
2524
|
+
// This is magical value that indicates an empty report: https://github.com/istanbuljs/v8-to-istanbul/blob/fca5e6a9e6ef38a9cdc3a178d5a6cf9ef82e6cab/lib/v8-to-istanbul.js#LL131C40-L131C40
|
2525
|
+
functionName: "(empty-report)"
|
2526
|
+
}
|
2527
|
+
]
|
2528
|
+
};
|
2529
|
+
return { result: [coverage] };
|
2530
|
+
})
|
2531
|
+
);
|
2414
2532
|
merged = mergeProcessCovs([
|
2415
2533
|
merged,
|
2416
|
-
...coverages.filter(
|
2534
|
+
...coverages.filter(
|
2535
|
+
(cov) => cov != null
|
2536
|
+
)
|
2417
2537
|
]);
|
2418
2538
|
}
|
2419
2539
|
return merged;
|
@@ -2440,8 +2560,9 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2440
2560
|
};
|
2441
2561
|
}
|
2442
2562
|
const sources = [url];
|
2443
|
-
if (map.sources && map.sources[0] && !url.endsWith(map.sources[0]))
|
2563
|
+
if (map.sources && map.sources[0] && !url.endsWith(map.sources[0])) {
|
2444
2564
|
sources[0] = new URL(map.sources[0], url).href;
|
2565
|
+
}
|
2445
2566
|
return {
|
2446
2567
|
isExecuted,
|
2447
2568
|
originalSource: sourcesContent,
|
@@ -2460,22 +2581,39 @@ class V8CoverageProvider extends BaseCoverageProvider {
|
|
2460
2581
|
const viteNode = this.ctx.projects.find((project) => project.getName() === projectName)?.vitenode || this.ctx.vitenode;
|
2461
2582
|
const fetchCache = transformMode ? viteNode.fetchCaches[transformMode] : viteNode.fetchCache;
|
2462
2583
|
const transformResults = normalizeTransformResults(fetchCache);
|
2463
|
-
const scriptCoverages = coverage.result.filter(
|
2584
|
+
const scriptCoverages = coverage.result.filter(
|
2585
|
+
(result) => this.testExclude.shouldInstrument(fileURLToPath$1(result.url))
|
2586
|
+
);
|
2464
2587
|
const coverageMap = libCoverage.createCoverageMap({});
|
2465
2588
|
let index = 0;
|
2466
|
-
for (const chunk of this.toSlices(
|
2589
|
+
for (const chunk of this.toSlices(
|
2590
|
+
scriptCoverages,
|
2591
|
+
this.options.processingConcurrency
|
2592
|
+
)) {
|
2467
2593
|
if (debug.enabled) {
|
2468
2594
|
index += chunk.length;
|
2469
2595
|
debug("Converting %d/%d", index, scriptCoverages.length);
|
2470
2596
|
}
|
2471
|
-
await Promise.all(
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2597
|
+
await Promise.all(
|
2598
|
+
chunk.map(async ({ url, functions }) => {
|
2599
|
+
const sources = await this.getSources(
|
2600
|
+
url,
|
2601
|
+
transformResults,
|
2602
|
+
functions
|
2603
|
+
);
|
2604
|
+
const wrapperLength = sources.isExecuted ? WRAPPER_LENGTH : 0;
|
2605
|
+
const converter = v8ToIstanbul$1(
|
2606
|
+
url,
|
2607
|
+
wrapperLength,
|
2608
|
+
sources,
|
2609
|
+
void 0,
|
2610
|
+
this.options.ignoreEmptyLines
|
2611
|
+
);
|
2612
|
+
await converter.load();
|
2613
|
+
converter.applyCoverage(functions);
|
2614
|
+
coverageMap.merge(converter.toIstanbul());
|
2615
|
+
})
|
2616
|
+
);
|
2479
2617
|
}
|
2480
2618
|
return coverageMap;
|
2481
2619
|
}
|
@@ -2485,10 +2623,12 @@ async function transformCoverage(coverageMap) {
|
|
2485
2623
|
return await sourceMapStore.transformCoverage(coverageMap);
|
2486
2624
|
}
|
2487
2625
|
function excludeGeneratedCode(source, map) {
|
2488
|
-
if (!source)
|
2626
|
+
if (!source) {
|
2489
2627
|
return map;
|
2490
|
-
|
2628
|
+
}
|
2629
|
+
if (!source.match(VITE_EXPORTS_LINE_PATTERN) && !source.match(DECORATOR_METADATA_PATTERN)) {
|
2491
2630
|
return map;
|
2631
|
+
}
|
2492
2632
|
const trimmed = new MagicString(source);
|
2493
2633
|
trimmed.replaceAll(VITE_EXPORTS_LINE_PATTERN, "\n");
|
2494
2634
|
trimmed.replaceAll(DECORATOR_METADATA_PATTERN, (match) => "\n".repeat(match.split("\n").length - 1));
|
@@ -2501,7 +2641,10 @@ function excludeGeneratedCode(source, map) {
|
|
2501
2641
|
}
|
2502
2642
|
function findLongestFunctionLength(functions) {
|
2503
2643
|
return functions.reduce((previous, current) => {
|
2504
|
-
const maxEndOffset = current.ranges.reduce(
|
2644
|
+
const maxEndOffset = current.ranges.reduce(
|
2645
|
+
(endOffset, range) => Math.max(endOffset, range.endOffset),
|
2646
|
+
0
|
2647
|
+
);
|
2505
2648
|
return Math.max(previous, maxEndOffset);
|
2506
2649
|
}, 0);
|
2507
2650
|
}
|
@@ -2509,8 +2652,9 @@ function normalizeTransformResults(fetchCache) {
|
|
2509
2652
|
const normalized = /* @__PURE__ */ new Map();
|
2510
2653
|
for (const [key, value] of fetchCache.entries()) {
|
2511
2654
|
const cleanEntry = cleanUrl(key);
|
2512
|
-
if (!normalized.has(cleanEntry))
|
2655
|
+
if (!normalized.has(cleanEntry)) {
|
2513
2656
|
normalized.set(cleanEntry, value.result);
|
2657
|
+
}
|
2514
2658
|
}
|
2515
2659
|
return normalized;
|
2516
2660
|
}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vitest/coverage-v8",
|
3
3
|
"type": "module",
|
4
|
-
"version": "2.0.0
|
4
|
+
"version": "2.0.0",
|
5
5
|
"description": "V8 coverage provider for Vitest",
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
7
7
|
"license": "MIT",
|
@@ -37,22 +37,22 @@
|
|
37
37
|
"dist"
|
38
38
|
],
|
39
39
|
"peerDependencies": {
|
40
|
-
"vitest": "2.0.0
|
40
|
+
"vitest": "2.0.0"
|
41
41
|
},
|
42
42
|
"dependencies": {
|
43
43
|
"@ampproject/remapping": "^2.3.0",
|
44
44
|
"@bcoe/v8-coverage": "^0.2.3",
|
45
|
-
"debug": "^4.3.
|
45
|
+
"debug": "^4.3.5",
|
46
46
|
"istanbul-lib-coverage": "^3.2.2",
|
47
47
|
"istanbul-lib-report": "^3.0.1",
|
48
|
-
"istanbul-lib-source-maps": "^5.0.
|
48
|
+
"istanbul-lib-source-maps": "^5.0.6",
|
49
49
|
"istanbul-reports": "^3.1.7",
|
50
50
|
"magic-string": "^0.30.10",
|
51
51
|
"magicast": "^0.3.4",
|
52
|
-
"picocolors": "^1.0.
|
52
|
+
"picocolors": "^1.0.1",
|
53
53
|
"std-env": "^3.7.0",
|
54
54
|
"strip-literal": "^2.1.0",
|
55
|
-
"test-exclude": "^
|
55
|
+
"test-exclude": "^7.0.1"
|
56
56
|
},
|
57
57
|
"devDependencies": {
|
58
58
|
"@types/debug": "^4.1.12",
|
@@ -61,9 +61,9 @@
|
|
61
61
|
"@types/istanbul-lib-source-maps": "^4.0.4",
|
62
62
|
"@types/istanbul-reports": "^3.0.4",
|
63
63
|
"pathe": "^1.1.2",
|
64
|
-
"v8-to-istanbul": "^9.
|
65
|
-
"vite-node": "2.0.0
|
66
|
-
"vitest": "2.0.0
|
64
|
+
"v8-to-istanbul": "^9.3.0",
|
65
|
+
"vite-node": "2.0.0",
|
66
|
+
"vitest": "2.0.0"
|
67
67
|
},
|
68
68
|
"scripts": {
|
69
69
|
"build": "rimraf dist && rollup -c",
|