@jsenv/test 3.0.24 → 3.0.26
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/js/exception.js +13 -0
- package/dist/jsenv_test.js +132 -122
- package/package.json +5 -5
- package/src/execution/execute_test_plan.js +0 -1
- package/src/execution/reporters/reporter_list.js +32 -21
package/dist/js/exception.js
CHANGED
|
@@ -120,6 +120,19 @@ const applyMatching = (pattern, string) => {
|
|
|
120
120
|
consumeRemainingString();
|
|
121
121
|
return true;
|
|
122
122
|
}
|
|
123
|
+
if (remainingPattern.slice(0, 4) === "/**/") {
|
|
124
|
+
consumePattern(3); // consumes "/**/"
|
|
125
|
+
const skipResult = skipUntilMatch({
|
|
126
|
+
pattern: remainingPattern,
|
|
127
|
+
string: remainingString,
|
|
128
|
+
canSkipSlash: true,
|
|
129
|
+
});
|
|
130
|
+
groups.push(...skipResult.groups);
|
|
131
|
+
consumePattern(skipResult.patternIndex);
|
|
132
|
+
consumeRemainingString();
|
|
133
|
+
restoreIndexes = false;
|
|
134
|
+
return skipResult.matched;
|
|
135
|
+
}
|
|
123
136
|
// pattern leading **
|
|
124
137
|
if (remainingPattern.slice(0, 2) === "**") {
|
|
125
138
|
consumePattern(2); // consumes "**"
|
package/dist/jsenv_test.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os, { cpus, release, totalmem, availableParallelism, freemem } from "node:os";
|
|
2
2
|
import process$1, { cpuUsage, memoryUsage } from "node:process";
|
|
3
|
-
import { readdir, chmod, stat, lstat, promises, readFile as readFile$1, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir,
|
|
3
|
+
import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync, readFileSync, existsSync } from "node:fs";
|
|
4
4
|
import { takeCoverage } from "node:v8";
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { URL_META, createException } from "./js/exception.js";
|
|
@@ -2298,6 +2298,105 @@ const collectFiles = async ({
|
|
|
2298
2298
|
}
|
|
2299
2299
|
};
|
|
2300
2300
|
|
|
2301
|
+
const writeEntryPermissionsSync = (source, permissions) => {
|
|
2302
|
+
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2303
|
+
|
|
2304
|
+
let binaryFlags;
|
|
2305
|
+
{
|
|
2306
|
+
binaryFlags = permissions;
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
chmodSync(new URL(sourceUrl), binaryFlags);
|
|
2310
|
+
};
|
|
2311
|
+
|
|
2312
|
+
/*
|
|
2313
|
+
* - stats object documentation on Node.js
|
|
2314
|
+
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
2315
|
+
*/
|
|
2316
|
+
|
|
2317
|
+
|
|
2318
|
+
const isWindows = process.platform === "win32";
|
|
2319
|
+
|
|
2320
|
+
const readEntryStatSync = (
|
|
2321
|
+
source,
|
|
2322
|
+
{ nullIfNotFound = false, followLink = true } = {},
|
|
2323
|
+
) => {
|
|
2324
|
+
let sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2325
|
+
if (sourceUrl.endsWith("/")) sourceUrl = sourceUrl.slice(0, -1);
|
|
2326
|
+
|
|
2327
|
+
const sourcePath = urlToFileSystemPath(sourceUrl);
|
|
2328
|
+
|
|
2329
|
+
const handleNotFoundOption = nullIfNotFound
|
|
2330
|
+
? {
|
|
2331
|
+
handleNotFoundError: () => null,
|
|
2332
|
+
}
|
|
2333
|
+
: {};
|
|
2334
|
+
|
|
2335
|
+
return statSyncNaive(sourcePath, {
|
|
2336
|
+
followLink,
|
|
2337
|
+
...handleNotFoundOption,
|
|
2338
|
+
...(isWindows
|
|
2339
|
+
? {
|
|
2340
|
+
// Windows can EPERM on stat
|
|
2341
|
+
handlePermissionDeniedError: (error) => {
|
|
2342
|
+
console.error(
|
|
2343
|
+
`trying to fix windows EPERM after stats on ${sourcePath}`,
|
|
2344
|
+
);
|
|
2345
|
+
|
|
2346
|
+
try {
|
|
2347
|
+
// unfortunately it means we mutate the permissions
|
|
2348
|
+
// without being able to restore them to the previous value
|
|
2349
|
+
// (because reading current permission would also throw)
|
|
2350
|
+
writeEntryPermissionsSync(sourceUrl, 0o666);
|
|
2351
|
+
const stats = statSyncNaive(sourcePath, {
|
|
2352
|
+
followLink,
|
|
2353
|
+
...handleNotFoundOption,
|
|
2354
|
+
// could not fix the permission error, give up and throw original error
|
|
2355
|
+
handlePermissionDeniedError: () => {
|
|
2356
|
+
console.error(`still got EPERM after stats on ${sourcePath}`);
|
|
2357
|
+
throw error;
|
|
2358
|
+
},
|
|
2359
|
+
});
|
|
2360
|
+
return stats;
|
|
2361
|
+
} catch (e) {
|
|
2362
|
+
console.error(
|
|
2363
|
+
`error while trying to fix windows EPERM after stats on ${sourcePath}: ${e.stack}`,
|
|
2364
|
+
);
|
|
2365
|
+
throw error;
|
|
2366
|
+
}
|
|
2367
|
+
},
|
|
2368
|
+
}
|
|
2369
|
+
: {}),
|
|
2370
|
+
});
|
|
2371
|
+
};
|
|
2372
|
+
|
|
2373
|
+
const statSyncNaive = (
|
|
2374
|
+
sourcePath,
|
|
2375
|
+
{
|
|
2376
|
+
followLink,
|
|
2377
|
+
handleNotFoundError = null,
|
|
2378
|
+
handlePermissionDeniedError = null,
|
|
2379
|
+
} = {},
|
|
2380
|
+
) => {
|
|
2381
|
+
const nodeMethod = followLink ? statSync : lstatSync;
|
|
2382
|
+
|
|
2383
|
+
try {
|
|
2384
|
+
const stats = nodeMethod(sourcePath);
|
|
2385
|
+
return stats;
|
|
2386
|
+
} catch (error) {
|
|
2387
|
+
if (handleNotFoundError && error.code === "ENOENT") {
|
|
2388
|
+
return handleNotFoundError(error);
|
|
2389
|
+
}
|
|
2390
|
+
if (
|
|
2391
|
+
handlePermissionDeniedError &&
|
|
2392
|
+
(error.code === "EPERM" || error.code === "EACCES")
|
|
2393
|
+
) {
|
|
2394
|
+
return handlePermissionDeniedError(error);
|
|
2395
|
+
}
|
|
2396
|
+
throw error;
|
|
2397
|
+
}
|
|
2398
|
+
};
|
|
2399
|
+
|
|
2301
2400
|
const statsToType = (stats) => {
|
|
2302
2401
|
if (stats.isFile()) return "file";
|
|
2303
2402
|
if (stats.isDirectory()) return "directory";
|
|
@@ -2648,105 +2747,6 @@ const removeDirectoryNaive = (
|
|
|
2648
2747
|
|
|
2649
2748
|
process.platform === "win32";
|
|
2650
2749
|
|
|
2651
|
-
const writeEntryPermissionsSync = (source, permissions) => {
|
|
2652
|
-
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2653
|
-
|
|
2654
|
-
let binaryFlags;
|
|
2655
|
-
{
|
|
2656
|
-
binaryFlags = permissions;
|
|
2657
|
-
}
|
|
2658
|
-
|
|
2659
|
-
chmodSync(new URL(sourceUrl), binaryFlags);
|
|
2660
|
-
};
|
|
2661
|
-
|
|
2662
|
-
/*
|
|
2663
|
-
* - stats object documentation on Node.js
|
|
2664
|
-
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
2665
|
-
*/
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
const isWindows = process.platform === "win32";
|
|
2669
|
-
|
|
2670
|
-
const readEntryStatSync = (
|
|
2671
|
-
source,
|
|
2672
|
-
{ nullIfNotFound = false, followLink = true } = {},
|
|
2673
|
-
) => {
|
|
2674
|
-
let sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2675
|
-
if (sourceUrl.endsWith("/")) sourceUrl = sourceUrl.slice(0, -1);
|
|
2676
|
-
|
|
2677
|
-
const sourcePath = urlToFileSystemPath(sourceUrl);
|
|
2678
|
-
|
|
2679
|
-
const handleNotFoundOption = nullIfNotFound
|
|
2680
|
-
? {
|
|
2681
|
-
handleNotFoundError: () => null,
|
|
2682
|
-
}
|
|
2683
|
-
: {};
|
|
2684
|
-
|
|
2685
|
-
return statSyncNaive(sourcePath, {
|
|
2686
|
-
followLink,
|
|
2687
|
-
...handleNotFoundOption,
|
|
2688
|
-
...(isWindows
|
|
2689
|
-
? {
|
|
2690
|
-
// Windows can EPERM on stat
|
|
2691
|
-
handlePermissionDeniedError: (error) => {
|
|
2692
|
-
console.error(
|
|
2693
|
-
`trying to fix windows EPERM after stats on ${sourcePath}`,
|
|
2694
|
-
);
|
|
2695
|
-
|
|
2696
|
-
try {
|
|
2697
|
-
// unfortunately it means we mutate the permissions
|
|
2698
|
-
// without being able to restore them to the previous value
|
|
2699
|
-
// (because reading current permission would also throw)
|
|
2700
|
-
writeEntryPermissionsSync(sourceUrl, 0o666);
|
|
2701
|
-
const stats = statSyncNaive(sourcePath, {
|
|
2702
|
-
followLink,
|
|
2703
|
-
...handleNotFoundOption,
|
|
2704
|
-
// could not fix the permission error, give up and throw original error
|
|
2705
|
-
handlePermissionDeniedError: () => {
|
|
2706
|
-
console.error(`still got EPERM after stats on ${sourcePath}`);
|
|
2707
|
-
throw error;
|
|
2708
|
-
},
|
|
2709
|
-
});
|
|
2710
|
-
return stats;
|
|
2711
|
-
} catch (e) {
|
|
2712
|
-
console.error(
|
|
2713
|
-
`error while trying to fix windows EPERM after stats on ${sourcePath}: ${e.stack}`,
|
|
2714
|
-
);
|
|
2715
|
-
throw error;
|
|
2716
|
-
}
|
|
2717
|
-
},
|
|
2718
|
-
}
|
|
2719
|
-
: {}),
|
|
2720
|
-
});
|
|
2721
|
-
};
|
|
2722
|
-
|
|
2723
|
-
const statSyncNaive = (
|
|
2724
|
-
sourcePath,
|
|
2725
|
-
{
|
|
2726
|
-
followLink,
|
|
2727
|
-
handleNotFoundError = null,
|
|
2728
|
-
handlePermissionDeniedError = null,
|
|
2729
|
-
} = {},
|
|
2730
|
-
) => {
|
|
2731
|
-
const nodeMethod = followLink ? statSync : lstatSync;
|
|
2732
|
-
|
|
2733
|
-
try {
|
|
2734
|
-
const stats = nodeMethod(sourcePath);
|
|
2735
|
-
return stats;
|
|
2736
|
-
} catch (error) {
|
|
2737
|
-
if (handleNotFoundError && error.code === "ENOENT") {
|
|
2738
|
-
return handleNotFoundError(error);
|
|
2739
|
-
}
|
|
2740
|
-
if (
|
|
2741
|
-
handlePermissionDeniedError &&
|
|
2742
|
-
(error.code === "EPERM" || error.code === "EACCES")
|
|
2743
|
-
) {
|
|
2744
|
-
return handlePermissionDeniedError(error);
|
|
2745
|
-
}
|
|
2746
|
-
throw error;
|
|
2747
|
-
}
|
|
2748
|
-
};
|
|
2749
|
-
|
|
2750
2750
|
const writeDirectorySync = (
|
|
2751
2751
|
destination,
|
|
2752
2752
|
{ recursive = true, allowUseless = false } = {},
|
|
@@ -4992,7 +4992,7 @@ ${testPlanResult.patterns.join("\n")}`;
|
|
|
4992
4992
|
return `${renderBigSection({
|
|
4993
4993
|
title: "execution start",
|
|
4994
4994
|
content: lines.join("\n"),
|
|
4995
|
-
})}\n
|
|
4995
|
+
})}\n`;
|
|
4996
4996
|
};
|
|
4997
4997
|
|
|
4998
4998
|
const renderExecutionLog = (execution, logOptions) => {
|
|
@@ -5314,8 +5314,8 @@ const renderErrors = (execution, logOptions) => {
|
|
|
5314
5314
|
};
|
|
5315
5315
|
|
|
5316
5316
|
const renderOutro = (testPlanResult, logOptions = {}) => {
|
|
5317
|
-
return
|
|
5318
|
-
title: "
|
|
5317
|
+
return `${renderBigSection({
|
|
5318
|
+
title: "",
|
|
5319
5319
|
content: renderOutroContent(testPlanResult, logOptions),
|
|
5320
5320
|
})}\n`;
|
|
5321
5321
|
};
|
|
@@ -5462,28 +5462,39 @@ const renderSection = ({
|
|
|
5462
5462
|
content,
|
|
5463
5463
|
dashColor = ANSI.GREY,
|
|
5464
5464
|
width = 38,
|
|
5465
|
+
bottomSeparator = true,
|
|
5465
5466
|
}) => {
|
|
5466
5467
|
let section = "";
|
|
5467
5468
|
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5469
|
+
if (title) {
|
|
5470
|
+
const titleWidth = stripAnsi(title).length;
|
|
5471
|
+
const minWidthRequired = `--- … ---`.length;
|
|
5472
|
+
const needsTruncate = titleWidth + minWidthRequired >= width;
|
|
5473
|
+
if (needsTruncate) {
|
|
5474
|
+
const titleTruncated = title.slice(0, width - minWidthRequired);
|
|
5475
|
+
const leftDashes = ANSI.color("---", dashColor);
|
|
5476
|
+
const rightDashes = ANSI.color("---", dashColor);
|
|
5477
|
+
section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
|
|
5478
|
+
} else {
|
|
5479
|
+
const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
|
|
5480
|
+
const dashLeftCount = Math.floor(remainingWidth / 2);
|
|
5481
|
+
const dashRightCount = remainingWidth - dashLeftCount;
|
|
5482
|
+
const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
|
|
5483
|
+
const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
|
|
5484
|
+
section += `${leftDashes} ${title} ${rightDashes}`;
|
|
5485
|
+
}
|
|
5486
|
+
section += "\n";
|
|
5476
5487
|
} else {
|
|
5477
|
-
const
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5488
|
+
const topDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
5489
|
+
section += topDashes;
|
|
5490
|
+
section += "\n";
|
|
5491
|
+
}
|
|
5492
|
+
section += `${content}`;
|
|
5493
|
+
if (bottomSeparator) {
|
|
5494
|
+
section += "\n";
|
|
5495
|
+
const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
5496
|
+
section += bottomDashes;
|
|
5497
|
+
}
|
|
5487
5498
|
return section;
|
|
5488
5499
|
};
|
|
5489
5500
|
|
|
@@ -6244,7 +6255,6 @@ To fix this warning:
|
|
|
6244
6255
|
},
|
|
6245
6256
|
});
|
|
6246
6257
|
}
|
|
6247
|
-
|
|
6248
6258
|
timings.executionStart = takeTiming();
|
|
6249
6259
|
// execute all
|
|
6250
6260
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.26",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
"@c88/v8-coverage": "0.1.1",
|
|
40
40
|
"@jsenv/abort": "4.3.0",
|
|
41
41
|
"@jsenv/ast": "6.0.7",
|
|
42
|
-
"@jsenv/filesystem": "4.
|
|
43
|
-
"@jsenv/github-check-run": "0.1.
|
|
42
|
+
"@jsenv/filesystem": "4.7.1",
|
|
43
|
+
"@jsenv/github-check-run": "0.1.15",
|
|
44
44
|
"@jsenv/humanize": "1.1.3",
|
|
45
|
-
"@jsenv/plugin-supervisor": "1.4.
|
|
46
|
-
"@jsenv/url-meta": "8.4.
|
|
45
|
+
"@jsenv/plugin-supervisor": "1.4.11",
|
|
46
|
+
"@jsenv/url-meta": "8.4.1",
|
|
47
47
|
"@jsenv/urls": "2.2.7",
|
|
48
48
|
"@jsenv/utils": "2.1.1",
|
|
49
49
|
"istanbul-lib-coverage": "3.2.2",
|
|
@@ -259,7 +259,7 @@ ${testPlanResult.patterns.join("\n")}`;
|
|
|
259
259
|
return `${renderBigSection({
|
|
260
260
|
title: "execution start",
|
|
261
261
|
content: lines.join("\n"),
|
|
262
|
-
})}\n
|
|
262
|
+
})}\n`;
|
|
263
263
|
};
|
|
264
264
|
|
|
265
265
|
const renderExecutionLog = (execution, logOptions) => {
|
|
@@ -581,8 +581,8 @@ const renderErrors = (execution, logOptions) => {
|
|
|
581
581
|
};
|
|
582
582
|
|
|
583
583
|
const renderOutro = (testPlanResult, logOptions = {}) => {
|
|
584
|
-
return
|
|
585
|
-
title: "
|
|
584
|
+
return `${renderBigSection({
|
|
585
|
+
title: "",
|
|
586
586
|
content: renderOutroContent(testPlanResult, logOptions),
|
|
587
587
|
})}\n`;
|
|
588
588
|
};
|
|
@@ -729,28 +729,39 @@ const renderSection = ({
|
|
|
729
729
|
content,
|
|
730
730
|
dashColor = ANSI.GREY,
|
|
731
731
|
width = 38,
|
|
732
|
+
bottomSeparator = true,
|
|
732
733
|
}) => {
|
|
733
734
|
let section = "";
|
|
734
735
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
736
|
+
if (title) {
|
|
737
|
+
const titleWidth = stripAnsi(title).length;
|
|
738
|
+
const minWidthRequired = `--- … ---`.length;
|
|
739
|
+
const needsTruncate = titleWidth + minWidthRequired >= width;
|
|
740
|
+
if (needsTruncate) {
|
|
741
|
+
const titleTruncated = title.slice(0, width - minWidthRequired);
|
|
742
|
+
const leftDashes = ANSI.color("---", dashColor);
|
|
743
|
+
const rightDashes = ANSI.color("---", dashColor);
|
|
744
|
+
section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
|
|
745
|
+
} else {
|
|
746
|
+
const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
|
|
747
|
+
const dashLeftCount = Math.floor(remainingWidth / 2);
|
|
748
|
+
const dashRightCount = remainingWidth - dashLeftCount;
|
|
749
|
+
const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
|
|
750
|
+
const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
|
|
751
|
+
section += `${leftDashes} ${title} ${rightDashes}`;
|
|
752
|
+
}
|
|
753
|
+
section += "\n";
|
|
743
754
|
} else {
|
|
744
|
-
const
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
755
|
+
const topDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
756
|
+
section += topDashes;
|
|
757
|
+
section += "\n";
|
|
758
|
+
}
|
|
759
|
+
section += `${content}`;
|
|
760
|
+
if (bottomSeparator) {
|
|
761
|
+
section += "\n";
|
|
762
|
+
const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
|
|
763
|
+
section += bottomDashes;
|
|
764
|
+
}
|
|
754
765
|
return section;
|
|
755
766
|
};
|
|
756
767
|
|