@jsenv/test 3.0.13 → 3.0.15
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 +95 -314
- 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 +15 -5
- 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
|
@@ -16,7 +16,7 @@ import { applyBabelPlugins } from "@jsenv/ast";
|
|
|
16
16
|
import { spawn, spawnSync, fork } from "node:child_process";
|
|
17
17
|
import { createServer } from "node:net";
|
|
18
18
|
import { injectSupervisorIntoHTML, supervisorFileUrl } from "@jsenv/plugin-supervisor";
|
|
19
|
-
import {
|
|
19
|
+
import { SOURCEMAP, generateSourcemapDataUrl } from "@jsenv/sourcemap";
|
|
20
20
|
import { findFreePort } from "@jsenv/server";
|
|
21
21
|
import { Worker } from "node:worker_threads";
|
|
22
22
|
import he from "he";
|
|
@@ -207,7 +207,7 @@ const createOperation = () => {
|
|
|
207
207
|
const operationSignal = operationAbortController.signal;
|
|
208
208
|
|
|
209
209
|
// abortCallbackList is used to ignore the max listeners warning from Node.js
|
|
210
|
-
// this warning is useful but becomes problematic when it's
|
|
210
|
+
// this warning is useful but becomes problematic when it's expect
|
|
211
211
|
// (a function doing 20 http call in parallel)
|
|
212
212
|
// To be 100% sure we don't have memory leak, only Abortable.asyncCallback
|
|
213
213
|
// uses abortCallbackList to know when something is aborted
|
|
@@ -618,170 +618,86 @@ const error = (...args) => console.error(...args);
|
|
|
618
618
|
|
|
619
619
|
const errorDisabled = () => {};
|
|
620
620
|
|
|
621
|
-
|
|
622
|
-
const OSC = '\u001B]';
|
|
623
|
-
const BEL = '\u0007';
|
|
624
|
-
const SEP = ';';
|
|
621
|
+
/* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
|
|
625
622
|
|
|
626
|
-
|
|
627
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
623
|
+
const isBrowser = globalThis.window?.document !== undefined;
|
|
628
624
|
|
|
629
|
-
|
|
630
|
-
const isWindows$3 = !isBrowser && process$1.platform === 'win32';
|
|
631
|
-
const cwdFunction = isBrowser ? () => {
|
|
632
|
-
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
633
|
-
} : process$1.cwd;
|
|
625
|
+
globalThis.process?.versions?.node !== undefined;
|
|
634
626
|
|
|
635
|
-
|
|
627
|
+
globalThis.process?.versions?.bun !== undefined;
|
|
636
628
|
|
|
637
|
-
|
|
638
|
-
if (typeof x !== 'number') {
|
|
639
|
-
throw new TypeError('The `x` argument is required');
|
|
640
|
-
}
|
|
629
|
+
globalThis.Deno?.version?.deno !== undefined;
|
|
641
630
|
|
|
642
|
-
|
|
643
|
-
return ESC + (x + 1) + 'G';
|
|
644
|
-
}
|
|
631
|
+
globalThis.process?.versions?.electron !== undefined;
|
|
645
632
|
|
|
646
|
-
|
|
647
|
-
};
|
|
633
|
+
globalThis.navigator?.userAgent?.includes('jsdom') === true;
|
|
648
634
|
|
|
649
|
-
|
|
650
|
-
if (typeof x !== 'number') {
|
|
651
|
-
throw new TypeError('The `x` argument is required');
|
|
652
|
-
}
|
|
635
|
+
typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
|
|
653
636
|
|
|
654
|
-
|
|
637
|
+
typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
655
638
|
|
|
656
|
-
|
|
657
|
-
returnValue += ESC + (-x) + 'D';
|
|
658
|
-
} else if (x > 0) {
|
|
659
|
-
returnValue += ESC + x + 'C';
|
|
660
|
-
}
|
|
639
|
+
typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
|
|
661
640
|
|
|
662
|
-
|
|
663
|
-
returnValue += ESC + (-y) + 'A';
|
|
664
|
-
} else if (y > 0) {
|
|
665
|
-
returnValue += ESC + y + 'B';
|
|
666
|
-
}
|
|
641
|
+
typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
|
|
667
642
|
|
|
668
|
-
|
|
669
|
-
|
|
643
|
+
// Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
|
|
644
|
+
const platform = globalThis.navigator?.userAgentData?.platform;
|
|
645
|
+
|
|
646
|
+
platform === 'macOS'
|
|
647
|
+
|| globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
|
|
648
|
+
|| globalThis.navigator?.userAgent?.includes(' Mac ') === true
|
|
649
|
+
|| globalThis.process?.platform === 'darwin';
|
|
650
|
+
|
|
651
|
+
platform === 'Windows'
|
|
652
|
+
|| globalThis.navigator?.platform === 'Win32'
|
|
653
|
+
|| globalThis.process?.platform === 'win32';
|
|
670
654
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
655
|
+
platform === 'Linux'
|
|
656
|
+
|| globalThis.navigator?.platform?.startsWith('Linux') === true
|
|
657
|
+
|| globalThis.navigator?.userAgent?.includes(' Linux ') === true
|
|
658
|
+
|| globalThis.process?.platform === 'linux';
|
|
675
659
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
ansiEscapes.cursorNextLine = ESC + 'E';
|
|
681
|
-
ansiEscapes.cursorPrevLine = ESC + 'F';
|
|
682
|
-
ansiEscapes.cursorHide = ESC + '?25l';
|
|
683
|
-
ansiEscapes.cursorShow = ESC + '?25h';
|
|
660
|
+
platform === 'Android'
|
|
661
|
+
|| globalThis.navigator?.platform === 'Android'
|
|
662
|
+
|| globalThis.navigator?.userAgent?.includes(' Android ') === true
|
|
663
|
+
|| globalThis.process?.platform === 'android';
|
|
684
664
|
|
|
685
|
-
|
|
665
|
+
const ESC = '\u001B[';
|
|
666
|
+
|
|
667
|
+
!isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
|
|
668
|
+
const isWindows$3 = !isBrowser && process$1.platform === 'win32';
|
|
669
|
+
|
|
670
|
+
isBrowser ? () => {
|
|
671
|
+
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
|
|
672
|
+
} : process$1.cwd;
|
|
673
|
+
|
|
674
|
+
const cursorUp = (count = 1) => ESC + count + 'A';
|
|
675
|
+
|
|
676
|
+
const cursorLeft = ESC + 'G';
|
|
677
|
+
|
|
678
|
+
const eraseLines = count => {
|
|
686
679
|
let clear = '';
|
|
687
680
|
|
|
688
681
|
for (let i = 0; i < count; i++) {
|
|
689
|
-
clear +=
|
|
682
|
+
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
|
|
690
683
|
}
|
|
691
684
|
|
|
692
685
|
if (count) {
|
|
693
|
-
clear +=
|
|
686
|
+
clear += cursorLeft;
|
|
694
687
|
}
|
|
695
688
|
|
|
696
689
|
return clear;
|
|
697
690
|
};
|
|
691
|
+
const eraseLine = ESC + '2K';
|
|
692
|
+
const eraseScreen = ESC + '2J';
|
|
698
693
|
|
|
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`
|
|
694
|
+
const clearTerminal = isWindows$3
|
|
695
|
+
? `${eraseScreen}${ESC}0f`
|
|
712
696
|
// 1. Erases the screen (Only done in case `2` is not supported)
|
|
713
697
|
// 2. Erases the whole screen including scrollback buffer
|
|
714
698
|
// 3. Moves cursor to the top-left position
|
|
715
699
|
// 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
|
-
};
|
|
700
|
+
: `${eraseScreen}${ESC}3J${ESC}H`;
|
|
785
701
|
|
|
786
702
|
/*
|
|
787
703
|
* see also https://github.com/vadimdemedes/ink
|
|
@@ -829,7 +745,7 @@ const createDynamicLog = ({
|
|
|
829
745
|
if (visualLineCount > rows) {
|
|
830
746
|
if (clearTerminalAllowed) {
|
|
831
747
|
clearAttemptResult = true;
|
|
832
|
-
return
|
|
748
|
+
return clearTerminal;
|
|
833
749
|
}
|
|
834
750
|
// the whole log cannot be cleared because it's vertically to long
|
|
835
751
|
// (longer than terminal height)
|
|
@@ -842,7 +758,7 @@ const createDynamicLog = ({
|
|
|
842
758
|
}
|
|
843
759
|
|
|
844
760
|
clearAttemptResult = true;
|
|
845
|
-
return
|
|
761
|
+
return eraseLines(visualLineCount);
|
|
846
762
|
};
|
|
847
763
|
|
|
848
764
|
const update = (string) => {
|
|
@@ -871,20 +787,22 @@ const createDynamicLog = ({
|
|
|
871
787
|
clearAttemptResult = undefined;
|
|
872
788
|
};
|
|
873
789
|
|
|
874
|
-
const clearDuringFunctionCall = (
|
|
790
|
+
const clearDuringFunctionCall = (
|
|
791
|
+
callback,
|
|
792
|
+
ouputAfterCallback = lastOutput,
|
|
793
|
+
) => {
|
|
875
794
|
// 1. Erase the current log
|
|
876
|
-
// 2. Call callback (
|
|
795
|
+
// 2. Call callback (expect to write something on stdout)
|
|
877
796
|
// 3. Restore the current log
|
|
878
797
|
// During step 2. we expect a "write from outside" so we uninstall
|
|
879
798
|
// the stream spy during function call
|
|
880
|
-
const currentOutput = lastOutput;
|
|
881
799
|
update("");
|
|
882
800
|
|
|
883
801
|
writing = true;
|
|
884
802
|
callback();
|
|
885
803
|
writing = false;
|
|
886
804
|
|
|
887
|
-
update(
|
|
805
|
+
update(ouputAfterCallback);
|
|
888
806
|
};
|
|
889
807
|
|
|
890
808
|
const writeFromOutsideEffect = (value) => {
|
|
@@ -1139,10 +1057,10 @@ function createSupportsColor(stream, options = {}) {
|
|
|
1139
1057
|
return translateLevel(level);
|
|
1140
1058
|
}
|
|
1141
1059
|
|
|
1142
|
-
|
|
1060
|
+
const supportsColor = {
|
|
1143
1061
|
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
|
|
1144
1062
|
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
|
|
1145
|
-
}
|
|
1063
|
+
};
|
|
1146
1064
|
|
|
1147
1065
|
const processSupportsBasicColor = createSupportsColor(process.stdout).hasBasic;
|
|
1148
1066
|
// https://github.com/Marak/colors.js/blob/master/lib/styles.js
|
|
@@ -1157,14 +1075,19 @@ const ANSI = {
|
|
|
1157
1075
|
YELLOW: "\x1b[33m",
|
|
1158
1076
|
BLUE: "\x1b[34m",
|
|
1159
1077
|
MAGENTA: "\x1b[35m",
|
|
1078
|
+
CYAN: "\x1b[36m",
|
|
1160
1079
|
GREY: "\x1b[90m",
|
|
1161
1080
|
color: (text, ANSI_COLOR) => {
|
|
1162
|
-
return ANSI.supported ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
1081
|
+
return ANSI.supported && ANSI_COLOR ? `${ANSI_COLOR}${text}${RESET}` : text;
|
|
1163
1082
|
},
|
|
1164
1083
|
|
|
1165
1084
|
BOLD: "\x1b[1m",
|
|
1085
|
+
UNDERLINE: "\x1b[4m",
|
|
1086
|
+
STRIKE: "\x1b[9m",
|
|
1166
1087
|
effect: (text, ANSI_EFFECT) => {
|
|
1167
|
-
return ANSI.supported
|
|
1088
|
+
return ANSI.supported && ANSI_EFFECT
|
|
1089
|
+
? `${ANSI_EFFECT}${text}${RESET}`
|
|
1090
|
+
: text;
|
|
1168
1091
|
},
|
|
1169
1092
|
};
|
|
1170
1093
|
|
|
@@ -1432,6 +1355,9 @@ const UNICODE = {
|
|
|
1432
1355
|
get CIRCLE_CROSS() {
|
|
1433
1356
|
return ANSI.color(UNICODE.CIRCLE_CROSS_RAW, ANSI.RED);
|
|
1434
1357
|
},
|
|
1358
|
+
get ELLIPSIS() {
|
|
1359
|
+
return UNICODE.supported ? `…` : `...`;
|
|
1360
|
+
},
|
|
1435
1361
|
};
|
|
1436
1362
|
|
|
1437
1363
|
const createDetailedMessage = (message, details = {}) => {
|
|
@@ -2078,7 +2004,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2078
2004
|
try {
|
|
2079
2005
|
url = String(new URL(url));
|
|
2080
2006
|
} catch (e) {
|
|
2081
|
-
throw new Error(`absolute url
|
|
2007
|
+
throw new Error(`absolute url expect but got ${url}`);
|
|
2082
2008
|
}
|
|
2083
2009
|
|
|
2084
2010
|
if (!isWindows$2) {
|
|
@@ -2089,7 +2015,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2089
2015
|
baseUrl = String(new URL(baseUrl));
|
|
2090
2016
|
} catch (e) {
|
|
2091
2017
|
throw new Error(
|
|
2092
|
-
`absolute baseUrl
|
|
2018
|
+
`absolute baseUrl expect but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
2093
2019
|
);
|
|
2094
2020
|
}
|
|
2095
2021
|
|
|
@@ -2111,7 +2037,7 @@ const ensureWindowsDriveLetter = (url, baseUrl) => {
|
|
|
2111
2037
|
);
|
|
2112
2038
|
if (!driveLetter) {
|
|
2113
2039
|
throw new Error(
|
|
2114
|
-
`drive letter
|
|
2040
|
+
`drive letter expect on baseUrl but got ${baseUrl} to ensure windows drive letter on ${url}`,
|
|
2115
2041
|
);
|
|
2116
2042
|
}
|
|
2117
2043
|
return `file:///${driveLetter}:${afterProtocol}`;
|
|
@@ -2162,67 +2088,11 @@ const readDirectory = async (url, { emfileMaxWait = 1000 } = {}) => {
|
|
|
2162
2088
|
return attempt();
|
|
2163
2089
|
};
|
|
2164
2090
|
|
|
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
2091
|
const writeEntryPermissions = async (source, permissions) => {
|
|
2199
2092
|
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2200
2093
|
|
|
2201
2094
|
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 {
|
|
2095
|
+
{
|
|
2226
2096
|
binaryFlags = permissions;
|
|
2227
2097
|
}
|
|
2228
2098
|
|
|
@@ -2237,45 +2107,6 @@ const writeEntryPermissions = async (source, permissions) => {
|
|
|
2237
2107
|
});
|
|
2238
2108
|
};
|
|
2239
2109
|
|
|
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
2110
|
/*
|
|
2280
2111
|
* - stats object documentation on Node.js
|
|
2281
2112
|
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
@@ -2812,75 +2643,13 @@ const writeEntryPermissionsSync = (source, permissions) => {
|
|
|
2812
2643
|
const sourceUrl = assertAndNormalizeFileUrl(source);
|
|
2813
2644
|
|
|
2814
2645
|
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 {
|
|
2646
|
+
{
|
|
2839
2647
|
binaryFlags = permissions;
|
|
2840
2648
|
}
|
|
2841
2649
|
|
|
2842
2650
|
chmodSync(new URL(sourceUrl), binaryFlags);
|
|
2843
2651
|
};
|
|
2844
2652
|
|
|
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
2653
|
/*
|
|
2885
2654
|
* - stats object documentation on Node.js
|
|
2886
2655
|
* https://nodejs.org/docs/latest-v13.x/api/fs.html#fs_class_fs_stats
|
|
@@ -5033,6 +4802,7 @@ const reporterList = ({
|
|
|
5033
4802
|
});
|
|
5034
4803
|
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
5035
4804
|
let frameIndex = 0;
|
|
4805
|
+
let oneExecutionWritten = false;
|
|
5036
4806
|
const renderDynamicLog = (testPlanResult) => {
|
|
5037
4807
|
frameIndex = frameIndex === frames.length - 1 ? 0 : frameIndex + 1;
|
|
5038
4808
|
let dynamicLogContent = "";
|
|
@@ -5065,7 +4835,10 @@ const reporterList = ({
|
|
|
5065
4835
|
ANSI.GREY,
|
|
5066
4836
|
)}${infoFormatted}${ANSI.color("]", ANSI.GREY)}`;
|
|
5067
4837
|
|
|
5068
|
-
|
|
4838
|
+
if (oneExecutionWritten) {
|
|
4839
|
+
dynamicLogContent = `\n${dynamicLogContent}`;
|
|
4840
|
+
}
|
|
4841
|
+
dynamicLogContent = `${dynamicLogContent}\n`;
|
|
5069
4842
|
return dynamicLogContent;
|
|
5070
4843
|
};
|
|
5071
4844
|
dynamicLog.update(renderDynamicLog(testPlanResult));
|
|
@@ -5080,10 +4853,16 @@ const reporterList = ({
|
|
|
5080
4853
|
});
|
|
5081
4854
|
},
|
|
5082
4855
|
afterEachInOrder: (execution) => {
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
4856
|
+
oneExecutionWritten = true;
|
|
4857
|
+
dynamicLog.clearDuringFunctionCall(
|
|
4858
|
+
() => {
|
|
4859
|
+
const log = renderExecutionLog(execution, logOptions);
|
|
4860
|
+
write(log);
|
|
4861
|
+
},
|
|
4862
|
+
// regenerate the dynamic log to put the leading "\n"
|
|
4863
|
+
// because of oneExecutionWritten becoming true
|
|
4864
|
+
renderDynamicLog(testPlanResult),
|
|
4865
|
+
);
|
|
5087
4866
|
},
|
|
5088
4867
|
afterAll: async () => {
|
|
5089
4868
|
dynamicLog.update("");
|
|
@@ -8021,6 +7800,7 @@ const nodeChildProcess = ({
|
|
|
8021
7800
|
env = {
|
|
8022
7801
|
...env,
|
|
8023
7802
|
JSENV: true,
|
|
7803
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
8024
7804
|
};
|
|
8025
7805
|
|
|
8026
7806
|
return {
|
|
@@ -8495,6 +8275,7 @@ const nodeWorkerThread = ({
|
|
|
8495
8275
|
env = {
|
|
8496
8276
|
...env,
|
|
8497
8277
|
JSENV: true,
|
|
8278
|
+
FORCE_COLOR: supportsColor.stdout,
|
|
8498
8279
|
};
|
|
8499
8280
|
|
|
8500
8281
|
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.15",
|
|
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("");
|
|
@@ -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,
|