@jsenv/test 3.6.6 → 3.6.8

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.
@@ -1,15 +1,15 @@
1
1
  import { readGitHubWorkflowEnv, startGithubCheckRun } from "@jsenv/github-check-run";
2
- import process$1, { cpuUsage, memoryUsage } from "node:process";
3
- import os, { cpus, totalmem, release, availableParallelism, freemem } from "node:os";
4
- import tty from "node:tty";
5
- import stringWidth from "string-width";
6
2
  import { applyNodeEsmResolution } from "@jsenv/node-esm-resolution";
3
+ import { startMonitoringCpuUsage, startMonitoringMemoryUsage, getAvailableMemory, countAvailableCpus, getOsVersion } from "@jsenv/os-metrics";
7
4
  import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, readdirSync, openSync, closeSync, unlinkSync, rmdirSync, mkdirSync, readFileSync, writeFileSync as writeFileSync$1, unlink, rmdir, existsSync } from "node:fs";
8
5
  import { takeCoverage } from "node:v8";
9
6
  import stripAnsi from "strip-ansi";
10
7
  import { pathToFileURL, fileURLToPath } from "node:url";
11
8
  import { createRequire } from "node:module";
12
9
  import { applyBabelPlugins } from "@jsenv/ast";
10
+ import { memoryUsage } from "node:process";
11
+ import { createSupportsColor, isUnicodeSupported, clearTerminal, eraseLines } from "./jsenv_test_node_modules.js";
12
+ import { measureTextWidth } from "@jsenv/terminal-text-size";
13
13
  import { createException } from "@jsenv/exception";
14
14
  import crypto from "node:crypto";
15
15
  import { dirname } from "node:path";
@@ -20,6 +20,8 @@ import { injectSupervisorIntoHTML, supervisorFileUrl } from "@jsenv/plugin-super
20
20
  import { findFreePort } from "@jsenv/server";
21
21
  import { Worker } from "node:worker_threads";
22
22
  import he from "he";
23
+ import "node:os";
24
+ import "node:tty";
23
25
 
24
26
  const createCallbackListNotifiedOnce = () => {
25
27
  let callbacks = [];
@@ -530,329 +532,86 @@ const SIGINT_CALLBACK = {
530
532
  },
531
533
  };
532
534
 
