@jsenv/test 3.0.12 → 3.0.14
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 +4 -4
- package/dist/jsenv_test.js +64 -321
- package/dist/node_child_process_controlled.mjs +2 -2
- package/dist/node_worker_thread_controlled.mjs +2 -2
- package/package.json +13 -13
- package/src/execution/reporters/reporter_list.js +21 -6
- package/src/runtime_node/node_child_process.js +2 -0
- package/src/runtime_node/node_child_process_controlled.mjs +2 -2
- package/src/runtime_node/node_worker_thread.js +2 -0
- package/src/runtime_node/node_worker_thread_controlled.mjs +2 -2
package/dist/js/exception.js
CHANGED
|
@@ -88,7 +88,7 @@ const applyMatching = (pattern, string) => {
|
|
|
88
88
|
}
|
|
89
89
|
// pattern consumed, string not consumed
|
|
90
90
|
if (remainingPattern === "" && remainingString !== "") {
|
|
91
|
-
return false; // fails because string longer than
|
|
91
|
+
return false; // fails because string longer than expect
|
|
92
92
|
}
|
|
93
93
|
// -- from this point pattern is not consumed --
|
|
94
94
|
// string consumed, pattern not consumed
|
|
@@ -101,7 +101,7 @@ const applyMatching = (pattern, string) => {
|
|
|
101
101
|
if (remainingPattern === "*") {
|
|
102
102
|
groups.push({ string: "" });
|
|
103
103
|
}
|
|
104
|
-
return false; // fail because string shorter than
|
|
104
|
+
return false; // fail because string shorter than expect
|
|
105
105
|
}
|
|
106
106
|
// -- from this point pattern and string are not consumed --
|
|
107
107
|
// fast path trailing slash
|
|
@@ -163,7 +163,7 @@ const applyMatching = (pattern, string) => {
|
|
|
163
163
|
groups.push({ string: consumeString(slashIndex) });
|
|
164
164
|
return false;
|
|
165
165
|
}
|
|
166
|
-
// the next char must not the one
|
|
166
|
+
// the next char must not the one expect by remainingPattern[0]
|
|
167
167
|
// because * is greedy and expect to skip at least one char
|
|
168
168
|
if (remainingPattern[0] === remainingString[0]) {
|
|
169
169
|
groups.push({ string: "" });
|
|
@@ -709,7 +709,7 @@ function parseStackTrace(stack) {
|
|
|
709
709
|
|
|
710
710
|
|
|
711
711
|
const isDev = process.execArgv.includes("--conditions=development");
|
|
712
|
-
const jsenvCoreDirectoryUrl = new URL("file:///Users/
|
|
712
|
+
const jsenvCoreDirectoryUrl = new URL("file:///Users/damien.maillard/dev/perso/jsenv-core/", import.meta.url);
|
|
713
713
|
|
|
714
714
|
const createException = (reason, { rootDirectoryUrl } = {}) => {
|
|
715
715
|
const exception = {
|
package/dist/jsenv_test.js
CHANGED
|
@@ -5,6 +5,7 @@ import { takeCoverage } from "node:v8";
|
|
|
5
5
|
import stripAnsi from "strip-ansi";
|
|
6
6
|
import { URL_META, createException } from "./js/exception.js";
|
|
7
7
|
import stringWidth from "string-width";
|
|
8
|
+
import { isBrowser } from "environment";
|
|
8
9
|
import tty from "node:tty";
|
|
9
10
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
10
11
|
import { dirname } from "node:path";
|
|
@@ -16,7 +17,7 @@ import { applyBabelPlugins } from "@jsenv/ast";
|
|
|
16
17
|
import { spawn, spawnSync, fork } from "node:child_process";
|
|
17
18
|
import { createServer } from "node:net";
|
|
18
19
|
import { injectSupervisorIntoHTML, supervisorFileUrl } from "@jsenv/plugin-supervisor";
|
|
19
|
-
import {
|
|
20
|
+
import { SOURCEMAP, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
20
21
|
import { findFreePort } from "@jsenv/server";
|
|
21
22
|
import { Worker } from "node:worker_threads";
|
|
22
23
|
import he from "he";
|
|
@@ -207,7 +208,7 @@ const createOperation = () => {
|
|
|
207
208
|
const operationSignal = operationAbortController.signal;
|
|
208
209
|
|
|
209
210
|
// abortCallbackList is used to ignore the max listeners warning from Node.js
|
|
210
|
-
// this warning is useful but becomes problematic when it's
|
|
211
|
+
// this warning is useful but becomes problematic when it's expect
|
|
211
212
|
// (a function doing 20 http call in parallel)
|
|
212
213
|
// To be 100% sure we don't have memory leak, only Abortable.asyncCallback
|
|
213
214
|
// uses abortCallbackList to know when something is aborted
|
|
@@ -619,169 +620,41 @@ const error = (...args) => console.error(...args);
|
|
|
619
620
|
const errorDisabled = () => {};
|
|
620
621
|
|
|
621
622
|
const ESC = '\u001B[';
|
|
622
|
-
const OSC = '\u001B]';
|
|
623
|
-
const BEL = '\u0007';
|
|
624
|
-
const SEP = ';';
|
|
625
623
|
|
|
626
|
-
|
|
627
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
628
|
-
|
|
629
|
-
const isTerminalApp = !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
624
|
+
!isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
630
625
|
const isWindows$3 = !isBrowser && process$1.platform === 'win32';
|
|
631
|
-
|
|
626
|
+
|
|
627
|
+
isBrowser ? () => {
|
|
632
628
|
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
633
629
|
} : process$1.cwd;
|
|
634
630
|
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
ansiEscapes.cursorTo = (x, y) => {
|
|
638
|
-
if (typeof x !== 'number') {
|
|
639
|
-
throw new TypeError('The `x` argument is required');
|
|
640
|
-
}
|
|
631
|
+
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
641
632
|
|
|
642
|
-
|
|
643
|
-
return ESC + (x + 1) + 'G';
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
return ESC + (y + 1) + SEP + (x + 1) + 'H';
|
|
647
|
-
};
|
|
633
|
+
const cursorLeft = ESC + 'G';
|
|
648
634
|
|
|
649
|
-
|
|
650
|
-
if (typeof x !== 'number') {
|
|
651
|
-
throw new TypeError('The `x` argument is required');
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
let returnValue = '';
|
|
655
|
-
|
|
656
|
-
if (x < 0) {
|
|
657
|
-
returnValue += ESC + (-x) + 'D';
|
|
658
|
-
} else if (x > 0) {
|
|
659
|
-
returnValue += ESC + x + 'C';
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
if (y < 0) {
|
|
663
|
-
returnValue += ESC + (-y) + 'A';
|
|
664
|
-
} else if (y > 0) {
|
|
665
|
-
returnValue += ESC + y + 'B';
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
return returnValue;
|
|
669
|
-
};
|
|
670
|
-
|
|
671
|
-
ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
|
|
672
|
-
ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
|
|
673
|
-
ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
|
|
674
|
-
ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
|
|
675
|
-
|
|
676
|
-
ansiEscapes.cursorLeft = ESC + 'G';
|
|
677
|
-
ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
|
|
678
|
-
ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
|
|
679
|
-
ansiEscapes.cursorGetPosition = ESC + '6n';
|
|
680
|
-
ansiEscapes.cursorNextLine = ESC + 'E';
|
|
681
|
-
ansiEscapes.cursorPrevLine = ESC + 'F';
|
|
682
|
-
ansiEscapes.cursorHide = ESC + '?25l';
|
|
683
|
-
ansiEscapes.cursorShow = ESC + '?25h';
|
|
684
|
-
|
|
685
|
-
ansiEscapes.eraseLines = count => {
|
|
635
|
+
const eraseLines = count => {
|
|
686
636
|
let clear = '';
|
|
687
637
|
|
|
688
638
|
for (let i = 0; i < count; i++) {
|
|
689
|
-
clear +=
|
|
639
|
+
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
690
640
|
}
|
|
691
641
|
|
|
692
642
|
if (count) {
|
|
693
|
-
clear +=
|
|
643
|
+
clear += cursorLeft;
|
|
694
644
|
}
|
|
695
645
|
|
|
696
646
|
return clear;
|
|
697
647
|
};
|
|
648
|
+
const eraseLine = ESC + '2K';
|
|
649
|
+
const eraseScreen = ESC + '2J';
|
|
698
650
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
ansiEscapes.eraseLine = ESC + '2K';
|
|
702
|
-
ansiEscapes.eraseDown = ESC + 'J';
|
|
703
|
-
ansiEscapes.eraseUp = ESC + '1J';
|
|
704
|
-
ansiEscapes.eraseScreen = ESC + '2J';
|
|
705
|
-
ansiEscapes.scrollUp = ESC + 'S';
|
|
706
|
-
ansiEscapes.scrollDown = ESC + 'T';
|
|
707
|
-
|
|
708
|
-
ansiEscapes.clearScreen = '\u001Bc';
|
|
709
|
-
|
|
710
|
-
ansiEscapes.clearTerminal = isWindows$3
|
|
711
|
-
? `${ansiEscapes.eraseScreen}${ESC}0f`
|
|
651
|
+
const clearTerminal = isWindows$3
|
|
652
|
+
? `${eraseScreen}${ESC}0f`
|
|
712
653
|
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
713
654
|
// 2. Erases the whole screen including scrollback buffer
|
|
714
655
|
// 3. Moves cursor to the top-left position
|
|
715
656
|
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
716
|
-
:
|
|
717
|
-
|
|
718
|
-
ansiEscapes.enterAlternativeScreen = ESC + '?1049h';
|
|
719
|
-
ansiEscapes.exitAlternativeScreen = ESC + '?1049l';
|
|
720
|
-
|
|
721
|
-
ansiEscapes.beep = BEL;
|
|
722
|
-
|
|
723
|
-
ansiEscapes.link = (text, url) => [
|
|
724
|
-
OSC,
|
|
725
|
-
'8',
|
|
726
|
-
SEP,
|
|
727
|
-
SEP,
|
|
728
|
-
url,
|
|
729
|
-
BEL,
|
|
730
|
-
text,
|
|
731
|
-
OSC,
|
|
732
|
-
'8',
|
|
733
|
-
SEP,
|
|
734
|
-
SEP,
|
|
735
|
-
BEL,
|
|
736
|
-
].join('');
|
|
737
|
-
|
|
738
|
-
ansiEscapes.image = (buffer, options = {}) => {
|
|
739
|
-
let returnValue = `${OSC}1337;File=inline=1`;
|
|
740
|
-
|
|
741
|
-
if (options.width) {
|
|
742
|
-
returnValue += `;width=${options.width}`;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
if (options.height) {
|
|
746
|
-
returnValue += `;height=${options.height}`;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (options.preserveAspectRatio === false) {
|
|
750
|
-
returnValue += ';preserveAspectRatio=0';
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
return returnValue + ':' + buffer.toString('base64') + BEL;
|
|
754
|
-
};
|
|
755
|
-
|
|
756
|
-
ansiEscapes.iTerm = {
|
|
757
|
-
setCwd: (cwd = cwdFunction()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
|
|
758
|
-
|
|
759
|
-
annotation(message, options = {}) {
|
|
760
|
-
let returnValue = `${OSC}1337;`;
|
|
761
|
-
|
|
762
|
-
const hasX = typeof options.x !== 'undefined';
|
|
763
|
-
const hasY = typeof options.y !== 'undefined';
|
|
764
|
-
if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
|
|
765
|
-
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
message = message.replace(/\|/g, '');
|
|
769
|
-
|
|
770
|
-
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
|
|
771
|
-
|
|
772
|
-
if (options.length > 0) {
|
|
773
|
-
returnValue += (
|
|
774
|
-
hasX
|
|
775
|
-
? [message, options.length, options.x, options.y]
|
|
776
|
-
: [options.length, message]
|
|
777
|
-
).join('|');
|
|
778
|
-
} else {
|
|
779
|
-
returnValue += message;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
return returnValue + BEL;
|
|
783
|
-
},
|
|
784
|
-
};
|
|
657
|
+
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
785
658
|
|
|
786
659
|
/*
|
|
787
660
|
* see also https://github.com/vadimdemedes/ink
|
|
@@ -829,7 +702,7 @@ const createDynamicLog = ({
|
|
|
829
702
|
if (visualLineCount > rows) {
|
|
830
703
|
if (clearTerminalAllowed) {
|
|
831
704
|
clearAttemptResult = true;
|
|
832
|
-
return
|
|
705
|
+
return clearTerminal;
|
|
833
706
|
}
|
|
834
707
|
// the whole log cannot be cleared because it's vertically to long
|
|
835
708
|
// (longer than terminal height)
|
|
@@ -842,7 +715,7 @@ const createDynamicLog = ({
|
|
|
842
715
|
}
|
|
843
716
|
|
|
844
717
|
clearAttemptResult = true;
|
|
845
|
-
return
|
|
718
|
+
return eraseLines(visualLineCount);
|
|
846
719
|
};
|
|
847
720
|
|
|
848
721
|
const update = (string) => {
|
|
@@ -871,20 +744,22 @@ const createDynamicLog = ({
|
|
|
871
744
|
clearAttemptResult = undefined;
|
|
872
745
|
};
|
|
873
746
|
|
|
874
|
-
const clearDuringFunctionCall = (
|
|
747
|
+
const clearDuringFunctionCall = (
|
|
748
|
+
callback,
|
|
749
|
+
ouputAfterCallback = lastOutput,
|
|
750
|
+
) => {
|
|
875
751
|
// 1. Erase the current log
|
|
876
|
-
// 2. Call callback (
|
|
752
|
+
// 2. Call callback (expect to write something on stdout)
|
|
877
753
|
// 3. Restore the current log
|
|
878
754
|
// During step 2. we expect a "write from outside" so we uninstall
|
|
879
755
|
// the stream spy during function call
|
|
880
|
-
const currentOutput = lastOutput;
|
|
881
756
|
update("");
|
|
882
757
|
|
|
883
758
|
writing = true;
|
|
884
759
|
callback();
|
|
885
760
|
writing = false;
|
|
886
761
|
|
|
887
|
-
update(
|
|
762
|
+
update(ouputAfterCallback);
|
|
888
763
|
};
|
|
889
764
|
|
|
890
765
|
const writeFromOutsideEffect = (value) => {
|
|
@@ -1139,10 +1014,10 @@ function createSupportsColor(stream, options = {}) {
|
|
|
1139
1014
|
return translateLevel(level);
|
|
1140
1015
|
}
|
|
1141
1016
|
|
|
1142
|
-
|
|
1017
|
+
const supportsColor = {
|
|
1143
1018
|
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
1144
1019
|
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
1145
|
-
}
|
|
1020
|
+
};
|
|
1146
1021
|
|
|
1147
1022
|
const processSupportsBasicColor = createSupportsColor(process.stdout).hasBasic;
|
|
1148
1023
|
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
@@ -1157,14 +1032,19 @@ const ANSI = {
|
|
|
1157
1032
|
YELLOW: "\x1b[33m",
|
|
1158
1033
|
BLUE: "\x1b[34m",
|
|
1159
1034
|
MAGENTA: "\x1b[35m",
|
|
1035
|
+
CYAN: "\x1b[36m",
|
|
1160
1036
|
GREY: "\x1b[90m",
|
|
1161
1037
|
color: (text, ANSI_COLOR) => {
|
|
1162
|
-
return ANSI.supported ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
1038
|
+
return ANSI.supported && ANSI_COLOR ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
1163
1039
|
},
|
|
1164
1040
|
|
|
1165
1041
|
BOLD: "\x1b[1m",
|
|
1042
|
+
UNDERLINE: "\x1b[4m",
|
|
1043
|
+
STRIKE: "\x1b[9m",
|
|
1166
1044
|
effect: (text, ANSI_EFFECT) => {
|
|
1167
|
-
return ANSI.supported
|
|
1045
|
+
return ANSI.supported && ANSI_EFFECT
|
|
1046
|
+
? `${ANSI_EFFECT}${text}${RESET}`
|
|
1047
|
+
: text;
|
|
1168
1048
|
},
|
|
1169
1049
|
};
|
|
1170
1050
|
|
|
@@ -1432,6 +1312,9 @@ const UNICODE = {
|
|
|
1432
1312
|
get CIRCLE_CROSS() {
|
|
1433
1313
|
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
1434
1314
|
},
|
|
1315
|
+
get ELLIPSIS() {
|
|
1316
|
+
return UNICODE.supported ? `…` : `...`;
|
|
1317
|
+
},
|
|
1435
1318
|
};
|
|
1436
1319
|
|
|
1437
1320
|
const createDetailedMessage = (message, details = {}) => {
|
|
@@ -2078,7 +1961,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2078
1961
|
try {
|
|
2079
1962
|
url = String(new URL(url));
|
|
2080
1963
|
} catch (e) {
|
|
2081
|
-
throw new Error(`absolute url
|
|
1964
|
+
throw new Error(`absolute url expect but got ${url}`);
|
|
2082
1965
|
}
|
|
2083
1966
|
|
|
2084
1967
|
if (!isWindows$2) {
|
|
@@ -2089,7 +1972,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2089
1972
|
baseUrl = String(new URL(baseUrl));
|
|
2090
1973
|
} catch (e) {
|
|
2091
1974
|
throw new Error(
|
|
2092
|
-
`absolute baseUrl
|
|
1975
|
+
`absolute baseUrl expect but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
2093
1976
|
);
|
|
2094
1977
|
}
|
|
2095
1978
|
|
|
@@ -2111,7 +1994,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2111
1994
|
);
|
|
2112
1995
|
if (!driveLetter) {
|
|
2113
1996
|
throw new Error(
|
|
2114
|
-
`drive letter
|
|
1997
|
+
`drive letter expect on baseUrl but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
2115
1998
|
);
|
|
2116
1999
|
}
|
|
2117
2000
|
return `file:///${driveLetter}:${afterProtocol}`;
|
|
@@ -2162,67 +2045,11 @@ const readDirectory = async (url, { emfileMaxWait = 1000 } = {}) => {
|
|
|
2162
2045
|
return attempt();
|
|
2163
2046
|
};
|
|
2164
2047
|
|
|
2165
|
-
// https://github.com/coderaiser/cloudcmd/issues/63#issuecomment-195478143
|
|
2166
|
-
// https://nodejs.org/api/fs.html#fs_file_modes
|
|
2167
|
-
// https://github.com/TooTallNate/stat-mode
|
|
2168
|
-
|
|
2169
|
-
// cannot get from fs.constants because they are not available on windows
|
|
2170
|
-
const S_IRUSR = 256; /* 0000400 read permission, owner */
|
|
2171
|
-
const S_IWUSR = 128; /* 0000200 write permission, owner */
|
|
2172
|
-
const S_IXUSR = 64; /* 0000100 execute/search permission, owner */
|
|
2173
|
-
const S_IRGRP = 32; /* 0000040 read permission, group */
|
|
2174
|
-
const S_IWGRP = 16; /* 0000020 write permission, group */
|
|
2175
|
-
const S_IXGRP = 8; /* 0000010 execute/search permission, group */
|
|
2176
|
-
const S_IROTH = 4; /* 0000004 read permission, others */
|
|
2177
|
-
const S_IWOTH = 2; /* 0000002 write permission, others */
|
|
2178
|
-
const S_IXOTH = 1; /* 0000001 execute/search permission, others */
|
|
2179
|
-
|
|
2180
|
-
const permissionsToBinaryFlags = ({ owner, group, others }) => {
|
|
2181
|
-
let binaryFlags = 0;
|
|
2182
|
-
|
|
2183
|
-
if (owner.read) binaryFlags |= S_IRUSR;
|
|
2184
|
-
if (owner.write) binaryFlags |= S_IWUSR;
|
|
2185
|
-
if (owner.execute) binaryFlags |= S_IXUSR;
|
|
2186
|
-
|
|
2187
|
-
if (group.read) binaryFlags |= S_IRGRP;
|
|
2188
|
-
if (group.write) binaryFlags |= S_IWGRP;
|
|
2189
|
-
if (group.execute) binaryFlags |= S_IXGRP;
|
|
2190
|
-
|
|
2191
|
-
if (others.read) binaryFlags |= S_IROTH;
|
|
2192
|
-
if (others.write) binaryFlags |= S_IWOTH;
|
|
2193
|
-
if (others.execute) binaryFlags |= S_IXOTH;
|
|
2194
|
-
|
|
2195
|
-
return binaryFlags;
|
|
2196
|
-
};
|
|
2197
|
-
|
|
2198
2048
|
const writeEntryPermissions = async (source, permissions) => {
|
|
2199
2049
|
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2200
2050
|
|
|
2201
2051
|
let binaryFlags;
|
|
2202
|
-
|
|
2203
|
-
permissions = {
|
|
2204
|
-
owner: {
|
|
2205
|
-
read: getPermissionOrComputeDefault$1("read", "owner", permissions),
|
|
2206
|
-
write: getPermissionOrComputeDefault$1("write", "owner", permissions),
|
|
2207
|
-
execute: getPermissionOrComputeDefault$1("execute", "owner", permissions),
|
|
2208
|
-
},
|
|
2209
|
-
group: {
|
|
2210
|
-
read: getPermissionOrComputeDefault$1("read", "group", permissions),
|
|
2211
|
-
write: getPermissionOrComputeDefault$1("write", "group", permissions),
|
|
2212
|
-
execute: getPermissionOrComputeDefault$1("execute", "group", permissions),
|
|
2213
|
-
},
|
|
2214
|
-
others: {
|
|
2215
|
-
read: getPermissionOrComputeDefault$1("read", "others", permissions),
|
|
2216
|
-
write: getPermissionOrComputeDefault$1("write", "others", permissions),
|
|
2217
|
-
execute: getPermissionOrComputeDefault$1(
|
|
2218
|
-
"execute",
|
|
2219
|
-
"others",
|
|
2220
|
-
permissions,
|
|
2221
|
-
),
|
|
2222
|
-
},
|
|
2223
|
-
};
|
|
2224
|
-
binaryFlags = permissionsToBinaryFlags(permissions);
|
|
2225
|
-
} else {
|
|
2052
|
+
{
|
|
2226
2053
|
binaryFlags = permissions;
|
|
2227
2054
|
}
|
|
2228
2055
|
|
|
@@ -2237,45 +2064,6 @@ const writeEntryPermissions = async (source, permissions) => {
|
|
|
2237
2064
|
});
|
|
2238
2065
|
};
|
|
2239
2066
|
|
|
2240
|
-
const actionLevels$1 = { read: 0, write: 1, execute: 2 };
|
|
2241
|
-
const subjectLevels$1 = { others: 0, group: 1, owner: 2 };
|
|
2242
|
-
|
|
2243
|
-
const getPermissionOrComputeDefault$1 = (action, subject, permissions) => {
|
|
2244
|
-
if (subject in permissions) {
|
|
2245
|
-
const subjectPermissions = permissions[subject];
|
|
2246
|
-
if (action in subjectPermissions) {
|
|
2247
|
-
return subjectPermissions[action];
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
const actionLevel = actionLevels$1[action];
|
|
2251
|
-
const actionFallback = Object.keys(actionLevels$1).find(
|
|
2252
|
-
(actionFallbackCandidate) =>
|
|
2253
|
-
actionLevels$1[actionFallbackCandidate] > actionLevel &&
|
|
2254
|
-
actionFallbackCandidate in subjectPermissions,
|
|
2255
|
-
);
|
|
2256
|
-
if (actionFallback) {
|
|
2257
|
-
return subjectPermissions[actionFallback];
|
|
2258
|
-
}
|
|
2259
|
-
}
|
|
2260
|
-
|
|
2261
|
-
const subjectLevel = subjectLevels$1[subject];
|
|
2262
|
-
// do we have a subject with a stronger level (group or owner)
|
|
2263
|
-
// where we could read the action permission ?
|
|
2264
|
-
const subjectFallback = Object.keys(subjectLevels$1).find(
|
|
2265
|
-
(subjectFallbackCandidate) =>
|
|
2266
|
-
subjectLevels$1[subjectFallbackCandidate] > subjectLevel &&
|
|
2267
|
-
subjectFallbackCandidate in permissions,
|
|
2268
|
-
);
|
|
2269
|
-
if (subjectFallback) {
|
|
2270
|
-
const subjectPermissions = permissions[subjectFallback];
|
|
2271
|
-
return action in subjectPermissions
|
|
2272
|
-
? subjectPermissions[action]
|
|
2273
|
-
: getPermissionOrComputeDefault$1(action, subjectFallback, permissions);
|
|
2274
|
-
}
|
|
2275
|
-
|
|
2276
|
-
return false;
|
|
2277
|
-
};
|
|
2278
|
-
|
|
2279
2067
|
/*
|
|
2280
2068
|
* - stats object documentation on Node.js
|
|
2281
2069
|
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
@@ -2812,75 +2600,13 @@ const writeEntryPermissionsSync = (source, permissions) => {
|
|
|
2812
2600
|
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2813
2601
|
|
|
2814
2602
|
let binaryFlags;
|
|
2815
|
-
|
|
2816
|
-
permissions = {
|
|
2817
|
-
owner: {
|
|
2818
|
-
read: getPermissionOrComputeDefault("read", "owner", permissions),
|
|
2819
|
-
write: getPermissionOrComputeDefault("write", "owner", permissions),
|
|
2820
|
-
execute: getPermissionOrComputeDefault("execute", "owner", permissions),
|
|
2821
|
-
},
|
|
2822
|
-
group: {
|
|
2823
|
-
read: getPermissionOrComputeDefault("read", "group", permissions),
|
|
2824
|
-
write: getPermissionOrComputeDefault("write", "group", permissions),
|
|
2825
|
-
execute: getPermissionOrComputeDefault("execute", "group", permissions),
|
|
2826
|
-
},
|
|
2827
|
-
others: {
|
|
2828
|
-
read: getPermissionOrComputeDefault("read", "others", permissions),
|
|
2829
|
-
write: getPermissionOrComputeDefault("write", "others", permissions),
|
|
2830
|
-
execute: getPermissionOrComputeDefault(
|
|
2831
|
-
"execute",
|
|
2832
|
-
"others",
|
|
2833
|
-
permissions,
|
|
2834
|
-
),
|
|
2835
|
-
},
|
|
2836
|
-
};
|
|
2837
|
-
binaryFlags = permissionsToBinaryFlags(permissions);
|
|
2838
|
-
} else {
|
|
2603
|
+
{
|
|
2839
2604
|
binaryFlags = permissions;
|
|
2840
2605
|
}
|
|
2841
2606
|
|
|
2842
2607
|
chmodSync(new URL(sourceUrl), binaryFlags);
|
|
2843
2608
|
};
|
|
2844
2609
|
|
|
2845
|
-
const actionLevels = { read: 0, write: 1, execute: 2 };
|
|
2846
|
-
const subjectLevels = { others: 0, group: 1, owner: 2 };
|
|
2847
|
-
|
|
2848
|
-
const getPermissionOrComputeDefault = (action, subject, permissions) => {
|
|
2849
|
-
if (subject in permissions) {
|
|
2850
|
-
const subjectPermissions = permissions[subject];
|
|
2851
|
-
if (action in subjectPermissions) {
|
|
2852
|
-
return subjectPermissions[action];
|
|
2853
|
-
}
|
|
2854
|
-
|
|
2855
|
-
const actionLevel = actionLevels[action];
|
|
2856
|
-
const actionFallback = Object.keys(actionLevels).find(
|
|
2857
|
-
(actionFallbackCandidate) =>
|
|
2858
|
-
actionLevels[actionFallbackCandidate] > actionLevel &&
|
|
2859
|
-
actionFallbackCandidate in subjectPermissions,
|
|
2860
|
-
);
|
|
2861
|
-
if (actionFallback) {
|
|
2862
|
-
return subjectPermissions[actionFallback];
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
|
|
2866
|
-
const subjectLevel = subjectLevels[subject];
|
|
2867
|
-
// do we have a subject with a stronger level (group or owner)
|
|
2868
|
-
// where we could read the action permission ?
|
|
2869
|
-
const subjectFallback = Object.keys(subjectLevels).find(
|
|
2870
|
-
(subjectFallbackCandidate) =>
|
|
2871
|
-
subjectLevels[subjectFallbackCandidate] > subjectLevel &&
|
|
2872
|
-
subjectFallbackCandidate in permissions,
|
|
2873
|
-
);
|
|
2874
|
-
if (subjectFallback) {
|
|
2875
|
-
const subjectPermissions = permissions[subjectFallback];
|
|
2876
|
-
return action in subjectPermissions
|
|
2877
|
-
? subjectPermissions[action]
|
|
2878
|
-
: getPermissionOrComputeDefault(action, subjectFallback, permissions);
|
|
2879
|
-
}
|
|
2880
|
-
|
|
2881
|
-
return false;
|
|
2882
|
-
};
|
|
2883
|
-
|
|
2884
2610
|
/*
|
|
2885
2611
|
* - stats object documentation on Node.js
|
|
2886
2612
|
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
@@ -5033,6 +4759,7 @@ const reporterList = ({
|
|
|
5033
4759
|
});
|
|
5034
4760
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
5035
4761
|
let frameIndex = 0;
|
|
4762
|
+
let oneExecutionWritten = false;
|
|
5036
4763
|
const renderDynamicLog = (testPlanResult) => {
|
|
5037
4764
|
frameIndex = frameIndex === frames.length - 1 ? 0 : frameIndex + 1;
|
|
5038
4765
|
let dynamicLogContent = "";
|
|
@@ -5065,7 +4792,10 @@ const reporterList = ({
|
|
|
5065
4792
|
ANSI.GREY,
|
|
5066
4793
|
)}${infoFormatted}${ANSI.color("]", ANSI.GREY)}`;
|
|
5067
4794
|
|
|
5068
|
-
|
|
4795
|
+
if (oneExecutionWritten) {
|
|
4796
|
+
dynamicLogContent = `\n${dynamicLogContent}`;
|
|
4797
|
+
}
|
|
4798
|
+
dynamicLogContent = `${dynamicLogContent}\n`;
|
|
5069
4799
|
return dynamicLogContent;
|
|
5070
4800
|
};
|
|
5071
4801
|
dynamicLog.update(renderDynamicLog(testPlanResult));
|
|
@@ -5080,10 +4810,16 @@ const reporterList = ({
|
|
|
5080
4810
|
});
|
|
5081
4811
|
},
|
|
5082
4812
|
afterEachInOrder: (execution) => {
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
4813
|
+
oneExecutionWritten = true;
|
|
4814
|
+
dynamicLog.clearDuringFunctionCall(
|
|
4815
|
+
() => {
|
|
4816
|
+
const log = renderExecutionLog(execution, logOptions);
|
|
4817
|
+
write(log);
|
|
4818
|
+
},
|
|
4819
|
+
// regenerate the dynamic log to put the leading "\n"
|
|
4820
|
+
// because of oneExecutionWritten becoming true
|
|
4821
|
+
renderDynamicLog(testPlanResult),
|
|
4822
|
+
);
|
|
5087
4823
|
},
|
|
5088
4824
|
afterAll: async () => {
|
|
5089
4825
|
dynamicLog.update("");
|
|
@@ -5172,6 +4908,8 @@ ${testPlanResult.patterns.join("\n")}`;
|
|
|
5172
4908
|
fileFoundLine += `${numberOfFiles} files matching "testPlan" in ${directory}`;
|
|
5173
4909
|
}
|
|
5174
4910
|
|
|
4911
|
+
// TODO: an option to log how many cpu, memory etc we'll use?
|
|
4912
|
+
|
|
5175
4913
|
lines.push(fileFoundLine);
|
|
5176
4914
|
|
|
5177
4915
|
return `${renderBigSection({
|
|
@@ -5559,7 +5297,10 @@ const renderOutro = (testPlanResult, logOptions = {}) => {
|
|
|
5559
5297
|
lines.push(memoryUsageLine);
|
|
5560
5298
|
}
|
|
5561
5299
|
|
|
5562
|
-
return `\n${renderBigSection({
|
|
5300
|
+
return `\n${renderBigSection({
|
|
5301
|
+
title: "execution end",
|
|
5302
|
+
content: lines.join("\n"),
|
|
5303
|
+
})}\n`;
|
|
5563
5304
|
};
|
|
5564
5305
|
|
|
5565
5306
|
const humanizeTiming = (value) => {
|
|
@@ -8016,6 +7757,7 @@ const nodeChildProcess = ({
|
|
|
8016
7757
|
env = {
|
|
8017
7758
|
...env,
|
|
8018
7759
|
JSENV: true,
|
|
7760
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
8019
7761
|
};
|
|
8020
7762
|
|
|
8021
7763
|
return {
|
|
@@ -8490,6 +8232,7 @@ const nodeWorkerThread = ({
|
|
|
8490
8232
|
env = {
|
|
8491
8233
|
...env,
|
|
8492
8234
|
JSENV: true,
|
|
8235
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
8493
8236
|
};
|
|
8494
8237
|
|
|
8495
8238
|
return {
|
|
@@ -57,9 +57,9 @@ const sendToParent = (type, data) => {
|
|
|
57
57
|
if (!process.connected) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
// this can keep process alive longer than
|
|
60
|
+
// this can keep process alive longer than expect
|
|
61
61
|
// when source is a long string.
|
|
62
|
-
// It means node process may stay alive longer than
|
|
62
|
+
// It means node process may stay alive longer than expect
|
|
63
63
|
// the time to send the data to the parent.
|
|
64
64
|
process.send({
|
|
65
65
|
__jsenv__: type,
|
|
@@ -29,9 +29,9 @@ const ACTIONS_AVAILABLE = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const sendToParent = (type, data) => {
|
|
32
|
-
// this can keep process alive longer than
|
|
32
|
+
// this can keep process alive longer than expect
|
|
33
33
|
// when source is a long string.
|
|
34
|
-
// It means node process may stay alive longer than
|
|
34
|
+
// It means node process may stay alive longer than expect
|
|
35
35
|
// the time to send the data to the parent.
|
|
36
36
|
parentPort.postMessage({
|
|
37
37
|
__jsenv__: type,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.14",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,26 +38,26 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@c88/v8-coverage": "0.1.1",
|
|
40
40
|
"@jsenv/abort": "4.3.0",
|
|
41
|
-
"@jsenv/ast": "6.0.
|
|
42
|
-
"@jsenv/filesystem": "4.6.
|
|
43
|
-
"@jsenv/github-check-run": "0.1.
|
|
44
|
-
"@jsenv/humanize": "1.
|
|
45
|
-
"@jsenv/plugin-supervisor": "1.4.
|
|
41
|
+
"@jsenv/ast": "6.0.4",
|
|
42
|
+
"@jsenv/filesystem": "4.6.6",
|
|
43
|
+
"@jsenv/github-check-run": "0.1.11",
|
|
44
|
+
"@jsenv/humanize": "1.1.0",
|
|
45
|
+
"@jsenv/plugin-supervisor": "1.4.4",
|
|
46
46
|
"@jsenv/url-meta": "8.4.0",
|
|
47
|
-
"@jsenv/urls": "2.2.
|
|
47
|
+
"@jsenv/urls": "2.2.4",
|
|
48
48
|
"@jsenv/utils": "2.1.1",
|
|
49
49
|
"istanbul-lib-coverage": "3.2.2",
|
|
50
|
-
"istanbul-lib-instrument": "6.0.
|
|
50
|
+
"istanbul-lib-instrument": "6.0.3",
|
|
51
51
|
"istanbul-lib-report": "3.0.1",
|
|
52
|
-
"istanbul-reports": "3.1.
|
|
52
|
+
"istanbul-reports": "3.1.7",
|
|
53
53
|
"he": "1.2.0",
|
|
54
54
|
"pidtree": "0.6.0",
|
|
55
55
|
"strip-ansi": "7.1.0",
|
|
56
|
-
"
|
|
57
|
-
"
|
|
56
|
+
"supports-color": "9.4.0",
|
|
57
|
+
"v8-to-istanbul": "9.3.0",
|
|
58
|
+
"errorstacks": "2.4.1"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"@jsenv/terminal-recorder": "../independent/terminal-recorder/"
|
|
61
|
-
"errorstacks": "2.4.1"
|
|
61
|
+
"@jsenv/terminal-recorder": "../independent/terminal-recorder/"
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -103,6 +103,7 @@ export const reporterList = ({
|
|
|
103
103
|
});
|
|
104
104
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
105
105
|
let frameIndex = 0;
|
|
106
|
+
let oneExecutionWritten = false;
|
|
106
107
|
const renderDynamicLog = (testPlanResult) => {
|
|
107
108
|
frameIndex = frameIndex === frames.length - 1 ? 0 : frameIndex + 1;
|
|
108
109
|
let dynamicLogContent = "";
|
|
@@ -135,7 +136,10 @@ export const reporterList = ({
|
|
|
135
136
|
ANSI.GREY,
|
|
136
137
|
)}${infoFormatted}${ANSI.color("]", ANSI.GREY)}`;
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
if (oneExecutionWritten) {
|
|
140
|
+
dynamicLogContent = `\n${dynamicLogContent}`;
|
|
141
|
+
}
|
|
142
|
+
dynamicLogContent = `${dynamicLogContent}\n`;
|
|
139
143
|
return dynamicLogContent;
|
|
140
144
|
};
|
|
141
145
|
dynamicLog.update(renderDynamicLog(testPlanResult));
|
|
@@ -150,10 +154,16 @@ export const reporterList = ({
|
|
|
150
154
|
});
|
|
151
155
|
},
|
|
152
156
|
afterEachInOrder: (execution) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
+
oneExecutionWritten = true;
|
|
158
|
+
dynamicLog.clearDuringFunctionCall(
|
|
159
|
+
() => {
|
|
160
|
+
const log = renderExecutionLog(execution, logOptions);
|
|
161
|
+
write(log);
|
|
162
|
+
},
|
|
163
|
+
// regenerate the dynamic log to put the leading "\n"
|
|
164
|
+
// because of oneExecutionWritten becoming true
|
|
165
|
+
renderDynamicLog(testPlanResult),
|
|
166
|
+
);
|
|
157
167
|
},
|
|
158
168
|
afterAll: async () => {
|
|
159
169
|
dynamicLog.update("");
|
|
@@ -242,6 +252,8 @@ ${testPlanResult.patterns.join("\n")}`;
|
|
|
242
252
|
fileFoundLine += `${numberOfFiles} files matching "testPlan" in ${directory}`;
|
|
243
253
|
}
|
|
244
254
|
|
|
255
|
+
// TODO: an option to log how many cpu, memory etc we'll use?
|
|
256
|
+
|
|
245
257
|
lines.push(fileFoundLine);
|
|
246
258
|
|
|
247
259
|
return `${renderBigSection({
|
|
@@ -629,7 +641,10 @@ export const renderOutro = (testPlanResult, logOptions = {}) => {
|
|
|
629
641
|
lines.push(memoryUsageLine);
|
|
630
642
|
}
|
|
631
643
|
|
|
632
|
-
return `\n${renderBigSection({
|
|
644
|
+
return `\n${renderBigSection({
|
|
645
|
+
title: "execution end",
|
|
646
|
+
content: lines.join("\n"),
|
|
647
|
+
})}\n`;
|
|
633
648
|
};
|
|
634
649
|
|
|
635
650
|
const humanizeTiming = (value) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { fork } from "node:child_process";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import supportsColor from "supports-color";
|
|
3
4
|
import { Abort, raceCallbacks } from "@jsenv/abort";
|
|
4
5
|
import { createDetailedMessage } from "@jsenv/humanize";
|
|
5
6
|
import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
|
|
@@ -36,6 +37,7 @@ export const nodeChildProcess = ({
|
|
|
36
37
|
env = {
|
|
37
38
|
...env,
|
|
38
39
|
JSENV: true,
|
|
40
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
return {
|
|
@@ -55,9 +55,9 @@ const sendToParent = (type, data) => {
|
|
|
55
55
|
if (!process.connected) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
|
-
// this can keep process alive longer than
|
|
58
|
+
// this can keep process alive longer than expect
|
|
59
59
|
// when source is a long string.
|
|
60
|
-
// It means node process may stay alive longer than
|
|
60
|
+
// It means node process may stay alive longer than expect
|
|
61
61
|
// the time to send the data to the parent.
|
|
62
62
|
process.send({
|
|
63
63
|
__jsenv__: type,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// https://github.com/avajs/ava/blob/576f534b345259055c95fa0c2b33bef10847a2af/lib/worker/base.js
|
|
4
4
|
import { Worker } from "node:worker_threads";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import supportsColor from "supports-color";
|
|
6
7
|
import { Abort, raceCallbacks } from "@jsenv/abort";
|
|
7
8
|
import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
|
|
8
9
|
|
|
@@ -32,6 +33,7 @@ export const nodeWorkerThread = ({
|
|
|
32
33
|
env = {
|
|
33
34
|
...env,
|
|
34
35
|
JSENV: true,
|
|
36
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
return {
|
|
@@ -27,9 +27,9 @@ const ACTIONS_AVAILABLE = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const sendToParent = (type, data) => {
|
|
30
|
-
// this can keep process alive longer than
|
|
30
|
+
// this can keep process alive longer than expect
|
|
31
31
|
// when source is a long string.
|
|
32
|
-
// It means node process may stay alive longer than
|
|
32
|
+
// It means node process may stay alive longer than expect
|
|
33
33
|
// the time to send the data to the parent.
|
|
34
34
|
parentPort.postMessage({
|
|
35
35
|
__jsenv__: type,
|