@jsenv/test 1.2.4 → 1.3.1
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/controllable_child_process.mjs +73 -66
- package/dist/controllable_worker_thread.mjs +62 -49
- package/dist/importmap_node_loader.mjs +286 -185
- package/dist/js/execute_using_dynamic_import.js +398 -283
- package/dist/js/v8_coverage.js +91 -98
- package/dist/jsenv_test.js +2605 -1904
- package/dist/no_experimental_warnings.cjs +4 -1
- package/package.json +5 -5
- package/src/coverage/empty_coverage_factory.js +1 -1
- package/src/execution/execute_steps.js +1 -1
- package/src/runtime_node/profiler_v8_coverage.js +1 -1
package/dist/js/v8_coverage.js
CHANGED
|
@@ -3,13 +3,18 @@ const assertUrlLike = (value, name = "url") => {
|
|
|
3
3
|
throw new TypeError(`${name} must be a url string, got ${value}`);
|
|
4
4
|
}
|
|
5
5
|
if (isWindowsPathnameSpecifier(value)) {
|
|
6
|
-
throw new TypeError(
|
|
6
|
+
throw new TypeError(
|
|
7
|
+
`${name} must be a url but looks like a windows pathname, got ${value}`,
|
|
8
|
+
);
|
|
7
9
|
}
|
|
8
10
|
if (!hasScheme(value)) {
|
|
9
|
-
throw new TypeError(
|
|
11
|
+
throw new TypeError(
|
|
12
|
+
`${name} must be a url and no scheme found, got ${value}`,
|
|
13
|
+
);
|
|
10
14
|
}
|
|
11
15
|
};
|
|
12
|
-
|
|
16
|
+
|
|
17
|
+
const isPlainObject = (value) => {
|
|
13
18
|
if (value === null) {
|
|
14
19
|
return false;
|
|
15
20
|
}
|
|
@@ -21,7 +26,8 @@ const isPlainObject = value => {
|
|
|
21
26
|
}
|
|
22
27
|
return false;
|
|
23
28
|
};
|
|
24
|
-
|
|
29
|
+
|
|
30
|
+
const isWindowsPathnameSpecifier = (specifier) => {
|
|
25
31
|
const firstChar = specifier[0];
|
|
26
32
|
if (!/[a-zA-Z]/.test(firstChar)) return false;
|
|
27
33
|
const secondChar = specifier[1];
|
|
@@ -29,16 +35,17 @@ const isWindowsPathnameSpecifier = specifier => {
|
|
|
29
35
|
const thirdChar = specifier[2];
|
|
30
36
|
return thirdChar === "/" || thirdChar === "\\";
|
|
31
37
|
};
|
|
32
|
-
|
|
38
|
+
|
|
39
|
+
const hasScheme = (specifier) => /^[a-zA-Z]+:/.test(specifier);
|
|
33
40
|
|
|
34
41
|
const resolveAssociations = (associations, baseUrl) => {
|
|
35
42
|
assertUrlLike(baseUrl, "baseUrl");
|
|
36
43
|
const associationsResolved = {};
|
|
37
|
-
Object.keys(associations).forEach(key => {
|
|
44
|
+
Object.keys(associations).forEach((key) => {
|
|
38
45
|
const value = associations[key];
|
|
39
46
|
if (typeof value === "object" && value !== null) {
|
|
40
47
|
const valueMapResolved = {};
|
|
41
|
-
Object.keys(value).forEach(pattern => {
|
|
48
|
+
Object.keys(value).forEach((pattern) => {
|
|
42
49
|
const valueAssociated = value[pattern];
|
|
43
50
|
const patternResolved = normalizeUrlPattern(pattern, baseUrl);
|
|
44
51
|
valueMapResolved[patternResolved] = valueAssociated;
|
|
@@ -50,6 +57,7 @@ const resolveAssociations = (associations, baseUrl) => {
|
|
|
50
57
|
});
|
|
51
58
|
return associationsResolved;
|
|
52
59
|
};
|
|
60
|
+
|
|
53
61
|
const normalizeUrlPattern = (urlPattern, baseUrl) => {
|
|
54
62
|
try {
|
|
55
63
|
return String(new URL(urlPattern, baseUrl));
|
|
@@ -59,25 +67,27 @@ const normalizeUrlPattern = (urlPattern, baseUrl) => {
|
|
|
59
67
|
}
|
|
60
68
|
};
|
|
61
69
|
|
|
62
|
-
const asFlatAssociations = associations => {
|
|
70
|
+
const asFlatAssociations = (associations) => {
|
|
63
71
|
if (!isPlainObject(associations)) {
|
|
64
|
-
throw new TypeError(
|
|
72
|
+
throw new TypeError(
|
|
73
|
+
`associations must be a plain object, got ${associations}`,
|
|
74
|
+
);
|
|
65
75
|
}
|
|
66
76
|
const flatAssociations = {};
|
|
67
|
-
Object.keys(associations).forEach(associationName => {
|
|
77
|
+
Object.keys(associations).forEach((associationName) => {
|
|
68
78
|
const associationValue = associations[associationName];
|
|
69
79
|
if (isPlainObject(associationValue)) {
|
|
70
|
-
Object.keys(associationValue).forEach(pattern => {
|
|
80
|
+
Object.keys(associationValue).forEach((pattern) => {
|
|
71
81
|
const patternValue = associationValue[pattern];
|
|
72
82
|
const previousValue = flatAssociations[pattern];
|
|
73
83
|
if (isPlainObject(previousValue)) {
|
|
74
84
|
flatAssociations[pattern] = {
|
|
75
85
|
...previousValue,
|
|
76
|
-
[associationName]: patternValue
|
|
86
|
+
[associationName]: patternValue,
|
|
77
87
|
};
|
|
78
88
|
} else {
|
|
79
89
|
flatAssociations[pattern] = {
|
|
80
|
-
[associationName]: patternValue
|
|
90
|
+
[associationName]: patternValue,
|
|
81
91
|
};
|
|
82
92
|
}
|
|
83
93
|
});
|
|
@@ -110,21 +120,13 @@ const asFlatAssociations = associations => {
|
|
|
110
120
|
* @param {string} applyPatternMatchingParams.url a string representing an url
|
|
111
121
|
* @return {MatchResult}
|
|
112
122
|
*/
|
|
113
|
-
const applyPatternMatching = ({
|
|
114
|
-
url,
|
|
115
|
-
pattern
|
|
116
|
-
}) => {
|
|
123
|
+
const applyPatternMatching = ({ url, pattern }) => {
|
|
117
124
|
assertUrlLike(pattern, "pattern");
|
|
118
125
|
assertUrlLike(url, "url");
|
|
119
|
-
const {
|
|
120
|
-
matched,
|
|
121
|
-
patternIndex,
|
|
122
|
-
index,
|
|
123
|
-
groups
|
|
124
|
-
} = applyMatching(pattern, url);
|
|
126
|
+
const { matched, patternIndex, index, groups } = applyMatching(pattern, url);
|
|
125
127
|
const matchGroups = [];
|
|
126
128
|
let groupIndex = 0;
|
|
127
|
-
groups.forEach(group => {
|
|
129
|
+
groups.forEach((group) => {
|
|
128
130
|
if (group.name) {
|
|
129
131
|
matchGroups[group.name] = group.string;
|
|
130
132
|
} else {
|
|
@@ -136,9 +138,10 @@ const applyPatternMatching = ({
|
|
|
136
138
|
matched,
|
|
137
139
|
patternIndex,
|
|
138
140
|
urlIndex: index,
|
|
139
|
-
matchGroups
|
|
141
|
+
matchGroups,
|
|
140
142
|
};
|
|
141
143
|
};
|
|
144
|
+
|
|
142
145
|
const applyMatching = (pattern, string) => {
|
|
143
146
|
const groups = [];
|
|
144
147
|
let patternIndex = 0;
|
|
@@ -146,13 +149,14 @@ const applyMatching = (pattern, string) => {
|
|
|
146
149
|
let remainingPattern = pattern;
|
|
147
150
|
let remainingString = string;
|
|
148
151
|
let restoreIndexes = true;
|
|
149
|
-
|
|
152
|
+
|
|
153
|
+
const consumePattern = (count) => {
|
|
150
154
|
const subpattern = remainingPattern.slice(0, count);
|
|
151
155
|
remainingPattern = remainingPattern.slice(count);
|
|
152
156
|
patternIndex += count;
|
|
153
157
|
return subpattern;
|
|
154
158
|
};
|
|
155
|
-
const consumeString = count => {
|
|
159
|
+
const consumeString = (count) => {
|
|
156
160
|
const substring = remainingString.slice(0, count);
|
|
157
161
|
remainingString = remainingString.slice(count);
|
|
158
162
|
index += count;
|
|
@@ -161,6 +165,7 @@ const applyMatching = (pattern, string) => {
|
|
|
161
165
|
const consumeRemainingString = () => {
|
|
162
166
|
return consumeString(remainingString.length);
|
|
163
167
|
};
|
|
168
|
+
|
|
164
169
|
let matched;
|
|
165
170
|
const iterate = () => {
|
|
166
171
|
const patternIndexBefore = patternIndex;
|
|
@@ -195,9 +200,7 @@ const applyMatching = (pattern, string) => {
|
|
|
195
200
|
return true;
|
|
196
201
|
}
|
|
197
202
|
if (remainingPattern === "*") {
|
|
198
|
-
groups.push({
|
|
199
|
-
string: ""
|
|
200
|
-
});
|
|
203
|
+
groups.push({ string: "" });
|
|
201
204
|
}
|
|
202
205
|
return false; // fail because string shorter than expected
|
|
203
206
|
}
|
|
@@ -207,9 +210,7 @@ const applyMatching = (pattern, string) => {
|
|
|
207
210
|
if (remainingString[0] === "/") {
|
|
208
211
|
// trailing slash match remaining
|
|
209
212
|
consumePattern(1);
|
|
210
|
-
groups.push({
|
|
211
|
-
string: consumeRemainingString()
|
|
212
|
-
});
|
|
213
|
+
groups.push({ string: consumeRemainingString() });
|
|
213
214
|
return true;
|
|
214
215
|
}
|
|
215
216
|
return false;
|
|
@@ -242,7 +243,7 @@ const applyMatching = (pattern, string) => {
|
|
|
242
243
|
const skipResult = skipUntilMatch({
|
|
243
244
|
pattern: remainingPattern,
|
|
244
245
|
string: remainingString,
|
|
245
|
-
canSkipSlash: true
|
|
246
|
+
canSkipSlash: true,
|
|
246
247
|
});
|
|
247
248
|
groups.push(...skipResult.groups);
|
|
248
249
|
consumePattern(skipResult.patternIndex);
|
|
@@ -257,29 +258,23 @@ const applyMatching = (pattern, string) => {
|
|
|
257
258
|
// matches everything except "/"
|
|
258
259
|
const slashIndex = remainingString.indexOf("/");
|
|
259
260
|
if (slashIndex === -1) {
|
|
260
|
-
groups.push({
|
|
261
|
-
string: consumeRemainingString()
|
|
262
|
-
});
|
|
261
|
+
groups.push({ string: consumeRemainingString() });
|
|
263
262
|
return true;
|
|
264
263
|
}
|
|
265
|
-
groups.push({
|
|
266
|
-
string: consumeString(slashIndex)
|
|
267
|
-
});
|
|
264
|
+
groups.push({ string: consumeString(slashIndex) });
|
|
268
265
|
return false;
|
|
269
266
|
}
|
|
270
267
|
// the next char must not the one expected by remainingPattern[0]
|
|
271
268
|
// because * is greedy and expect to skip at least one char
|
|
272
269
|
if (remainingPattern[0] === remainingString[0]) {
|
|
273
|
-
groups.push({
|
|
274
|
-
string: ""
|
|
275
|
-
});
|
|
270
|
+
groups.push({ string: "" });
|
|
276
271
|
patternIndex = patternIndex - 1;
|
|
277
272
|
return false;
|
|
278
273
|
}
|
|
279
274
|
const skipResult = skipUntilMatch({
|
|
280
275
|
pattern: remainingPattern,
|
|
281
276
|
string: remainingString,
|
|
282
|
-
canSkipSlash: false
|
|
277
|
+
canSkipSlash: false,
|
|
283
278
|
});
|
|
284
279
|
groups.push(skipResult.group, ...skipResult.groups);
|
|
285
280
|
consumePattern(skipResult.patternIndex);
|
|
@@ -293,22 +288,21 @@ const applyMatching = (pattern, string) => {
|
|
|
293
288
|
return undefined;
|
|
294
289
|
};
|
|
295
290
|
iterate();
|
|
291
|
+
|
|
296
292
|
return {
|
|
297
293
|
matched,
|
|
298
294
|
patternIndex,
|
|
299
295
|
index,
|
|
300
|
-
groups
|
|
296
|
+
groups,
|
|
301
297
|
};
|
|
302
298
|
};
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
string,
|
|
306
|
-
canSkipSlash
|
|
307
|
-
}) => {
|
|
299
|
+
|
|
300
|
+
const skipUntilMatch = ({ pattern, string, canSkipSlash }) => {
|
|
308
301
|
let index = 0;
|
|
309
302
|
let remainingString = string;
|
|
310
303
|
let longestAttemptRange = null;
|
|
311
304
|
let isLastAttempt = false;
|
|
305
|
+
|
|
312
306
|
const failure = () => {
|
|
313
307
|
return {
|
|
314
308
|
matched: false,
|
|
@@ -316,10 +310,11 @@ const skipUntilMatch = ({
|
|
|
316
310
|
index: longestAttemptRange.index + longestAttemptRange.length,
|
|
317
311
|
groups: longestAttemptRange.groups,
|
|
318
312
|
group: {
|
|
319
|
-
string: string.slice(0, longestAttemptRange.index)
|
|
320
|
-
}
|
|
313
|
+
string: string.slice(0, longestAttemptRange.index),
|
|
314
|
+
},
|
|
321
315
|
};
|
|
322
316
|
};
|
|
317
|
+
|
|
323
318
|
const tryToMatch = () => {
|
|
324
319
|
const matchAttempt = applyMatching(pattern, remainingString);
|
|
325
320
|
if (matchAttempt.matched) {
|
|
@@ -329,8 +324,11 @@ const skipUntilMatch = ({
|
|
|
329
324
|
index: index + matchAttempt.index,
|
|
330
325
|
groups: matchAttempt.groups,
|
|
331
326
|
group: {
|
|
332
|
-
string:
|
|
333
|
-
|
|
327
|
+
string:
|
|
328
|
+
remainingString === ""
|
|
329
|
+
? string
|
|
330
|
+
: string.slice(0, -remainingString.length),
|
|
331
|
+
},
|
|
334
332
|
};
|
|
335
333
|
}
|
|
336
334
|
const attemptIndex = matchAttempt.index;
|
|
@@ -338,9 +336,12 @@ const skipUntilMatch = ({
|
|
|
338
336
|
patternIndex: matchAttempt.patternIndex,
|
|
339
337
|
index,
|
|
340
338
|
length: attemptIndex,
|
|
341
|
-
groups: matchAttempt.groups
|
|
339
|
+
groups: matchAttempt.groups,
|
|
342
340
|
};
|
|
343
|
-
if (
|
|
341
|
+
if (
|
|
342
|
+
!longestAttemptRange ||
|
|
343
|
+
longestAttemptRange.length < attemptRange.length
|
|
344
|
+
) {
|
|
344
345
|
longestAttemptRange = attemptRange;
|
|
345
346
|
}
|
|
346
347
|
if (isLastAttempt) {
|
|
@@ -367,25 +368,20 @@ const skipUntilMatch = ({
|
|
|
367
368
|
return tryToMatch();
|
|
368
369
|
};
|
|
369
370
|
|
|
370
|
-
const applyAssociations = ({
|
|
371
|
-
url,
|
|
372
|
-
associations
|
|
373
|
-
}) => {
|
|
371
|
+
const applyAssociations = ({ url, associations }) => {
|
|
374
372
|
assertUrlLike(url);
|
|
375
373
|
const flatAssociations = asFlatAssociations(associations);
|
|
376
374
|
return Object.keys(flatAssociations).reduce((previousValue, pattern) => {
|
|
377
|
-
const {
|
|
378
|
-
matched
|
|
379
|
-
} = applyPatternMatching({
|
|
375
|
+
const { matched } = applyPatternMatching({
|
|
380
376
|
pattern,
|
|
381
|
-
url
|
|
377
|
+
url,
|
|
382
378
|
});
|
|
383
379
|
if (matched) {
|
|
384
380
|
const value = flatAssociations[pattern];
|
|
385
381
|
if (isPlainObject(previousValue) && isPlainObject(value)) {
|
|
386
382
|
return {
|
|
387
383
|
...previousValue,
|
|
388
|
-
...value
|
|
384
|
+
...value,
|
|
389
385
|
};
|
|
390
386
|
}
|
|
391
387
|
return value;
|
|
@@ -394,15 +390,12 @@ const applyAssociations = ({
|
|
|
394
390
|
}, {});
|
|
395
391
|
};
|
|
396
392
|
|
|
397
|
-
const applyAliases = ({
|
|
398
|
-
url,
|
|
399
|
-
aliases
|
|
400
|
-
}) => {
|
|
393
|
+
const applyAliases = ({ url, aliases }) => {
|
|
401
394
|
let aliasFullMatchResult;
|
|
402
|
-
const aliasMatchingKey = Object.keys(aliases).find(key => {
|
|
395
|
+
const aliasMatchingKey = Object.keys(aliases).find((key) => {
|
|
403
396
|
const aliasMatchResult = applyPatternMatching({
|
|
404
397
|
pattern: key,
|
|
405
|
-
url
|
|
398
|
+
url,
|
|
406
399
|
});
|
|
407
400
|
if (aliasMatchResult.matched) {
|
|
408
401
|
aliasFullMatchResult = aliasMatchResult;
|
|
@@ -413,22 +406,18 @@ const applyAliases = ({
|
|
|
413
406
|
if (!aliasMatchingKey) {
|
|
414
407
|
return url;
|
|
415
408
|
}
|
|
416
|
-
const {
|
|
417
|
-
matchGroups
|
|
418
|
-
} = aliasFullMatchResult;
|
|
409
|
+
const { matchGroups } = aliasFullMatchResult;
|
|
419
410
|
const alias = aliases[aliasMatchingKey];
|
|
420
411
|
const parts = alias.split("*");
|
|
421
412
|
const newUrl = parts.reduce((previous, value, index) => {
|
|
422
|
-
return `${previous}${value}${
|
|
413
|
+
return `${previous}${value}${
|
|
414
|
+
index === parts.length - 1 ? "" : matchGroups[index]
|
|
415
|
+
}`;
|
|
423
416
|
}, "");
|
|
424
417
|
return newUrl;
|
|
425
418
|
};
|
|
426
419
|
|
|
427
|
-
const urlChildMayMatch = ({
|
|
428
|
-
url,
|
|
429
|
-
associations,
|
|
430
|
-
predicate
|
|
431
|
-
}) => {
|
|
420
|
+
const urlChildMayMatch = ({ url, associations, predicate }) => {
|
|
432
421
|
assertUrlLike(url, "url");
|
|
433
422
|
// the function was meants to be used on url ending with '/'
|
|
434
423
|
if (!url.endsWith("/")) {
|
|
@@ -444,18 +433,18 @@ const urlChildMayMatch = ({
|
|
|
444
433
|
// for partial match, any meta satisfying predicate will be valid because
|
|
445
434
|
// we don't know for sure if pattern will still match for a file inside pathname
|
|
446
435
|
const partialMatchMetaArray = [];
|
|
447
|
-
Object.keys(flatAssociations).forEach(pattern => {
|
|
436
|
+
Object.keys(flatAssociations).forEach((pattern) => {
|
|
448
437
|
const value = flatAssociations[pattern];
|
|
449
438
|
const matchResult = applyPatternMatching({
|
|
450
439
|
pattern,
|
|
451
|
-
url
|
|
440
|
+
url,
|
|
452
441
|
});
|
|
453
442
|
if (matchResult.matched) {
|
|
454
443
|
someFullMatch = true;
|
|
455
444
|
if (isPlainObject(fullMatchMeta) && isPlainObject(value)) {
|
|
456
445
|
fullMatchMeta = {
|
|
457
446
|
...fullMatchMeta,
|
|
458
|
-
...value
|
|
447
|
+
...value,
|
|
459
448
|
};
|
|
460
449
|
} else {
|
|
461
450
|
fullMatchMeta = value;
|
|
@@ -467,7 +456,9 @@ const urlChildMayMatch = ({
|
|
|
467
456
|
if (someFullMatch) {
|
|
468
457
|
return Boolean(predicate(fullMatchMeta));
|
|
469
458
|
}
|
|
470
|
-
return partialMatchMetaArray.some(partialMatchMeta =>
|
|
459
|
+
return partialMatchMetaArray.some((partialMatchMeta) =>
|
|
460
|
+
predicate(partialMatchMeta),
|
|
461
|
+
);
|
|
471
462
|
};
|
|
472
463
|
|
|
473
464
|
const URL_META = {
|
|
@@ -475,28 +466,30 @@ const URL_META = {
|
|
|
475
466
|
applyAssociations,
|
|
476
467
|
urlChildMayMatch,
|
|
477
468
|
applyPatternMatching,
|
|
478
|
-
applyAliases
|
|
469
|
+
applyAliases,
|
|
479
470
|
};
|
|
480
471
|
|
|
481
|
-
const filterV8Coverage = async (
|
|
482
|
-
|
|
483
|
-
coverageConfig
|
|
484
|
-
|
|
485
|
-
const associations = URL_META.resolveAssociations(
|
|
486
|
-
cover: coverageConfig
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
} = URL_META.applyAssociations({
|
|
472
|
+
const filterV8Coverage = async (
|
|
473
|
+
v8Coverage,
|
|
474
|
+
{ rootDirectoryUrl, coverageConfig },
|
|
475
|
+
) => {
|
|
476
|
+
const associations = URL_META.resolveAssociations(
|
|
477
|
+
{ cover: coverageConfig },
|
|
478
|
+
rootDirectoryUrl,
|
|
479
|
+
);
|
|
480
|
+
const urlShouldBeCovered = (url) => {
|
|
481
|
+
const { cover } = URL_META.applyAssociations({
|
|
492
482
|
url: new URL(url, rootDirectoryUrl).href,
|
|
493
|
-
associations
|
|
483
|
+
associations,
|
|
494
484
|
});
|
|
495
485
|
return cover;
|
|
496
486
|
};
|
|
487
|
+
|
|
497
488
|
const v8CoverageFiltered = {
|
|
498
489
|
...v8Coverage,
|
|
499
|
-
result: v8Coverage.result.filter(fileReport =>
|
|
490
|
+
result: v8Coverage.result.filter((fileReport) =>
|
|
491
|
+
urlShouldBeCovered(fileReport.url),
|
|
492
|
+
),
|
|
500
493
|
};
|
|
501
494
|
return v8CoverageFiltered;
|
|
502
495
|
};
|