533
- // From: https://github.com/sindresorhus/has-flag/blob/main/index.js
534
- /// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
535
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
536
- const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
537
- const position = argv.indexOf(prefix + flag);
538
- const terminatorPosition = argv.indexOf('--');
539
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
540
- }
541
-
542
- const {env} = process$1;
543
-
544
- let flagForceColor;
545
- if (
546
- hasFlag('no-color')
547
- || hasFlag('no-colors')
548
- || hasFlag('color=false')
549
- || hasFlag('color=never')
550
- ) {
551
- flagForceColor = 0;
552
- } else if (
553
- hasFlag('color')
554
- || hasFlag('colors')
555
- || hasFlag('color=true')
556
- || hasFlag('color=always')
557
- ) {
558
- flagForceColor = 1;
559
- }
560
-
561
- function envForceColor() {
562
- if (!('FORCE_COLOR' in env)) {
563
- return;
564
- }
565
-
566
- if (env.FORCE_COLOR === 'true') {
567
- return 1;
568
- }
569
-
570
- if (env.FORCE_COLOR === 'false') {
571
- return 0;
572
- }
573
-
574
- if (env.FORCE_COLOR.length === 0) {
575
- return 1;
576
- }
577
-
578
- const level = Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
579
-
580
- if (![0, 1, 2, 3].includes(level)) {
581
- return;
582
- }
583
-
584
- return level;
585
- }
586
-
587
- function translateLevel(level) {
588
- if (level === 0) {
589
- return false;
590
- }
591
-
592
- return {
593
- level,
594
- hasBasic: true,
595
- has256: level >= 2,
596
- has16m: level >= 3,
597
- };
598
- }
599
-
600
- function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
601
- const noFlagForceColor = envForceColor();
602
- if (noFlagForceColor !== undefined) {
603
- flagForceColor = noFlagForceColor;
604
- }
605
-
606
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
607
-
608
- if (forceColor === 0) {
609
- return 0;
610
- }
611
-
612
- if (sniffFlags) {
613
- if (hasFlag('color=16m')
614
- || hasFlag('color=full')
615
- || hasFlag('color=truecolor')) {
616
- return 3;
617
- }
618
-
619
- if (hasFlag('color=256')) {
620
- return 2;
621
- }
622
- }
623
-
624
- // Check for Azure DevOps pipelines.
625
- // Has to be above the `!streamIsTTY` check.
626
- if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
627
- return 1;
628
- }
629
-
630
- if (haveStream && !streamIsTTY && forceColor === undefined) {
631
- return 0;
632
- }
633
-
634
- const min = forceColor || 0;
635
-
636
- if (env.TERM === 'dumb') {
637
- return min;
638
- }
639
-
640
- if (process$1.platform === 'win32') {
641
- // Windows 10 build 10586 is the first Windows release that supports 256 colors.
642
- // Windows 10 build 14931 is the first release that supports 16m/TrueColor.
643
- const osRelease = os.release().split('.');
644
- if (
645
- Number(osRelease[0]) >= 10
646
- && Number(osRelease[2]) >= 10_586
647
- ) {
648
- return Number(osRelease[2]) >= 14_931 ? 3 : 2;
649
- }
650
-
651
- return 1;
652
- }
653
-
654
- if ('CI' in env) {
655
- if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
656
- return 3;
657
- }
658
-
659
- if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
660
- return 1;
661
- }
662
-
663
- return min;
664
- }
665
-
666
- if ('TEAMCITY_VERSION' in env) {
667
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
668
- }
669
-
670
- if (env.COLORTERM === 'truecolor') {
671
- return 3;
672
- }
673
-
674
- if (env.TERM === 'xterm-kitty') {
675
- return 3;
676
- }
677
-
678
- if ('TERM_PROGRAM' in env) {
679
- const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
680
-
681
- switch (env.TERM_PROGRAM) {
682
- case 'iTerm.app': {
683
- return version >= 3 ? 3 : 2;
684
- }
685
-
686
- case 'Apple_Terminal': {
687
- return 2;
688
- }
689
- // No default
690
- }
691
- }
692
-
693
- if (/-256(color)?$/i.test(env.TERM)) {
694
- return 2;
695
- }
696
-
697
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
698
- return 1;
699
- }
700
-
701
- if ('COLORTERM' in env) {
702
- return 1;
703
- }
704
-
705
- return min;
706
- }
707
-
708
- function createSupportsColor(stream, options = {}) {
709
- const level = _supportsColor(stream, {
710
- streamIsTTY: stream && stream.isTTY,
711
- ...options,
712
- });
713
-
714
- return translateLevel(level);
715
- }
716
-
717
- ({
718
- stdout: createSupportsColor({isTTY: tty.isatty(1)}),
719
- stderr: createSupportsColor({isTTY: tty.isatty(2)}),
720
- });
721
-
722
- function isUnicodeSupported() {
723
- const {env} = process$1;
724
- const {TERM, TERM_PROGRAM} = env;
725
-
726
- if (process$1.platform !== 'win32') {
727
- return TERM !== 'linux'; // Linux console (kernel)
728
- }
729
-
730
- return Boolean(env.WT_SESSION) // Windows Terminal
731
- || Boolean(env.TERMINUS_SUBLIME) // Terminus (<0.2.27)
732
- || env.ConEmuTask === '{cmd::Cmder}' // ConEmu and cmder
733
- || TERM_PROGRAM === 'Terminus-Sublime'
734
- || TERM_PROGRAM === 'vscode'
735
- || TERM === 'xterm-256color'
736
- || TERM === 'alacritty'
737
- || TERM === 'rxvt-unicode'
738
- || TERM === 'rxvt-unicode-256color'
739
- || env.TERMINAL_EMULATOR === 'JetBrains-JediTerm';
740
- }
741
-
742
- /* globals WorkerGlobalScope, DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope */
743
-
744
- const isBrowser = globalThis.window?.document !== undefined;
745
-
746
- globalThis.process?.versions?.node !== undefined;
747
-
748
- globalThis.process?.versions?.bun !== undefined;
749
-
750
- globalThis.Deno?.version?.deno !== undefined;
751
-
752
- globalThis.process?.versions?.electron !== undefined;
753
-
754
- globalThis.navigator?.userAgent?.includes('jsdom') === true;
755
-
756
- typeof WorkerGlobalScope !== 'undefined' && globalThis instanceof WorkerGlobalScope;
757
-
758
- typeof DedicatedWorkerGlobalScope !== 'undefined' && globalThis instanceof DedicatedWorkerGlobalScope;
759
-
760
- typeof SharedWorkerGlobalScope !== 'undefined' && globalThis instanceof SharedWorkerGlobalScope;
761
-
762
- typeof ServiceWorkerGlobalScope !== 'undefined' && globalThis instanceof ServiceWorkerGlobalScope;
763
-
764
- // Note: I'm intentionally not DRYing up the other variables to keep them "lazy".
765
- const platform = globalThis.navigator?.userAgentData?.platform;
766
-
767
- platform === 'macOS'
768
- || globalThis.navigator?.platform === 'MacIntel' // Even on Apple silicon Macs.
769
- || globalThis.navigator?.userAgent?.includes(' Mac ') === true
770
- || globalThis.process?.platform === 'darwin';
771
-
772
- platform === 'Windows'
773
- || globalThis.navigator?.platform === 'Win32'
774
- || globalThis.process?.platform === 'win32';
775
-
776
- platform === 'Linux'
777
- || globalThis.navigator?.platform?.startsWith('Linux') === true
778
- || globalThis.navigator?.userAgent?.includes(' Linux ') === true
779
- || globalThis.process?.platform === 'linux';
780
-
781
- platform === 'Android'
782
- || globalThis.navigator?.platform === 'Android'
783
- || globalThis.navigator?.userAgent?.includes(' Android ') === true
784
- || globalThis.process?.platform === 'android';
785
-
786
- const ESC = '\u001B[';
787
-
788
- !isBrowser && process$1.env.TERM_PROGRAM === 'Apple_Terminal';
789
- const isWindows$3 = !isBrowser && process$1.platform === 'win32';
790
-
791
- isBrowser ? () => {
792
- throw new Error('`process.cwd()` only works in Node.js, not the browser.');
793
- } : process$1.cwd;
794
-
795
- const cursorUp = (count = 1) => ESC + count + 'A';
796
-
797
- const cursorLeft = ESC + 'G';
798
-
799
- const eraseLines = count => {
800
- let clear = '';
801
-
802
- for (let i = 0; i < count; i++) {
803
- clear += eraseLine + (i < count - 1 ? cursorUp() : '');
804
- }
805
-
806
- if (count) {
807
- clear += cursorLeft;
808
- }
809
-
810
- return clear;
811
- };
812
- const eraseLine = ESC + '2K';
813
- const eraseScreen = ESC + '2J';
814
-
815
- const clearTerminal = isWindows$3
816
- ? `${eraseScreen}${ESC}0f`
817
- // 1. Erases the screen (Only done in case `2` is not supported)
818
- // 2. Erases the whole screen including scrollback buffer
819
- // 3. Moves cursor to the top-left position
820
- // More info: https://www.real-world-systems.com/docs/ANSIcode.html
821
- : `${eraseScreen}${ESC}3J${ESC}H`;
822
-
823
535
  const createDetailedMessage = (message, details = {}) => {
824
- let string = `${message}`;
536
+ let text = `${message}`;
537
+ const namedSectionsText = renderNamedSections(details);
538
+ if (namedSectionsText) {
539
+ text += `
540
+ ${namedSectionsText}`;
541
+ }
542
+ return text;
543
+ };
825
544
 
826
- Object.keys(details).forEach((key) => {
827
- const value = details[key];
828
- string += `
829
- --- ${key} ---
545
+ const renderNamedSections = (namedSections) => {
546
+ let text = "";
547
+ let keys = Object.keys(namedSections);
548
+ for (const key of keys) {
549
+ const isLastKey = key === keys[keys.length - 1];
550
+ const value = namedSections[key];
551
+ text += `--- ${key} ---
830
552
  ${
831
553
  Array.isArray(value)
832
554
  ? value.join(`
833
555
  `)
834
556
  : value
835
557
  }`;
836
- });
837
-
838
- return string;
558
+ if (!isLastKey) {
559
+ text += "\n";
560
+ }
561
+ }
562
+ return text;
839
563
  };
840
564
 
841
565
  // https://github.com/Marak/colors.js/blob/master/lib/styles.js
842
566
  // https://stackoverflow.com/a/75985833/2634179
843
567
  const RESET = "\x1b[0m";
844
568
 
569
+ const RED = "red";
570
+ const GREEN = "green";
571
+ const YELLOW = "yellow";
572
+ const BLUE = "blue";
573
+ const MAGENTA = "magenta";
574
+ const CYAN = "cyan";
575
+ const GREY = "grey";
576
+ const WHITE = "white";
577
+ const BLACK = "black";
578
+
579
+ const TEXT_COLOR_ANSI_CODES = {
580
+ [RED]: "\x1b[31m",
581
+ [GREEN]: "\x1b[32m",
582
+ [YELLOW]: "\x1b[33m",
583
+ [BLUE]: "\x1b[34m",
584
+ [MAGENTA]: "\x1b[35m",
585
+ [CYAN]: "\x1b[36m",
586
+ [GREY]: "\x1b[90m",
587
+ [WHITE]: "\x1b[37m",
588
+ [BLACK]: "\x1b[30m",
589
+ };
590
+ const BACKGROUND_COLOR_ANSI_CODES = {
591
+ [RED]: "\x1b[41m",
592
+ [GREEN]: "\x1b[42m",
593
+ [YELLOW]: "\x1b[43m",
594
+ [BLUE]: "\x1b[44m",
595
+ [MAGENTA]: "\x1b[45m",
596
+ [CYAN]: "\x1b[46m",
597
+ [GREY]: "\x1b[100m",
598
+ [WHITE]: "\x1b[47m",
599
+ [BLACK]: "\x1b[40m",
600
+ };
601
+
845
602
  const createAnsi = ({ supported }) => {
846
603
  const ANSI = {
847
604
  supported,
848
605
 
849
- RED: "\x1b[31m",
850
- GREEN: "\x1b[32m",
851
- YELLOW: "\x1b[33m",
852
- BLUE: "\x1b[34m",
853
- MAGENTA: "\x1b[35m",
854
- CYAN: "\x1b[36m",
855
- GREY: "\x1b[90m",
606
+ RED,
607
+ GREEN,
608
+ YELLOW,
609
+ BLUE,
610
+ MAGENTA,
611
+ CYAN,
612
+ GREY,
613
+ WHITE,
614
+ BLACK,
856
615
  color: (text, color) => {
857
616
  if (!ANSI.supported) {
858
617
  return text;
@@ -864,7 +623,29 @@ const createAnsi = ({ supported }) => {
864
623
  // cannot set color of blank chars
865
624
  return text;
866
625
  }
867
- return `${color}${text}${RESET}`;
626
+ const ansiEscapeCodeForTextColor = TEXT_COLOR_ANSI_CODES[color];
627
+ if (!ansiEscapeCodeForTextColor) {
628
+ return text;
629
+ }
630
+ return `${ansiEscapeCodeForTextColor}${text}${RESET}`;
631
+ },
632
+ backgroundColor: (text, color) => {
633
+ if (!ANSI.supported) {
634
+ return text;
635
+ }
636
+ if (!color) {
637
+ return text;
638
+ }
639
+ if (typeof text === "string" && text.trim() === "") {
640
+ // cannot set background color of blank chars
641
+ return text;
642
+ }
643
+ const ansiEscapeCodeForBackgroundColor =
644
+ BACKGROUND_COLOR_ANSI_CODES[color];
645
+ if (!ansiEscapeCodeForBackgroundColor) {
646
+ return text;
647
+ }
648
+ return `${ansiEscapeCodeForBackgroundColor}${text}${RESET}`;
868
649
  },
869
650
 
870
651
  BOLD: "\x1b[1m",
@@ -881,7 +662,8 @@ const createAnsi = ({ supported }) => {
881
662
  if (text === "") {
882
663
  return text;
883
664
  }
884
- return `${effect}${text}${RESET}`;
665
+ const ansiEscapeCodeForEffect = effect;
666
+ return `${ansiEscapeCodeForEffect}${text}${RESET}`;
885
667
  },
886
668
  };
887
669
 
@@ -1012,6 +794,23 @@ const setDecimalsPrecision = (
1012
794
  const asFloat = asInteger / coef;
1013
795
  return number < 0 ? -asFloat : asFloat;
1014
796
  };
797
+
798
+ // https://www.codingem.com/javascript-how-to-limit-decimal-places/
799
+ // export const roundNumber = (number, maxDecimals) => {
800
+ // const decimalsExp = Math.pow(10, maxDecimals)
801
+ // const numberRoundInt = Math.round(decimalsExp * (number + Number.EPSILON))
802
+ // const numberRoundFloat = numberRoundInt / decimalsExp
803
+ // return numberRoundFloat
804
+ // }
805
+
806
+ // export const setPrecision = (number, precision) => {
807
+ // if (Math.floor(number) === number) return number
808
+ // const [int, decimals] = number.toString().split(".")
809
+ // if (precision <= 0) return int
810
+ // const numberTruncated = `${int}.${decimals.slice(0, precision)}`
811
+ // return numberTruncated
812
+ // }
813
+
1015
814
  const unitShort = {
1016
815
  year: "y",
1017
816
  month: "m",
@@ -1334,6 +1133,119 @@ const fillLeft$1 = (value, biggestValue, char = " ") => {
1334
1133
  return padded;
1335
1134
  };
1336
1135
 
1136
+ const createCallOrderer = () => {
1137
+ const queue = [];
1138
+ const callWhenPreviousExecutionAreDone = (executionIndex, callback) => {
1139
+ if (queue[executionIndex]) {
1140
+ throw new Error(`${executionIndex} already used`);
1141
+ }
1142
+
1143
+ let allBeforeAreDone = true;
1144
+ if (executionIndex > 0) {
1145
+ let beforeIndex = executionIndex - 1;
1146
+ do {
1147
+ const value = queue[beforeIndex];
1148
+ if (!value) {
1149
+ allBeforeAreDone = false;
1150
+ break;
1151
+ }
1152
+ } while (beforeIndex--);
1153
+ }
1154
+ if (!allBeforeAreDone) {
1155
+ queue[executionIndex] = callback;
1156
+ return;
1157
+ }
1158
+ queue[executionIndex] = true;
1159
+ callback();
1160
+ let afterIndex = executionIndex + 1;
1161
+ while (afterIndex < queue.length) {
1162
+ const value = queue[afterIndex];
1163
+ if (value === undefined) {
1164
+ break;
1165
+ }
1166
+ if (typeof value === "function") {
1167
+ queue[afterIndex] = true;
1168
+ value();
1169
+ }
1170
+ afterIndex++;
1171
+ }
1172
+ };
1173
+ return callWhenPreviousExecutionAreDone;
1174
+ };
1175
+
1176
+ const renderBigSection = (params) => {
1177
+ return renderSection({
1178
+ width: 45,
1179
+ ...params,
1180
+ });
1181
+ };
1182
+
1183
+ const renderSection = ({
1184
+ title,
1185
+ content,
1186
+ dashColor = ANSI.GREY,
1187
+ width = 38,
1188
+ bottomSeparator = true,
1189
+ }) => {
1190
+ let section = "";
1191
+
1192
+ if (title) {
1193
+ const titleWidth = stripAnsi(title).length;
1194
+ const minWidthRequired = `--- … ---`.length;
1195
+ const needsTruncate = titleWidth + minWidthRequired >= width;
1196
+ if (needsTruncate) {
1197
+ const titleTruncated = title.slice(0, width - minWidthRequired);
1198
+ const leftDashes = ANSI.color("---", dashColor);
1199
+ const rightDashes = ANSI.color("---", dashColor);
1200
+ section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
1201
+ } else {
1202
+ const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
1203
+ const dashLeftCount = Math.floor(remainingWidth / 2);
1204
+ const dashRightCount = remainingWidth - dashLeftCount;
1205
+ const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
1206
+ const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
1207
+ section += `${leftDashes} ${title} ${rightDashes}`;
1208
+ }
1209
+ section += "\n";
1210
+ } else {
1211
+ const topDashes = ANSI.color(`-`.repeat(width), dashColor);
1212
+ section += topDashes;
1213
+ section += "\n";
1214
+ }
1215
+ section += `${content}`;
1216
+ if (bottomSeparator) {
1217
+ section += "\n";
1218
+ const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
1219
+ section += bottomDashes;
1220
+ }
1221
+ return section;
1222
+ };
1223
+
1224
+ const renderDetails = (data) => {
1225
+ const details = [];
1226
+ for (const key of Object.keys(data)) {
1227
+ const value = data[key];
1228
+ let valueString = "";
1229
+ valueString += ANSI.color(`${key}:`, ANSI.GREY);
1230
+ const useNonGreyAnsiColor =
1231
+ typeof value === "string" && value.includes("\x1b");
1232
+ valueString += " ";
1233
+ valueString += useNonGreyAnsiColor
1234
+ ? value
1235
+ : ANSI.color(String(value), ANSI.GREY);
1236
+ details.push(valueString);
1237
+ }
1238
+ if (details.length === 0) {
1239
+ return "";
1240
+ }
1241
+
1242
+ let string = "";
1243
+ string += ` ${ANSI.color("(", ANSI.GREY)}`;
1244
+ string += details.join(ANSI.color(", ", ANSI.GREY));
1245
+ string += ANSI.color(")", ANSI.GREY);
1246
+ return string;
1247
+ };
1248
+
1337
1249
  const LOG_LEVEL_OFF = "off";
1338
1250
 
1339
1251
  const LOG_LEVEL_DEBUG = "debug";
@@ -1457,7 +1369,7 @@ const createDynamicLog = ({
1457
1369
  const logLines = lastOutput.split(/\r\n|\r|\n/);
1458
1370
  let visualLineCount = 0;
1459
1371
  for (const logLine of logLines) {
1460
- const width = stringWidth(logLine);
1372
+ const width = measureTextWidth(logLine);
1461
1373
  if (width === 0) {
1462
1374
  visualLineCount++;
1463
1375
  } else {
@@ -1522,7 +1434,8 @@ const createDynamicLog = ({
1522
1434
  update("");
1523
1435
 
1524
1436
  writing = true;
1525
- callback();
1437
+ callback(update);
1438
+ lastOutput = "";
1526
1439
  writing = false;
1527
1440
 
1528
1441
  update(ouputAfterCallback);
@@ -2491,9 +2404,19 @@ const applyPatternMatching = ({ url, pattern }) => {
2491
2404
  return applyPattern({ url, pattern });
2492
2405
  };
2493
2406
 
2494
- const resolveAssociations = (associations, baseUrl) => {
2495
- if (baseUrl && typeof baseUrl.href === "string") baseUrl = baseUrl.href;
2496
- assertUrlLike(baseUrl, "baseUrl");
2407
+ const resolveAssociations = (associations, resolver) => {
2408
+ let resolve = () => {};
2409
+ if (typeof resolver === "function") {
2410
+ resolve = resolver;
2411
+ } else if (typeof resolver === "string") {
2412
+ const baseUrl = resolver;
2413
+ assertUrlLike(baseUrl, "baseUrl");
2414
+ resolve = (pattern) => new URL(pattern, baseUrl).href;
2415
+ } else if (resolver && typeof resolver.href === "string") {
2416
+ const baseUrl = resolver.href;
2417
+ assertUrlLike(baseUrl, "baseUrl");
2418
+ resolve = (pattern) => new URL(pattern, baseUrl).href;
2419
+ }
2497
2420
 
2498
2421
  const associationsResolved = {};
2499
2422
  for (const key of Object.keys(associations)) {
@@ -2504,12 +2427,11 @@ const resolveAssociations = (associations, baseUrl) => {
2504
2427
  const valueAssociated = value[pattern];
2505
2428
  let patternResolved;
2506
2429
  try {
2507
- patternResolved = String(new URL(pattern, baseUrl));
2430
+ patternResolved = resolve(pattern);
2508
2431
  } catch {
2509
2432
  // it's not really an url, no need to perform url resolution nor encoding
2510
2433
  patternResolved = pattern;
2511
2434
  }
2512
-
2513
2435
  valueMapResolved[patternResolved] = valueAssociated;
2514
2436
  }
2515
2437
  associationsResolved[key] = valueMapResolved;
@@ -2632,34 +2554,29 @@ const urlChildMayMatch = ({ url, associations, predicate }) => {
2632
2554
  };
2633
2555
 
2634
2556
  const applyAliases = ({ url, aliases }) => {
2635
- let aliasFullMatchResult;
2636
- const aliasMatchingKey = Object.keys(aliases).find((key) => {
2637
- const aliasMatchResult = applyPatternMatching({
2557
+ for (const key of Object.keys(aliases)) {
2558
+ const matchResult = applyPatternMatching({
2638
2559
  pattern: key,
2639
2560
  url,
2640
2561
  });
2641
- if (aliasMatchResult.matched) {
2642
- aliasFullMatchResult = aliasMatchResult;
2643
- return true;
2562
+ if (!matchResult.matched) {
2563
+ continue;
2644
2564
  }
2645
- return false;
2646
- });
2647
- if (!aliasMatchingKey) {
2648
- return url;
2649
- }
2650
- const { matchGroups } = aliasFullMatchResult;
2651
- const alias = aliases[aliasMatchingKey];
2652
- const parts = alias.split("*");
2653
- let newUrl = "";
2654
- let index = 0;
2655
- for (const part of parts) {
2656
- newUrl += `${part}`;
2657
- if (index < parts.length - 1) {
2658
- newUrl += matchGroups[index];
2565
+ const { matchGroups } = matchResult;
2566
+ const alias = aliases[key];
2567
+ const parts = alias.split("*");
2568
+ let newUrl = "";
2569
+ let index = 0;
2570
+ for (const part of parts) {
2571
+ newUrl += `${part}`;
2572
+ if (index < parts.length - 1) {
2573
+ newUrl += matchGroups[index];
2574
+ }
2575
+ index++;
2659
2576
  }
2660
- index++;
2577
+ return newUrl;
2661
2578
  }
2662
- return newUrl;
2579
+ return url;
2663
2580
  };
2664
2581
 
2665
2582
  const matches = (url, patterns) => {
@@ -4453,217 +4370,6 @@ const getCoverageFromTestPlanResults = async (
4453
4370
 
4454
4371
  const isV8Coverage = (coverage) => Boolean(coverage.result);
4455
4372
 
4456
- const createCallOrderer = () => {
4457
- const queue = [];
4458
- const callWhenPreviousExecutionAreDone = (executionIndex, callback) => {
4459
- if (queue[executionIndex]) {
4460
- throw new Error(`${executionIndex} already used`);
4461
- }
4462
-
4463
- let allBeforeAreDone = true;
4464
- if (executionIndex > 0) {
4465
- let beforeIndex = executionIndex - 1;
4466
- do {
4467
- const value = queue[beforeIndex];
4468
- if (!value) {
4469
- allBeforeAreDone = false;
4470
- break;
4471
- }
4472
- } while (beforeIndex--);
4473
- }
4474
- if (!allBeforeAreDone) {
4475
- queue[executionIndex] = callback;
4476
- return;
4477
- }
4478
- queue[executionIndex] = true;
4479
- callback();
4480
- let afterIndex = executionIndex + 1;
4481
- while (afterIndex < queue.length) {
4482
- const value = queue[afterIndex];
4483
- if (value === undefined) {
4484
- break;
4485
- }
4486
- if (typeof value === "function") {
4487
- queue[afterIndex] = true;
4488
- value();
4489
- }
4490
- afterIndex++;
4491
- }
4492
- };
4493
- return callWhenPreviousExecutionAreDone;
4494
- };
4495
-
4496
- // https://gist.github.com/GaetanoPiazzolla/c40e1ebb9f709d091208e89baf9f4e00
4497
-
4498
-
4499
- const startMeasuringTotalCpuUsage = () => {
4500
- let previousCpuArray = cpus();
4501
- let previousMs = Date.now();
4502
- let previousCpuUsage = cpuUsage();
4503
-
4504
- const overall = {
4505
- inactive: 100,
4506
- active: 0,
4507
- system: 0,
4508
- user: 0,
4509
- };
4510
- const thisProcess = {
4511
- active: 0,
4512
- system: 0,
4513
- user: 0,
4514
- };
4515
- const details = previousCpuArray.map(() => {
4516
- return {
4517
- inactive: 100,
4518
- active: 0,
4519
- system: 0,
4520
- user: 0,
4521
- };
4522
- });
4523
-
4524
- const samples = [];
4525
- const interval = setInterval(() => {
4526
- let cpuArray = cpus();
4527
- const ms = Date.now();
4528
- const ellapsedMs = ms - previousMs;
4529
- const cpuUsageSampleArray = [];
4530
- let overallSystemMs = 0;
4531
- let overallUserMs = 0;
4532
- let overallInactiveMs = 0;
4533
- let overallActiveMs = 0;
4534
- let overallMsEllapsed = 0;
4535
- let index = 0;
4536
- for (const cpu of cpuArray) {
4537
- const previousCpuTimes = previousCpuArray[index].times;
4538
- const cpuTimes = cpu.times;
4539
- const systemMs = cpuTimes.sys - previousCpuTimes.sys;
4540
- const userMs = cpuTimes.user - previousCpuTimes.user;
4541
- const activeMs = systemMs + userMs;
4542
- const inactiveMs = ellapsedMs - activeMs;
4543
- const cpuUsageSample = {
4544
- inactive: inactiveMs / ellapsedMs,
4545
- active: activeMs / ellapsedMs,
4546
- system: systemMs / ellapsedMs,
4547
- user: userMs / ellapsedMs,
4548
- };
4549
- cpuUsageSampleArray.push(cpuUsageSample);
4550
-
4551
- overallSystemMs += systemMs;
4552
- overallUserMs += userMs;
4553
- overallInactiveMs += inactiveMs;
4554
- overallActiveMs += activeMs;
4555
- overallMsEllapsed += ellapsedMs;
4556
- index++;
4557
- }
4558
- const overallUsageSample = {
4559
- inactive: overallInactiveMs / overallMsEllapsed,
4560
- active: overallActiveMs / overallMsEllapsed,
4561
- system: overallSystemMs / overallMsEllapsed,
4562
- user: overallUserMs / overallMsEllapsed,
4563
- };
4564
- previousCpuArray = cpuArray;
4565
- previousMs = ms;
4566
-
4567
- const processCpuUsage = cpuUsage();
4568
- const thisProcessSystemMs = Math.round(
4569
- (processCpuUsage.system - previousCpuUsage.system) / 1000,
4570
- );
4571
- const thisProcessUserMs = Math.round(
4572
- (processCpuUsage.user - previousCpuUsage.user) / 1000,
4573
- );
4574
- previousCpuUsage = processCpuUsage;
4575
-
4576
- const thisProcessActiveMs = thisProcessSystemMs + thisProcessUserMs;
4577
- const thisProcessInactiveMs = overallMsEllapsed - thisProcessActiveMs;
4578
- const thisProcessSample = {
4579
- inactive: thisProcessInactiveMs / overallMsEllapsed,
4580
- active: thisProcessActiveMs / overallMsEllapsed,
4581
- system: thisProcessSystemMs / overallMsEllapsed,
4582
- user: thisProcessUserMs / overallMsEllapsed,
4583
- };
4584
- samples.push({
4585
- cpuUsageSampleArray,
4586
- overallUsageSample,
4587
- thisProcessSample,
4588
- });
4589
- if (samples.length === 10) {
4590
- {
4591
- let index = 0;
4592
- for (const detail of details) {
4593
- let systemSum = 0;
4594
- let userSum = 0;
4595
- let inactiveSum = 0;
4596
- let activeSum = 0;
4597
- for (const sample of samples) {
4598
- const { cpuUsageSampleArray } = sample;
4599
- const cpuUsageSample = cpuUsageSampleArray[index];
4600
- inactiveSum += cpuUsageSample.inactive;
4601
- activeSum += cpuUsageSample.active;
4602
- systemSum += cpuUsageSample.system;
4603
- userSum += cpuUsageSample.user;
4604
- }
4605
- Object.assign(detail, {
4606
- inactive: inactiveSum / samples.length,
4607
- active: activeSum / samples.length,
4608
- system: systemSum / samples.length,
4609
- user: userSum / samples.length,
4610
- });
4611
- index++;
4612
- }
4613
- }
4614
- {
4615
- let overallSystemSum = 0;
4616
- let overallUserSum = 0;
4617
- let overallInactiveSum = 0;
4618
- let overallActiveSum = 0;
4619
- for (const sample of samples) {
4620
- const { overallUsageSample } = sample;
4621
- overallSystemSum += overallUsageSample.system;
4622
- overallUserSum += overallUsageSample.user;
4623
- overallInactiveSum += overallUsageSample.inactive;
4624
- overallActiveSum += overallUsageSample.active;
4625
- }
4626
- Object.assign(overall, {
4627
- inactive: overallInactiveSum / samples.length,
4628
- active: overallActiveSum / samples.length,
4629
- system: overallSystemSum / samples.length,
4630
- user: overallUserSum / samples.length,
4631
- });
4632
- }
4633
- {
4634
- let thisProcessSystemSum = 0;
4635
- let thisProcessUserSum = 0;
4636
- let thisProcessInactiveSum = 0;
4637
- let thisProcessActiveSum = 0;
4638
- for (const sample of samples) {
4639
- const { thisProcessSample } = sample;
4640
- thisProcessSystemSum += thisProcessSample.system;
4641
- thisProcessUserSum += thisProcessSample.user;
4642
- thisProcessInactiveSum += thisProcessSample.inactive;
4643
- thisProcessActiveSum += thisProcessSample.active;
4644
- }
4645
- Object.assign(thisProcess, {
4646
- inactive: thisProcessInactiveSum / samples.length,
4647
- active: thisProcessActiveSum / samples.length,
4648
- system: thisProcessSystemSum / samples.length,
4649
- user: thisProcessUserSum / samples.length,
4650
- });
4651
- }
4652
- samples.length = 0;
4653
- }
4654
- }, 15);
4655
- interval.unref();
4656
-
4657
- return {
4658
- overall,
4659
- thisProcess,
4660
- details,
4661
- stop: () => {
4662
- clearInterval(interval);
4663
- },
4664
- };
4665
- };
4666
-
4667
4373
  const githubAnnotationFromError = (
4668
4374
  error,
4669
4375
  { rootDirectoryUrl, execution },
@@ -5951,79 +5657,6 @@ const renderStatusRepartition = (counters, { showProgression } = {}) => {
5951
5657
  return `${parts.join(", ")}`;
5952
5658
  };
5953
5659
 
5954
- const renderBigSection = (params) => {
5955
- return renderSection({
5956
- width: 45,
5957
- ...params,
5958
- });
5959
- };
5960
-
5961
- const renderSection = ({
5962
- title,
5963
- content,
5964
- dashColor = ANSI.GREY,
5965
- width = 38,
5966
- bottomSeparator = true,
5967
- }) => {
5968
- let section = "";
5969
-
5970
- if (title) {
5971
- const titleWidth = stripAnsi(title).length;
5972
- const minWidthRequired = `--- … ---`.length;
5973
- const needsTruncate = titleWidth + minWidthRequired >= width;
5974
- if (needsTruncate) {
5975
- const titleTruncated = title.slice(0, width - minWidthRequired);
5976
- const leftDashes = ANSI.color("---", dashColor);
5977
- const rightDashes = ANSI.color("---", dashColor);
5978
- section += `${leftDashes} ${titleTruncated}… ${rightDashes}`;
5979
- } else {
5980
- const remainingWidth = width - titleWidth - 2; // 2 for spaces around the title
5981
- const dashLeftCount = Math.floor(remainingWidth / 2);
5982
- const dashRightCount = remainingWidth - dashLeftCount;
5983
- const leftDashes = ANSI.color("-".repeat(dashLeftCount), dashColor);
5984
- const rightDashes = ANSI.color("-".repeat(dashRightCount), dashColor);
5985
- section += `${leftDashes} ${title} ${rightDashes}`;
5986
- }
5987
- section += "\n";
5988
- } else {
5989
- const topDashes = ANSI.color(`-`.repeat(width), dashColor);
5990
- section += topDashes;
5991
- section += "\n";
5992
- }
5993
- section += `${content}`;
5994
- if (bottomSeparator) {
5995
- section += "\n";
5996
- const bottomDashes = ANSI.color(`-`.repeat(width), dashColor);
5997
- section += bottomDashes;
5998
- }
5999
- return section;
6000
- };
6001
-
6002
- const renderDetails = (data) => {
6003
- const details = [];
6004
- for (const key of Object.keys(data)) {
6005
- const value = data[key];
6006
- let valueString = "";
6007
- valueString += ANSI.color(`${key}:`, ANSI.GREY);
6008
- const useNonGreyAnsiColor =
6009
- typeof value === "string" && value.includes("\x1b");
6010
- valueString += " ";
6011
- valueString += useNonGreyAnsiColor
6012
- ? value
6013
- : ANSI.color(String(value), ANSI.GREY);
6014
- details.push(valueString);
6015
- }
6016
- if (details.length === 0) {
6017
- return "";
6018
- }
6019
-
6020
- let string = "";
6021
- string += ` ${ANSI.color("(", ANSI.GREY)}`;
6022
- string += details.join(ANSI.color(", ", ANSI.GREY));
6023
- string += ANSI.color(")", ANSI.GREY);
6024
- return string;
6025
- };
6026
-
6027
5660
  /*
6028
5661
  * Export a function capable to run a file on a runtime.
6029
5662
  *
@@ -6727,22 +6360,12 @@ const executeTestPlan = async ({
6727
6360
  });
6728
6361
  }
6729
6362
 
6730
- const cpuUsage = startMeasuringTotalCpuUsage();
6731
- operation.addEndCallback(cpuUsage.stop);
6732
- const processCpuUsageMonitoring = startMonitoringMetric(() => {
6733
- return cpuUsage.thisProcess.active;
6734
- });
6735
- const osCpuUsageMonitoring = startMonitoringMetric(() => {
6736
- return cpuUsage.overall.active;
6737
- });
6738
- const processMemoryUsageMonitoring = startMonitoringMetric(() => {
6739
- return memoryUsage().rss;
6740
- });
6741
- const osMemoryUsageMonitoring = startMonitoringMetric(() => {
6742
- const total = totalmem();
6743
- const free = freemem();
6744
- return total - free;
6745
- });
6363
+ const cpuMonitoring = startMonitoringCpuUsage();
6364
+ operation.addEndCallback(cpuMonitoring.stop);
6365
+ const [processCpuUsageMonitoring, osCpuUsageMonitoring] = cpuMonitoring;
6366
+ const memoryMonitoring = startMonitoringMemoryUsage();
6367
+ const [processMemoryUsageMonitoring, osMemoryUsageMonitoring] =
6368
+ memoryMonitoring;
6746
6369
 
6747
6370
  const timingsOrigin = Date.now();
6748
6371
  const takeTiming = () => {
@@ -6758,9 +6381,9 @@ const executeTestPlan = async ({
6758
6381
  : process.platform === "linux"
6759
6382
  ? "linux"
6760
6383
  : "other",
6761
- version: release(),
6384
+ version: getOsVersion(),
6762
6385
  availableCpu: countAvailableCpus(),
6763
- availableMemory: totalmem(),
6386
+ availableMemory: getAvailableMemory(),
6764
6387
  },
6765
6388
  runtime: {
6766
6389
  name: "node",
@@ -7727,59 +7350,6 @@ To fix this warning:
7727
7350
  return testPlanResult;
7728
7351
  };
7729
7352
 
7730
- const startMonitoringMetric = (measure) => {
7731
- const metrics = [];
7732
- const takeMeasure = () => {
7733
- const value = measure();
7734
- metrics.push(value);
7735
- return value;
7736
- };
7737
-
7738
- const info = {
7739
- start: takeMeasure(),
7740
- min: null,
7741
- max: null,
7742
- median: null,
7743
- end: null,
7744
- };
7745
- return {
7746
- info,
7747
- measure: takeMeasure,
7748
- end: () => {
7749
- info.end = takeMeasure();
7750
- metrics.sort((a, b) => a - b);
7751
- info.min = metrics[0];
7752
- info.max = metrics[metrics.length - 1];
7753
- info.median = medianFromSortedArray(metrics);
7754
- metrics.length = 0;
7755
- },
7756
- };
7757
- };
7758
-
7759
- const medianFromSortedArray = (array) => {
7760
- const length = array.length;
7761
- const isOdd = length % 2 === 1;
7762
- if (isOdd) {
7763
- const medianNumberIndex = (length - 1) / 2;
7764
- const medianNumber = array[medianNumberIndex];
7765
- return medianNumber;
7766
- }
7767
- const rightMiddleNumberIndex = length / 2;
7768
- const leftMiddleNumberIndex = rightMiddleNumberIndex - 1;
7769
- const leftMiddleNumber = array[leftMiddleNumberIndex];
7770
- const rightMiddleNumber = array[rightMiddleNumberIndex];
7771
- const medianNumber = (leftMiddleNumber + rightMiddleNumber) / 2;
7772
- return medianNumber;
7773
- };
7774
-
7775
- const countAvailableCpus = () => {
7776
- if (typeof availableParallelism === "function") {
7777
- return availableParallelism();
7778
- }
7779
- const cpuArray = cpus();
7780
- return cpuArray.length || 1;
7781
- };
7782
-
7783
7353
  const mutateCountersBeforeExecutionStarts = (counters) => {
7784
7354
  counters.executing++;
7785
7355
  counters.waiting--;