vitest 0.0.81 → 0.0.82

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/cli.js CHANGED
@@ -1,21 +1,22 @@
1
- import require$$2, { EventEmitter } from 'events';
2
- import { s as stringWidth, a as ansiStyles, b as stripAnsi, c as sliceAnsi, d as c, F as F_POINTER, e as F_DOWN, f as F_LONG_DASH, g as F_DOWN_RIGHT, h as F_DOT, i as F_CHECK, j as F_CROSS, k as cliTruncate, l as F_RIGHT, p as printError } from './error-6bb44a98.js';
3
- import path, { isAbsolute, relative, dirname, basename, resolve } from 'path';
4
- import process$2 from 'process';
5
- import { promises } from 'fs';
6
- import { createServer } from 'vite';
7
- import { d as defaultInclude, a as defaultExclude, b as defaultPort, c as configFiles, e as distDir } from './constants-1268ea5c.js';
8
- import { performance } from 'perf_hooks';
9
- import { g as getNames, s as slash, a as getTests, b as getSuites, t as toArray, h as hasFailed } from './utils-9dcc4050.js';
10
- import require$$0 from 'assert';
11
- import { MessageChannel } from 'worker_threads';
12
- import { pathToFileURL } from 'url';
13
- import Piscina from 'piscina';
14
- import fg from 'fast-glob';
15
- import mm from 'micromatch';
16
- import readline from 'readline';
1
+ import { EventEmitter } from 'events';
2
+ import { c } from './error-dd23da12.js';
3
+ import { c as createVitest } from './index-9a2ee1fc.js';
4
+ import 'fs';
5
+ import 'path';
17
6
  import 'tty';
18
7
  import 'source-map';
8
+ import './utils-9dcc4050.js';
9
+ import 'vite';
10
+ import 'process';
11
+ import './constants-adef7ffb.js';
12
+ import 'url';
13
+ import 'perf_hooks';
14
+ import 'assert';
15
+ import 'worker_threads';
16
+ import 'piscina';
17
+ import 'fast-glob';
18
+ import 'micromatch';
19
+ import 'readline';
19
20
 
20
21
  function toArr(any) {
21
22
  return any == null ? [] : Array.isArray(any) ? any : [any];
@@ -630,1888 +631,8 @@ class CAC extends EventEmitter {
630
631
 
631
632
  const cac = (name = "") => new CAC(name);
632
633
 
633
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
634
+ var version = "0.0.82";
634
635
 
635
- var version = "0.0.81";
636
-
637
- /*
638
- How it works:
639
- `this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
640
- */
641
-
642
- class Node {
643
- value;
644
- next;
645
-
646
- constructor(value) {
647
- this.value = value;
648
- }
649
- }
650
-
651
- class Queue {
652
- #head;
653
- #tail;
654
- #size;
655
-
656
- constructor() {
657
- this.clear();
658
- }
659
-
660
- enqueue(value) {
661
- const node = new Node(value);
662
-
663
- if (this.#head) {
664
- this.#tail.next = node;
665
- this.#tail = node;
666
- } else {
667
- this.#head = node;
668
- this.#tail = node;
669
- }
670
-
671
- this.#size++;
672
- }
673
-
674
- dequeue() {
675
- const current = this.#head;
676
- if (!current) {
677
- return;
678
- }
679
-
680
- this.#head = this.#head.next;
681
- this.#size--;
682
- return current.value;
683
- }
684
-
685
- clear() {
686
- this.#head = undefined;
687
- this.#tail = undefined;
688
- this.#size = 0;
689
- }
690
-
691
- get size() {
692
- return this.#size;
693
- }
694
-
695
- * [Symbol.iterator]() {
696
- let current = this.#head;
697
-
698
- while (current) {
699
- yield current.value;
700
- current = current.next;
701
- }
702
- }
703
- }
704
-
705
- function pLimit(concurrency) {
706
- if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
707
- throw new TypeError('Expected `concurrency` to be a number from 1 and up');
708
- }
709
-
710
- const queue = new Queue();
711
- let activeCount = 0;
712
-
713
- const next = () => {
714
- activeCount--;
715
-
716
- if (queue.size > 0) {
717
- queue.dequeue()();
718
- }
719
- };
720
-
721
- const run = async (fn, resolve, args) => {
722
- activeCount++;
723
-
724
- const result = (async () => fn(...args))();
725
-
726
- resolve(result);
727
-
728
- try {
729
- await result;
730
- } catch {}
731
-
732
- next();
733
- };
734
-
735
- const enqueue = (fn, resolve, args) => {
736
- queue.enqueue(run.bind(undefined, fn, resolve, args));
737
-
738
- (async () => {
739
- // This function needs to wait until the next microtask before comparing
740
- // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
741
- // when the run function is dequeued and called. The comparison in the if-statement
742
- // needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
743
- await Promise.resolve();
744
-
745
- if (activeCount < concurrency && queue.size > 0) {
746
- queue.dequeue()();
747
- }
748
- })();
749
- };
750
-
751
- const generator = (fn, ...args) => new Promise(resolve => {
752
- enqueue(fn, resolve, args);
753
- });
754
-
755
- Object.defineProperties(generator, {
756
- activeCount: {
757
- get: () => activeCount,
758
- },
759
- pendingCount: {
760
- get: () => queue.size,
761
- },
762
- clearQueue: {
763
- value: () => {
764
- queue.clear();
765
- },
766
- },
767
- });
768
-
769
- return generator;
770
- }
771
-
772
- class EndError extends Error {
773
- constructor(value) {
774
- super();
775
- this.value = value;
776
- }
777
- }
778
-
779
- // The input can also be a promise, so we await it.
780
- const testElement = async (element, tester) => tester(await element);
781
-
782
- // The input can also be a promise, so we `Promise.all()` them both.
783
- const finder = async element => {
784
- const values = await Promise.all(element);
785
- if (values[1] === true) {
786
- throw new EndError(values[0]);
787
- }
788
-
789
- return false;
790
- };
791
-
792
- async function pLocate(
793
- iterable,
794
- tester,
795
- {
796
- concurrency = Number.POSITIVE_INFINITY,
797
- preserveOrder = true,
798
- } = {},
799
- ) {
800
- const limit = pLimit(concurrency);
801
-
802
- // Start all the promises concurrently with optional limit.
803
- const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
804
-
805
- // Check the promises either serially or concurrently.
806
- const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
807
-
808
- try {
809
- await Promise.all(items.map(element => checkLimit(finder, element)));
810
- } catch (error) {
811
- if (error instanceof EndError) {
812
- return error.value;
813
- }
814
-
815
- throw error;
816
- }
817
- }
818
-
819
- const typeMappings = {
820
- directory: 'isDirectory',
821
- file: 'isFile',
822
- };
823
-
824
- function checkType(type) {
825
- if (type in typeMappings) {
826
- return;
827
- }
828
-
829
- throw new Error(`Invalid type specified: ${type}`);
830
- }
831
-
832
- const matchType = (type, stat) => type === undefined || stat[typeMappings[type]]();
833
-
834
- async function locatePath(
835
- paths,
836
- {
837
- cwd = process$2.cwd(),
838
- type = 'file',
839
- allowSymlinks = true,
840
- concurrency,
841
- preserveOrder,
842
- } = {},
843
- ) {
844
- checkType(type);
845
-
846
- const statFunction = allowSymlinks ? promises.stat : promises.lstat;
847
-
848
- return pLocate(paths, async path_ => {
849
- try {
850
- const stat = await statFunction(path.resolve(cwd, path_));
851
- return matchType(type, stat);
852
- } catch {
853
- return false;
854
- }
855
- }, {concurrency, preserveOrder});
856
- }
857
-
858
- const findUpStop = Symbol('findUpStop');
859
-
860
- async function findUpMultiple(name, options = {}) {
861
- let directory = path.resolve(options.cwd || '');
862
- const {root} = path.parse(directory);
863
- const stopAt = path.resolve(directory, options.stopAt || root);
864
- const limit = options.limit || Number.POSITIVE_INFINITY;
865
- const paths = [name].flat();
866
-
867
- const runMatcher = async locateOptions => {
868
- if (typeof name !== 'function') {
869
- return locatePath(paths, locateOptions);
870
- }
871
-
872
- const foundPath = await name(locateOptions.cwd);
873
- if (typeof foundPath === 'string') {
874
- return locatePath([foundPath], locateOptions);
875
- }
876
-
877
- return foundPath;
878
- };
879
-
880
- const matches = [];
881
- // eslint-disable-next-line no-constant-condition
882
- while (true) {
883
- // eslint-disable-next-line no-await-in-loop
884
- const foundPath = await runMatcher({...options, cwd: directory});
885
-
886
- if (foundPath === findUpStop) {
887
- break;
888
- }
889
-
890
- if (foundPath) {
891
- matches.push(path.resolve(directory, foundPath));
892
- }
893
-
894
- if (directory === stopAt || matches.length >= limit) {
895
- break;
896
- }
897
-
898
- directory = path.dirname(directory);
899
- }
900
-
901
- return matches;
902
- }
903
-
904
- async function findUp(name, options = {}) {
905
- const matches = await findUpMultiple(name, {...options, limit: 1});
906
- return matches[0];
907
- }
908
-
909
- class SnapshotManager {
910
- constructor(config) {
911
- this.config = config;
912
- this.summary = void 0;
913
- this.clear();
914
- }
915
- clear() {
916
- this.summary = emptySummary(this.config.snapshotOptions);
917
- }
918
- add(result) {
919
- addSnapshotResult(this.summary, result);
920
- }
921
- }
922
- function emptySummary(options) {
923
- const summary = {
924
- added: 0,
925
- failure: false,
926
- filesAdded: 0,
927
- filesRemoved: 0,
928
- filesRemovedList: [],
929
- filesUnmatched: 0,
930
- filesUpdated: 0,
931
- matched: 0,
932
- total: 0,
933
- unchecked: 0,
934
- uncheckedKeysByFile: [],
935
- unmatched: 0,
936
- updated: 0,
937
- didUpdate: options.updateSnapshot === "all"
938
- };
939
- return summary;
940
- }
941
- function addSnapshotResult(summary, result) {
942
- if (result.added)
943
- summary.filesAdded++;
944
- if (result.fileDeleted)
945
- summary.filesRemoved++;
946
- if (result.unmatched)
947
- summary.filesUnmatched++;
948
- if (result.updated)
949
- summary.filesUpdated++;
950
- summary.added += result.added;
951
- summary.matched += result.matched;
952
- summary.unchecked += result.unchecked;
953
- if (result.uncheckedKeys && result.uncheckedKeys.length > 0) {
954
- summary.uncheckedKeysByFile.push({
955
- filePath: result.filepath,
956
- keys: result.uncheckedKeys
957
- });
958
- }
959
- summary.unmatched += result.unmatched;
960
- summary.updated += result.updated;
961
- summary.total += result.added + result.matched + result.unmatched + result.updated;
962
- }
963
-
964
- const ESC = '\u001B[';
965
- const OSC = '\u001B]';
966
- const BEL = '\u0007';
967
- const SEP = ';';
968
- const isTerminalApp = process.env.TERM_PROGRAM === 'Apple_Terminal';
969
-
970
- const ansiEscapes = {};
971
-
972
- ansiEscapes.cursorTo = (x, y) => {
973
- if (typeof x !== 'number') {
974
- throw new TypeError('The `x` argument is required');
975
- }
976
-
977
- if (typeof y !== 'number') {
978
- return ESC + (x + 1) + 'G';
979
- }
980
-
981
- return ESC + (y + 1) + ';' + (x + 1) + 'H';
982
- };
983
-
984
- ansiEscapes.cursorMove = (x, y) => {
985
- if (typeof x !== 'number') {
986
- throw new TypeError('The `x` argument is required');
987
- }
988
-
989
- let returnValue = '';
990
-
991
- if (x < 0) {
992
- returnValue += ESC + (-x) + 'D';
993
- } else if (x > 0) {
994
- returnValue += ESC + x + 'C';
995
- }
996
-
997
- if (y < 0) {
998
- returnValue += ESC + (-y) + 'A';
999
- } else if (y > 0) {
1000
- returnValue += ESC + y + 'B';
1001
- }
1002
-
1003
- return returnValue;
1004
- };
1005
-
1006
- ansiEscapes.cursorUp = (count = 1) => ESC + count + 'A';
1007
- ansiEscapes.cursorDown = (count = 1) => ESC + count + 'B';
1008
- ansiEscapes.cursorForward = (count = 1) => ESC + count + 'C';
1009
- ansiEscapes.cursorBackward = (count = 1) => ESC + count + 'D';
1010
-
1011
- ansiEscapes.cursorLeft = ESC + 'G';
1012
- ansiEscapes.cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
1013
- ansiEscapes.cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
1014
- ansiEscapes.cursorGetPosition = ESC + '6n';
1015
- ansiEscapes.cursorNextLine = ESC + 'E';
1016
- ansiEscapes.cursorPrevLine = ESC + 'F';
1017
- ansiEscapes.cursorHide = ESC + '?25l';
1018
- ansiEscapes.cursorShow = ESC + '?25h';
1019
-
1020
- ansiEscapes.eraseLines = count => {
1021
- let clear = '';
1022
-
1023
- for (let i = 0; i < count; i++) {
1024
- clear += ansiEscapes.eraseLine + (i < count - 1 ? ansiEscapes.cursorUp() : '');
1025
- }
1026
-
1027
- if (count) {
1028
- clear += ansiEscapes.cursorLeft;
1029
- }
1030
-
1031
- return clear;
1032
- };
1033
-
1034
- ansiEscapes.eraseEndLine = ESC + 'K';
1035
- ansiEscapes.eraseStartLine = ESC + '1K';
1036
- ansiEscapes.eraseLine = ESC + '2K';
1037
- ansiEscapes.eraseDown = ESC + 'J';
1038
- ansiEscapes.eraseUp = ESC + '1J';
1039
- ansiEscapes.eraseScreen = ESC + '2J';
1040
- ansiEscapes.scrollUp = ESC + 'S';
1041
- ansiEscapes.scrollDown = ESC + 'T';
1042
-
1043
- ansiEscapes.clearScreen = '\u001Bc';
1044
-
1045
- ansiEscapes.clearTerminal = process.platform === 'win32' ?
1046
- `${ansiEscapes.eraseScreen}${ESC}0f` :
1047
- // 1. Erases the screen (Only done in case `2` is not supported)
1048
- // 2. Erases the whole screen including scrollback buffer
1049
- // 3. Moves cursor to the top-left position
1050
- // More info: https://www.real-world-systems.com/docs/ANSIcode.html
1051
- `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
1052
-
1053
- ansiEscapes.beep = BEL;
1054
-
1055
- ansiEscapes.link = (text, url) => {
1056
- return [
1057
- OSC,
1058
- '8',
1059
- SEP,
1060
- SEP,
1061
- url,
1062
- BEL,
1063
- text,
1064
- OSC,
1065
- '8',
1066
- SEP,
1067
- SEP,
1068
- BEL
1069
- ].join('');
1070
- };
1071
-
1072
- ansiEscapes.image = (buffer, options = {}) => {
1073
- let returnValue = `${OSC}1337;File=inline=1`;
1074
-
1075
- if (options.width) {
1076
- returnValue += `;width=${options.width}`;
1077
- }
1078
-
1079
- if (options.height) {
1080
- returnValue += `;height=${options.height}`;
1081
- }
1082
-
1083
- if (options.preserveAspectRatio === false) {
1084
- returnValue += ';preserveAspectRatio=0';
1085
- }
1086
-
1087
- return returnValue + ':' + buffer.toString('base64') + BEL;
1088
- };
1089
-
1090
- ansiEscapes.iTerm = {
1091
- setCwd: (cwd = process.cwd()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
1092
-
1093
- annotation: (message, options = {}) => {
1094
- let returnValue = `${OSC}1337;`;
1095
-
1096
- const hasX = typeof options.x !== 'undefined';
1097
- const hasY = typeof options.y !== 'undefined';
1098
- if ((hasX || hasY) && !(hasX && hasY && typeof options.length !== 'undefined')) {
1099
- throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
1100
- }
1101
-
1102
- message = message.replace(/\|/g, '');
1103
-
1104
- returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
1105
-
1106
- if (options.length > 0) {
1107
- returnValue +=
1108
- (hasX ?
1109
- [message, options.length, options.x, options.y] :
1110
- [options.length, message]).join('|');
1111
- } else {
1112
- returnValue += message;
1113
- }
1114
-
1115
- return returnValue + BEL;
1116
- }
1117
- };
1118
-
1119
- var onetime$2 = {exports: {}};
1120
-
1121
- var mimicFn$2 = {exports: {}};
1122
-
1123
- const mimicFn$1 = (to, from) => {
1124
- for (const prop of Reflect.ownKeys(from)) {
1125
- Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop));
1126
- }
1127
-
1128
- return to;
1129
- };
1130
-
1131
- mimicFn$2.exports = mimicFn$1;
1132
- // TODO: Remove this for the next major release
1133
- mimicFn$2.exports.default = mimicFn$1;
1134
-
1135
- const mimicFn = mimicFn$2.exports;
1136
-
1137
- const calledFunctions = new WeakMap();
1138
-
1139
- const onetime = (function_, options = {}) => {
1140
- if (typeof function_ !== 'function') {
1141
- throw new TypeError('Expected a function');
1142
- }
1143
-
1144
- let returnValue;
1145
- let callCount = 0;
1146
- const functionName = function_.displayName || function_.name || '<anonymous>';
1147
-
1148
- const onetime = function (...arguments_) {
1149
- calledFunctions.set(onetime, ++callCount);
1150
-
1151
- if (callCount === 1) {
1152
- returnValue = function_.apply(this, arguments_);
1153
- function_ = null;
1154
- } else if (options.throw === true) {
1155
- throw new Error(`Function \`${functionName}\` can only be called once`);
1156
- }
1157
-
1158
- return returnValue;
1159
- };
1160
-
1161
- mimicFn(onetime, function_);
1162
- calledFunctions.set(onetime, callCount);
1163
-
1164
- return onetime;
1165
- };
1166
-
1167
- onetime$2.exports = onetime;
1168
- // TODO: Remove this for the next major release
1169
- onetime$2.exports.default = onetime;
1170
-
1171
- onetime$2.exports.callCount = function_ => {
1172
- if (!calledFunctions.has(function_)) {
1173
- throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
1174
- }
1175
-
1176
- return calledFunctions.get(function_);
1177
- };
1178
-
1179
- var onetime$1 = onetime$2.exports;
1180
-
1181
- var signalExit$1 = {exports: {}};
1182
-
1183
- var signals$1 = {exports: {}};
1184
-
1185
- (function (module) {
1186
- // This is not the set of all possible signals.
1187
- //
1188
- // It IS, however, the set of all signals that trigger
1189
- // an exit on either Linux or BSD systems. Linux is a
1190
- // superset of the signal names supported on BSD, and
1191
- // the unknown signals just fail to register, so we can
1192
- // catch that easily enough.
1193
- //
1194
- // Don't bother with SIGKILL. It's uncatchable, which
1195
- // means that we can't fire any callbacks anyway.
1196
- //
1197
- // If a user does happen to register a handler on a non-
1198
- // fatal signal like SIGWINCH or something, and then
1199
- // exit, it'll end up firing `process.emit('exit')`, so
1200
- // the handler will be fired anyway.
1201
- //
1202
- // SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
1203
- // artificially, inherently leave the process in a
1204
- // state from which it is not safe to try and enter JS
1205
- // listeners.
1206
- module.exports = [
1207
- 'SIGABRT',
1208
- 'SIGALRM',
1209
- 'SIGHUP',
1210
- 'SIGINT',
1211
- 'SIGTERM'
1212
- ];
1213
-
1214
- if (process.platform !== 'win32') {
1215
- module.exports.push(
1216
- 'SIGVTALRM',
1217
- 'SIGXCPU',
1218
- 'SIGXFSZ',
1219
- 'SIGUSR2',
1220
- 'SIGTRAP',
1221
- 'SIGSYS',
1222
- 'SIGQUIT',
1223
- 'SIGIOT'
1224
- // should detect profiler and enable/disable accordingly.
1225
- // see #21
1226
- // 'SIGPROF'
1227
- );
1228
- }
1229
-
1230
- if (process.platform === 'linux') {
1231
- module.exports.push(
1232
- 'SIGIO',
1233
- 'SIGPOLL',
1234
- 'SIGPWR',
1235
- 'SIGSTKFLT',
1236
- 'SIGUNUSED'
1237
- );
1238
- }
1239
- }(signals$1));
1240
-
1241
- // Note: since nyc uses this module to output coverage, any lines
1242
- // that are in the direct sync flow of nyc's outputCoverage are
1243
- // ignored, since we can never get coverage for them.
1244
- // grab a reference to node's real process object right away
1245
- var process$1 = commonjsGlobal.process;
1246
-
1247
- const processOk = function (process) {
1248
- return process &&
1249
- typeof process === 'object' &&
1250
- typeof process.removeListener === 'function' &&
1251
- typeof process.emit === 'function' &&
1252
- typeof process.reallyExit === 'function' &&
1253
- typeof process.listeners === 'function' &&
1254
- typeof process.kill === 'function' &&
1255
- typeof process.pid === 'number' &&
1256
- typeof process.on === 'function'
1257
- };
1258
-
1259
- // some kind of non-node environment, just no-op
1260
- /* istanbul ignore if */
1261
- if (!processOk(process$1)) {
1262
- signalExit$1.exports = function () {};
1263
- } else {
1264
- var assert = require$$0;
1265
- var signals = signals$1.exports;
1266
- var isWin = /^win/i.test(process$1.platform);
1267
-
1268
- var EE = require$$2;
1269
- /* istanbul ignore if */
1270
- if (typeof EE !== 'function') {
1271
- EE = EE.EventEmitter;
1272
- }
1273
-
1274
- var emitter;
1275
- if (process$1.__signal_exit_emitter__) {
1276
- emitter = process$1.__signal_exit_emitter__;
1277
- } else {
1278
- emitter = process$1.__signal_exit_emitter__ = new EE();
1279
- emitter.count = 0;
1280
- emitter.emitted = {};
1281
- }
1282
-
1283
- // Because this emitter is a global, we have to check to see if a
1284
- // previous version of this library failed to enable infinite listeners.
1285
- // I know what you're about to say. But literally everything about
1286
- // signal-exit is a compromise with evil. Get used to it.
1287
- if (!emitter.infinite) {
1288
- emitter.setMaxListeners(Infinity);
1289
- emitter.infinite = true;
1290
- }
1291
-
1292
- signalExit$1.exports = function (cb, opts) {
1293
- /* istanbul ignore if */
1294
- if (!processOk(commonjsGlobal.process)) {
1295
- return
1296
- }
1297
- assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler');
1298
-
1299
- if (loaded === false) {
1300
- load();
1301
- }
1302
-
1303
- var ev = 'exit';
1304
- if (opts && opts.alwaysLast) {
1305
- ev = 'afterexit';
1306
- }
1307
-
1308
- var remove = function () {
1309
- emitter.removeListener(ev, cb);
1310
- if (emitter.listeners('exit').length === 0 &&
1311
- emitter.listeners('afterexit').length === 0) {
1312
- unload();
1313
- }
1314
- };
1315
- emitter.on(ev, cb);
1316
-
1317
- return remove
1318
- };
1319
-
1320
- var unload = function unload () {
1321
- if (!loaded || !processOk(commonjsGlobal.process)) {
1322
- return
1323
- }
1324
- loaded = false;
1325
-
1326
- signals.forEach(function (sig) {
1327
- try {
1328
- process$1.removeListener(sig, sigListeners[sig]);
1329
- } catch (er) {}
1330
- });
1331
- process$1.emit = originalProcessEmit;
1332
- process$1.reallyExit = originalProcessReallyExit;
1333
- emitter.count -= 1;
1334
- };
1335
- signalExit$1.exports.unload = unload;
1336
-
1337
- var emit = function emit (event, code, signal) {
1338
- /* istanbul ignore if */
1339
- if (emitter.emitted[event]) {
1340
- return
1341
- }
1342
- emitter.emitted[event] = true;
1343
- emitter.emit(event, code, signal);
1344
- };
1345
-
1346
- // { <signal>: <listener fn>, ... }
1347
- var sigListeners = {};
1348
- signals.forEach(function (sig) {
1349
- sigListeners[sig] = function listener () {
1350
- /* istanbul ignore if */
1351
- if (!processOk(commonjsGlobal.process)) {
1352
- return
1353
- }
1354
- // If there are no other listeners, an exit is coming!
1355
- // Simplest way: remove us and then re-send the signal.
1356
- // We know that this will kill the process, so we can
1357
- // safely emit now.
1358
- var listeners = process$1.listeners(sig);
1359
- if (listeners.length === emitter.count) {
1360
- unload();
1361
- emit('exit', null, sig);
1362
- /* istanbul ignore next */
1363
- emit('afterexit', null, sig);
1364
- /* istanbul ignore next */
1365
- if (isWin && sig === 'SIGHUP') {
1366
- // "SIGHUP" throws an `ENOSYS` error on Windows,
1367
- // so use a supported signal instead
1368
- sig = 'SIGINT';
1369
- }
1370
- /* istanbul ignore next */
1371
- process$1.kill(process$1.pid, sig);
1372
- }
1373
- };
1374
- });
1375
-
1376
- signalExit$1.exports.signals = function () {
1377
- return signals
1378
- };
1379
-
1380
- var loaded = false;
1381
-
1382
- var load = function load () {
1383
- if (loaded || !processOk(commonjsGlobal.process)) {
1384
- return
1385
- }
1386
- loaded = true;
1387
-
1388
- // This is the number of onSignalExit's that are in play.
1389
- // It's important so that we can count the correct number of
1390
- // listeners on signals, and don't wait for the other one to
1391
- // handle it instead of us.
1392
- emitter.count += 1;
1393
-
1394
- signals = signals.filter(function (sig) {
1395
- try {
1396
- process$1.on(sig, sigListeners[sig]);
1397
- return true
1398
- } catch (er) {
1399
- return false
1400
- }
1401
- });
1402
-
1403
- process$1.emit = processEmit;
1404
- process$1.reallyExit = processReallyExit;
1405
- };
1406
- signalExit$1.exports.load = load;
1407
-
1408
- var originalProcessReallyExit = process$1.reallyExit;
1409
- var processReallyExit = function processReallyExit (code) {
1410
- /* istanbul ignore if */
1411
- if (!processOk(commonjsGlobal.process)) {
1412
- return
1413
- }
1414
- process$1.exitCode = code || /* istanbul ignore next */ 0;
1415
- emit('exit', process$1.exitCode, null);
1416
- /* istanbul ignore next */
1417
- emit('afterexit', process$1.exitCode, null);
1418
- /* istanbul ignore next */
1419
- originalProcessReallyExit.call(process$1, process$1.exitCode);
1420
- };
1421
-
1422
- var originalProcessEmit = process$1.emit;
1423
- var processEmit = function processEmit (ev, arg) {
1424
- if (ev === 'exit' && processOk(commonjsGlobal.process)) {
1425
- /* istanbul ignore else */
1426
- if (arg !== undefined) {
1427
- process$1.exitCode = arg;
1428
- }
1429
- var ret = originalProcessEmit.apply(this, arguments);
1430
- /* istanbul ignore next */
1431
- emit('exit', process$1.exitCode, null);
1432
- /* istanbul ignore next */
1433
- emit('afterexit', process$1.exitCode, null);
1434
- /* istanbul ignore next */
1435
- return ret
1436
- } else {
1437
- return originalProcessEmit.apply(this, arguments)
1438
- }
1439
- };
1440
- }
1441
-
1442
- var signalExit = signalExit$1.exports;
1443
-
1444
- const restoreCursor = onetime$1(() => {
1445
- signalExit(() => {
1446
- process$2.stderr.write('\u001B[?25h');
1447
- }, {alwaysLast: true});
1448
- });
1449
-
1450
- let isHidden = false;
1451
-
1452
- const cliCursor = {};
1453
-
1454
- cliCursor.show = (writableStream = process$2.stderr) => {
1455
- if (!writableStream.isTTY) {
1456
- return;
1457
- }
1458
-
1459
- isHidden = false;
1460
- writableStream.write('\u001B[?25h');
1461
- };
1462
-
1463
- cliCursor.hide = (writableStream = process$2.stderr) => {
1464
- if (!writableStream.isTTY) {
1465
- return;
1466
- }
1467
-
1468
- restoreCursor();
1469
- isHidden = true;
1470
- writableStream.write('\u001B[?25l');
1471
- };
1472
-
1473
- cliCursor.toggle = (force, writableStream) => {
1474
- if (force !== undefined) {
1475
- isHidden = force;
1476
- }
1477
-
1478
- if (isHidden) {
1479
- cliCursor.show(writableStream);
1480
- } else {
1481
- cliCursor.hide(writableStream);
1482
- }
1483
- };
1484
-
1485
- const ESCAPES = new Set([
1486
- '\u001B',
1487
- '\u009B',
1488
- ]);
1489
-
1490
- const END_CODE = 39;
1491
- const ANSI_ESCAPE_BELL = '\u0007';
1492
- const ANSI_CSI = '[';
1493
- const ANSI_OSC = ']';
1494
- const ANSI_SGR_TERMINATOR = 'm';
1495
- const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
1496
-
1497
- const wrapAnsiCode = code => `${ESCAPES.values().next().value}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
1498
- const wrapAnsiHyperlink = uri => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${uri}${ANSI_ESCAPE_BELL}`;
1499
-
1500
- // Calculate the length of words split on ' ', ignoring
1501
- // the extra characters added by ansi escape codes
1502
- const wordLengths = string => string.split(' ').map(character => stringWidth(character));
1503
-
1504
- // Wrap a long word across multiple rows
1505
- // Ansi escape codes do not count towards length
1506
- const wrapWord = (rows, word, columns) => {
1507
- const characters = [...word];
1508
-
1509
- let isInsideEscape = false;
1510
- let isInsideLinkEscape = false;
1511
- let visible = stringWidth(stripAnsi(rows[rows.length - 1]));
1512
-
1513
- for (const [index, character] of characters.entries()) {
1514
- const characterLength = stringWidth(character);
1515
-
1516
- if (visible + characterLength <= columns) {
1517
- rows[rows.length - 1] += character;
1518
- } else {
1519
- rows.push(character);
1520
- visible = 0;
1521
- }
1522
-
1523
- if (ESCAPES.has(character)) {
1524
- isInsideEscape = true;
1525
- isInsideLinkEscape = characters.slice(index + 1).join('').startsWith(ANSI_ESCAPE_LINK);
1526
- }
1527
-
1528
- if (isInsideEscape) {
1529
- if (isInsideLinkEscape) {
1530
- if (character === ANSI_ESCAPE_BELL) {
1531
- isInsideEscape = false;
1532
- isInsideLinkEscape = false;
1533
- }
1534
- } else if (character === ANSI_SGR_TERMINATOR) {
1535
- isInsideEscape = false;
1536
- }
1537
-
1538
- continue;
1539
- }
1540
-
1541
- visible += characterLength;
1542
-
1543
- if (visible === columns && index < characters.length - 1) {
1544
- rows.push('');
1545
- visible = 0;
1546
- }
1547
- }
1548
-
1549
- // It's possible that the last row we copy over is only
1550
- // ansi escape characters, handle this edge-case
1551
- if (!visible && rows[rows.length - 1].length > 0 && rows.length > 1) {
1552
- rows[rows.length - 2] += rows.pop();
1553
- }
1554
- };
1555
-
1556
- // Trims spaces from a string ignoring invisible sequences
1557
- const stringVisibleTrimSpacesRight = string => {
1558
- const words = string.split(' ');
1559
- let last = words.length;
1560
-
1561
- while (last > 0) {
1562
- if (stringWidth(words[last - 1]) > 0) {
1563
- break;
1564
- }
1565
-
1566
- last--;
1567
- }
1568
-
1569
- if (last === words.length) {
1570
- return string;
1571
- }
1572
-
1573
- return words.slice(0, last).join(' ') + words.slice(last).join('');
1574
- };
1575
-
1576
- // The wrap-ansi module can be invoked in either 'hard' or 'soft' wrap mode
1577
- //
1578
- // 'hard' will never allow a string to take up more than columns characters
1579
- //
1580
- // 'soft' allows long words to expand past the column length
1581
- const exec = (string, columns, options = {}) => {
1582
- if (options.trim !== false && string.trim() === '') {
1583
- return '';
1584
- }
1585
-
1586
- let returnValue = '';
1587
- let escapeCode;
1588
- let escapeUrl;
1589
-
1590
- const lengths = wordLengths(string);
1591
- let rows = [''];
1592
-
1593
- for (const [index, word] of string.split(' ').entries()) {
1594
- if (options.trim !== false) {
1595
- rows[rows.length - 1] = rows[rows.length - 1].trimStart();
1596
- }
1597
-
1598
- let rowLength = stringWidth(rows[rows.length - 1]);
1599
-
1600
- if (index !== 0) {
1601
- if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
1602
- // If we start with a new word but the current row length equals the length of the columns, add a new row
1603
- rows.push('');
1604
- rowLength = 0;
1605
- }
1606
-
1607
- if (rowLength > 0 || options.trim === false) {
1608
- rows[rows.length - 1] += ' ';
1609
- rowLength++;
1610
- }
1611
- }
1612
-
1613
- // In 'hard' wrap mode, the length of a line is never allowed to extend past 'columns'
1614
- if (options.hard && lengths[index] > columns) {
1615
- const remainingColumns = (columns - rowLength);
1616
- const breaksStartingThisLine = 1 + Math.floor((lengths[index] - remainingColumns - 1) / columns);
1617
- const breaksStartingNextLine = Math.floor((lengths[index] - 1) / columns);
1618
- if (breaksStartingNextLine < breaksStartingThisLine) {
1619
- rows.push('');
1620
- }
1621
-
1622
- wrapWord(rows, word, columns);
1623
- continue;
1624
- }
1625
-
1626
- if (rowLength + lengths[index] > columns && rowLength > 0 && lengths[index] > 0) {
1627
- if (options.wordWrap === false && rowLength < columns) {
1628
- wrapWord(rows, word, columns);
1629
- continue;
1630
- }
1631
-
1632
- rows.push('');
1633
- }
1634
-
1635
- if (rowLength + lengths[index] > columns && options.wordWrap === false) {
1636
- wrapWord(rows, word, columns);
1637
- continue;
1638
- }
1639
-
1640
- rows[rows.length - 1] += word;
1641
- }
1642
-
1643
- if (options.trim !== false) {
1644
- rows = rows.map(row => stringVisibleTrimSpacesRight(row));
1645
- }
1646
-
1647
- const pre = [...rows.join('\n')];
1648
-
1649
- for (const [index, character] of pre.entries()) {
1650
- returnValue += character;
1651
-
1652
- if (ESCAPES.has(character)) {
1653
- const {groups} = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(pre.slice(index).join('')) || {groups: {}};
1654
- if (groups.code !== undefined) {
1655
- const code = Number.parseFloat(groups.code);
1656
- escapeCode = code === END_CODE ? undefined : code;
1657
- } else if (groups.uri !== undefined) {
1658
- escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
1659
- }
1660
- }
1661
-
1662
- const code = ansiStyles.codes.get(Number(escapeCode));
1663
-
1664
- if (pre[index + 1] === '\n') {
1665
- if (escapeUrl) {
1666
- returnValue += wrapAnsiHyperlink('');
1667
- }
1668
-
1669
- if (escapeCode && code) {
1670
- returnValue += wrapAnsiCode(code);
1671
- }
1672
- } else if (character === '\n') {
1673
- if (escapeCode && code) {
1674
- returnValue += wrapAnsiCode(escapeCode);
1675
- }
1676
-
1677
- if (escapeUrl) {
1678
- returnValue += wrapAnsiHyperlink(escapeUrl);
1679
- }
1680
- }
1681
- }
1682
-
1683
- return returnValue;
1684
- };
1685
-
1686
- // For each newline, invoke the method separately
1687
- function wrapAnsi(string, columns, options) {
1688
- return String(string)
1689
- .normalize()
1690
- .replace(/\r\n/g, '\n')
1691
- .split('\n')
1692
- .map(line => exec(line, columns, options))
1693
- .join('\n');
1694
- }
1695
-
1696
- const defaultTerminalHeight = 24;
1697
-
1698
- const getWidth = stream => {
1699
- const {columns} = stream;
1700
-
1701
- if (!columns) {
1702
- return 80;
1703
- }
1704
-
1705
- return columns;
1706
- };
1707
-
1708
- const fitToTerminalHeight = (stream, text) => {
1709
- const terminalHeight = stream.rows || defaultTerminalHeight;
1710
- const lines = text.split('\n');
1711
-
1712
- const toRemove = lines.length - terminalHeight;
1713
- if (toRemove <= 0) {
1714
- return text;
1715
- }
1716
-
1717
- return sliceAnsi(
1718
- text,
1719
- lines.slice(0, toRemove).join('\n').length + 1,
1720
- text.length);
1721
- };
1722
-
1723
- function createLogUpdate(stream, {showCursor = false} = {}) {
1724
- let previousLineCount = 0;
1725
- let previousWidth = getWidth(stream);
1726
- let previousOutput = '';
1727
-
1728
- const render = (...arguments_) => {
1729
- if (!showCursor) {
1730
- cliCursor.hide();
1731
- }
1732
-
1733
- let output = arguments_.join(' ') + '\n';
1734
- output = fitToTerminalHeight(stream, output);
1735
- const width = getWidth(stream);
1736
- if (output === previousOutput && previousWidth === width) {
1737
- return;
1738
- }
1739
-
1740
- previousOutput = output;
1741
- previousWidth = width;
1742
- output = wrapAnsi(output, width, {
1743
- trim: false,
1744
- hard: true,
1745
- wordWrap: false,
1746
- });
1747
- stream.write(ansiEscapes.eraseLines(previousLineCount) + output);
1748
- previousLineCount = output.split('\n').length;
1749
- };
1750
-
1751
- render.clear = () => {
1752
- stream.write(ansiEscapes.eraseLines(previousLineCount));
1753
- previousOutput = '';
1754
- previousWidth = getWidth(stream);
1755
- previousLineCount = 0;
1756
- };
1757
-
1758
- render.done = () => {
1759
- previousOutput = '';
1760
- previousWidth = getWidth(stream);
1761
- previousLineCount = 0;
1762
-
1763
- if (!showCursor) {
1764
- cliCursor.show();
1765
- }
1766
- };
1767
-
1768
- return render;
1769
- }
1770
-
1771
- createLogUpdate(process$2.stdout);
1772
-
1773
- createLogUpdate(process$2.stderr);
1774
-
1775
- const DURATION_LONG = 300;
1776
- const MAX_HEIGHT = 20;
1777
- const spinnerMap = new WeakMap();
1778
- const outputMap = new WeakMap();
1779
- const pointer = c.yellow(F_POINTER);
1780
- const skipped = c.yellow(F_DOWN);
1781
- function divider(text, left, right) {
1782
- let length = process.stdout.columns;
1783
- if (!length || isNaN(length))
1784
- length = 10;
1785
- if (text) {
1786
- const textLength = stripAnsi(text).length;
1787
- if (left == null && right != null) {
1788
- left = length - textLength - right;
1789
- } else {
1790
- left = left ?? Math.floor((length - textLength) / 2);
1791
- right = length - textLength - left;
1792
- }
1793
- left = Math.max(0, left);
1794
- right = Math.max(0, right);
1795
- return `${F_LONG_DASH.repeat(left)}${text}${F_LONG_DASH.repeat(right)}`;
1796
- }
1797
- return F_LONG_DASH.repeat(length);
1798
- }
1799
- function formatTestPath(root, path) {
1800
- var _a;
1801
- if (isAbsolute(path))
1802
- path = relative(root, path);
1803
- const dir = dirname(path);
1804
- const ext = ((_a = path.match(/(\.(spec|test)\.[cm]?[tj]sx?)$/)) == null ? void 0 : _a[0]) || "";
1805
- const base = basename(path, ext);
1806
- return slash(c.dim(`${dir}/`) + c.bold(base)) + c.dim(ext);
1807
- }
1808
- function renderSnapshotSummary(rootDir, snapshots) {
1809
- const summary = [];
1810
- if (snapshots.added)
1811
- summary.push(c.bold(c.green(`${snapshots.added} written`)));
1812
- if (snapshots.unmatched)
1813
- summary.push(c.bold(c.red(`${snapshots.unmatched} failed`)));
1814
- if (snapshots.updated)
1815
- summary.push(c.bold(c.green(`${snapshots.updated} updated `)));
1816
- if (snapshots.filesRemoved) {
1817
- if (snapshots.didUpdate)
1818
- summary.push(c.bold(c.green(`${snapshots.filesRemoved} files removed `)));
1819
- else
1820
- summary.push(c.bold(c.yellow(`${snapshots.filesRemoved} files obsolete `)));
1821
- }
1822
- if (snapshots.filesRemovedList && snapshots.filesRemovedList.length) {
1823
- const [head, ...tail] = snapshots.filesRemovedList;
1824
- summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, head)}`);
1825
- tail.forEach((key) => {
1826
- summary.push(` ${c.gray(F_DOT)} ${formatTestPath(rootDir, key)}`);
1827
- });
1828
- }
1829
- if (snapshots.unchecked) {
1830
- if (snapshots.didUpdate)
1831
- summary.push(c.bold(c.green(`${snapshots.unchecked} removed`)));
1832
- else
1833
- summary.push(c.bold(c.yellow(`${snapshots.unchecked} obsolete`)));
1834
- snapshots.uncheckedKeysByFile.forEach((uncheckedFile) => {
1835
- summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
1836
- uncheckedFile.keys.forEach((key) => summary.push(` ${c.gray(F_DOT)} ${key}`));
1837
- });
1838
- }
1839
- return summary;
1840
- }
1841
- function getStateString(tasks, name = "tests") {
1842
- if (tasks.length === 0)
1843
- return c.dim(`no ${name}`);
1844
- const passed = tasks.filter((i) => {
1845
- var _a;
1846
- return ((_a = i.result) == null ? void 0 : _a.state) === "pass";
1847
- });
1848
- const failed = tasks.filter((i) => {
1849
- var _a;
1850
- return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
1851
- });
1852
- const skipped2 = tasks.filter((i) => i.mode === "skip");
1853
- const todo = tasks.filter((i) => i.mode === "todo");
1854
- return [
1855
- failed.length ? c.bold(c.red(`${failed.length} failed`)) : null,
1856
- passed.length ? c.bold(c.green(`${passed.length} passed`)) : null,
1857
- skipped2.length ? c.yellow(`${skipped2.length} skipped`) : null,
1858
- todo.length ? c.gray(`${todo.length} todo`) : null
1859
- ].filter(Boolean).join(c.dim(" | ")) + c.gray(` (${tasks.length})`);
1860
- }
1861
- function getStateSymbol(task) {
1862
- if (task.mode === "skip" || task.mode === "todo")
1863
- return skipped;
1864
- if (!task.result)
1865
- return c.gray("\xB7");
1866
- if (task.result.state === "run") {
1867
- if (task.type === "suite")
1868
- return pointer;
1869
- let spinner = spinnerMap.get(task);
1870
- if (!spinner) {
1871
- spinner = elegantSpinner();
1872
- spinnerMap.set(task, spinner);
1873
- }
1874
- return c.yellow(spinner());
1875
- }
1876
- if (task.result.state === "pass")
1877
- return c.green(F_CHECK);
1878
- if (task.result.state === "fail") {
1879
- return task.type === "suite" ? pointer : c.red(F_CROSS);
1880
- }
1881
- return " ";
1882
- }
1883
- function renderTree(tasks, level = 0) {
1884
- var _a, _b, _c, _d;
1885
- let output = [];
1886
- for (const task of tasks) {
1887
- let suffix = "";
1888
- const prefix = ` ${getStateSymbol(task)} `;
1889
- if (task.mode === "skip" || task.mode === "todo")
1890
- suffix += ` ${c.dim("[skipped]")}`;
1891
- if (task.type === "suite")
1892
- suffix += c.dim(` (${getTests(task).length})`);
1893
- if ((_a = task.result) == null ? void 0 : _a.end) {
1894
- const duration = task.result.end - task.result.start;
1895
- if (duration > DURATION_LONG)
1896
- suffix += c.yellow(` ${Math.round(duration)}${c.dim("ms")}`);
1897
- }
1898
- output.push(" ".repeat(level) + prefix + task.name + suffix);
1899
- if (((_b = task.result) == null ? void 0 : _b.state) !== "pass" && outputMap.get(task) != null) {
1900
- let data = outputMap.get(task);
1901
- if (typeof data === "string") {
1902
- data = stripAnsi(data.trim().split("\n").filter(Boolean).pop());
1903
- if (data === "")
1904
- data = void 0;
1905
- }
1906
- if (data != null) {
1907
- const out = `${" ".repeat(level)}${F_RIGHT} ${data}`;
1908
- output.push(` ${c.gray(cliTruncate(out, process.stdout.columns - 3))}`);
1909
- }
1910
- }
1911
- if ((((_c = task.result) == null ? void 0 : _c.state) === "fail" || ((_d = task.result) == null ? void 0 : _d.state) === "run") && task.type === "suite" && task.tasks.length > 0)
1912
- output = output.concat(renderTree(task.tasks, level + 1));
1913
- }
1914
- return output.slice(0, MAX_HEIGHT).join("\n");
1915
- }
1916
- const createRenderer = (_tasks) => {
1917
- let tasks = _tasks;
1918
- let timer;
1919
- const stdout = process.stdout;
1920
- const log = createLogUpdate(stdout);
1921
- function update() {
1922
- log(renderTree(tasks));
1923
- }
1924
- return {
1925
- start() {
1926
- if (timer)
1927
- return this;
1928
- timer = setInterval(update, 200);
1929
- return this;
1930
- },
1931
- update(_tasks2) {
1932
- tasks = _tasks2;
1933
- update();
1934
- return this;
1935
- },
1936
- async stop() {
1937
- if (timer) {
1938
- clearInterval(timer);
1939
- timer = void 0;
1940
- }
1941
- log.clear();
1942
- stdout.write(`${renderTree(tasks)}
1943
- `);
1944
- return this;
1945
- },
1946
- clear() {
1947
- log.clear();
1948
- }
1949
- };
1950
- };
1951
- function getFullName(task) {
1952
- return getNames(task).join(c.dim(" > "));
1953
- }
1954
- const spinnerFrames = process.platform === "win32" ? ["-", "\\", "|", "/"] : ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
1955
- function elegantSpinner() {
1956
- let index = 0;
1957
- return () => {
1958
- index = ++index % spinnerFrames.length;
1959
- return spinnerFrames[index];
1960
- };
1961
- }
1962
-
1963
- const isTTY = process.stdout.isTTY && !process.env.CI;
1964
- class ConsoleReporter {
1965
- constructor(ctx) {
1966
- this.ctx = ctx;
1967
- this.start = 0;
1968
- this.end = 0;
1969
- this.console = globalThis.console;
1970
- this.isFirstWatchRun = true;
1971
- const mode = ctx.config.watch ? c.yellow(" DEV ") : c.cyan(" RUN ");
1972
- this.log(`${c.inverse(c.bold(mode))} ${c.gray(this.ctx.config.root)}
1973
- `);
1974
- this.start = performance.now();
1975
- }
1976
- log(...args) {
1977
- if (this.ctx.config.silent)
1978
- return;
1979
- this.console.log(...args);
1980
- }
1981
- error(...args) {
1982
- if (this.ctx.config.silent)
1983
- return;
1984
- this.console.error(...args);
1985
- }
1986
- relative(path) {
1987
- return relative(this.ctx.config.root, path);
1988
- }
1989
- onStart() {
1990
- if (isTTY) {
1991
- const files = this.ctx.state.getFiles(this.watchFilters);
1992
- if (!this.renderer)
1993
- this.renderer = createRenderer(files).start();
1994
- else
1995
- this.renderer.update(files);
1996
- }
1997
- }
1998
- onTaskUpdate(pack) {
1999
- var _a, _b, _c;
2000
- if (isTTY)
2001
- return;
2002
- const task = this.ctx.state.idMap[pack[0]];
2003
- if (task.type === "test" && ((_a = task.result) == null ? void 0 : _a.state) && ((_b = task.result) == null ? void 0 : _b.state) !== "run") {
2004
- this.log(` ${getStateSymbol(task)} ${getFullName(task)}`);
2005
- if (task.result.state === "fail")
2006
- this.log(c.red(` ${F_RIGHT} ${(_c = task.result.error) == null ? void 0 : _c.message}`));
2007
- }
2008
- }
2009
- async onFinished(files = this.ctx.state.getFiles()) {
2010
- var _a, _b;
2011
- this.end = performance.now();
2012
- await this.stopListRender();
2013
- this.log();
2014
- const suites = getSuites(files);
2015
- const tests = getTests(files);
2016
- const failedSuites = suites.filter((i) => {
2017
- var _a2;
2018
- return (_a2 = i.result) == null ? void 0 : _a2.error;
2019
- });
2020
- const failedTests = tests.filter((i) => {
2021
- var _a2;
2022
- return ((_a2 = i.result) == null ? void 0 : _a2.state) === "fail";
2023
- });
2024
- const failedTotal = failedSuites.length + failedTests.length;
2025
- let current = 1;
2026
- const errorDivider = () => this.error(`${c.red(c.dim(divider(`[${current++}/${failedTotal}]`, void 0, 1)))}
2027
- `);
2028
- if (failedSuites.length) {
2029
- this.error(c.red(divider(c.bold(c.inverse(` Failed Suites ${failedSuites.length} `)))));
2030
- this.error();
2031
- for (const suite of failedSuites) {
2032
- this.error(c.red(`
2033
- - ${getFullName(suite)}`));
2034
- await printError((_a = suite.result) == null ? void 0 : _a.error);
2035
- errorDivider();
2036
- }
2037
- }
2038
- if (failedTests.length) {
2039
- this.error(c.red(divider(c.bold(c.inverse(` Failed Tests ${failedTests.length} `)))));
2040
- this.error();
2041
- for (const test of failedTests) {
2042
- this.error(`${c.red(c.bold(c.inverse(" FAIL ")))} ${getFullName(test)}`);
2043
- await printError((_b = test.result) == null ? void 0 : _b.error);
2044
- errorDivider();
2045
- }
2046
- }
2047
- const executionTime = this.end - this.start;
2048
- const threadTime = tests.reduce((acc, test) => {
2049
- var _a2;
2050
- return acc + (((_a2 = test.result) == null ? void 0 : _a2.end) ? test.result.end - test.result.start : 0);
2051
- }, 0);
2052
- const padTitle = (str) => c.dim(`${str.padStart(10)} `);
2053
- const time = (time2) => {
2054
- if (time2 > 1e3)
2055
- return `${(time2 / 1e3).toFixed(2)}s`;
2056
- return `${Math.round(time2)}ms`;
2057
- };
2058
- const snapshotOutput = renderSnapshotSummary(this.ctx.config.root, this.ctx.snapshot.summary);
2059
- if (snapshotOutput.length) {
2060
- this.log(snapshotOutput.map((t, i) => i === 0 ? `${padTitle("Snapshots")} ${t}` : `${padTitle("")} ${t}`).join("\n"));
2061
- if (snapshotOutput.length > 1)
2062
- this.log();
2063
- }
2064
- this.log(padTitle("Test Files"), getStateString(files));
2065
- this.log(padTitle("Tests"), getStateString(tests));
2066
- if (this.watchFilters)
2067
- this.log(padTitle("Time"), time(threadTime));
2068
- else
2069
- this.log(padTitle("Time"), time(executionTime) + c.gray(` (in thread ${time(threadTime)}, ${(executionTime / threadTime * 100).toFixed(2)}%)`));
2070
- this.log();
2071
- }
2072
- async onWatcherStart() {
2073
- await this.stopListRender();
2074
- const failed = getTests(this.ctx.state.getFiles()).filter((i) => {
2075
- var _a;
2076
- return ((_a = i.result) == null ? void 0 : _a.state) === "fail";
2077
- });
2078
- if (failed.length)
2079
- this.log(`
2080
- ${c.bold(c.inverse(c.red(" FAIL ")))}${c.red(` ${failed.length} tests failed. Watching for file changes...`)}`);
2081
- else
2082
- this.log(`
2083
- ${c.bold(c.inverse(c.green(" PASS ")))}${c.green(" Waiting for file changes...")}`);
2084
- if (this.isFirstWatchRun) {
2085
- this.isFirstWatchRun = false;
2086
- this.log(c.gray("press any key to exit..."));
2087
- }
2088
- }
2089
- async onWatcherRerun(files, trigger) {
2090
- await this.stopListRender();
2091
- this.watchFilters = files;
2092
- this.console.clear();
2093
- this.log(c.blue("Re-running tests...") + c.dim(` [ ${this.relative(trigger)} ]
2094
- `));
2095
- }
2096
- async stopListRender() {
2097
- var _a;
2098
- (_a = this.renderer) == null ? void 0 : _a.stop();
2099
- this.renderer = void 0;
2100
- await new Promise((resolve) => setTimeout(resolve, 10));
2101
- }
2102
- onUserConsoleLog(log) {
2103
- var _a;
2104
- (_a = this.renderer) == null ? void 0 : _a.clear();
2105
- const task = log.taskId ? this.ctx.state.idMap[log.taskId] : void 0;
2106
- this.log(c.gray(log.type + c.dim(` | ${task ? getFullName(task) : "unknown test"}`)));
2107
- process[log.type].write(`${log.content}
2108
- `);
2109
- }
2110
- }
2111
-
2112
- class StateManager {
2113
- constructor() {
2114
- this.filesMap = {};
2115
- this.idMap = {};
2116
- this.taskFileMap = new WeakMap();
2117
- }
2118
- getFiles(keys) {
2119
- if (keys)
2120
- return keys.map((key) => this.filesMap[key]);
2121
- return Object.values(this.filesMap);
2122
- }
2123
- collectFiles(files) {
2124
- files.forEach((file) => {
2125
- this.filesMap[file.filepath] = file;
2126
- this.updateId(file);
2127
- });
2128
- }
2129
- updateId(task) {
2130
- if (this.idMap[task.id] === task)
2131
- return;
2132
- this.idMap[task.id] = task;
2133
- if (task.type === "suite") {
2134
- task.tasks.forEach((task2) => {
2135
- this.updateId(task2);
2136
- });
2137
- }
2138
- }
2139
- updateTasks(packs) {
2140
- for (const [id, result] of packs) {
2141
- if (this.idMap[id])
2142
- this.idMap[id].result = result;
2143
- }
2144
- }
2145
- }
2146
-
2147
- var __defProp$1 = Object.defineProperty;
2148
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
2149
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
2150
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
2151
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2152
- var __spreadValues$1 = (a, b) => {
2153
- for (var prop in b || (b = {}))
2154
- if (__hasOwnProp$1.call(b, prop))
2155
- __defNormalProp$1(a, prop, b[prop]);
2156
- if (__getOwnPropSymbols$1)
2157
- for (var prop of __getOwnPropSymbols$1(b)) {
2158
- if (__propIsEnum$1.call(b, prop))
2159
- __defNormalProp$1(a, prop, b[prop]);
2160
- }
2161
- return a;
2162
- };
2163
- async function initVitest(options = {}) {
2164
- const root = resolve(options.root || process.cwd());
2165
- process.chdir(root);
2166
- if (options.dom)
2167
- options.environment = "happy-dom";
2168
- const configPath = options.config ? resolve(root, options.config) : await findUp(configFiles, { cwd: root });
2169
- const resolved = __spreadValues$1({}, options);
2170
- resolved.config = configPath;
2171
- resolved.root = root;
2172
- const server = await createServer({
2173
- root,
2174
- logLevel: "error",
2175
- clearScreen: false,
2176
- configFile: resolved.config,
2177
- plugins: [
2178
- {
2179
- name: "vitest",
2180
- configResolved(viteConfig) {
2181
- resolveConfig(resolved, viteConfig);
2182
- },
2183
- async configureServer(server2) {
2184
- if (resolved.api)
2185
- server2.middlewares.use((await import('./middleware-b567041c.js')).default());
2186
- }
2187
- }
2188
- ],
2189
- server: {
2190
- open: options.open,
2191
- strictPort: true
2192
- },
2193
- optimizeDeps: {
2194
- exclude: [
2195
- "vitest"
2196
- ]
2197
- }
2198
- });
2199
- await server.pluginContainer.buildStart({});
2200
- if (typeof resolved.api === "number")
2201
- await server.listen(resolved.api);
2202
- const ctx = {
2203
- server,
2204
- config: resolved,
2205
- state: new StateManager(),
2206
- snapshot: new SnapshotManager(resolved),
2207
- reporters: toArray(resolved.reporters),
2208
- console: globalThis.console
2209
- };
2210
- if (!ctx.reporters.length)
2211
- ctx.reporters.push(new ConsoleReporter(ctx));
2212
- return ctx;
2213
- }
2214
- function resolveConfig(resolved, viteConfig) {
2215
- var _a, _b;
2216
- Object.assign(resolved, viteConfig.test);
2217
- resolved.depsInline = ((_a = resolved.deps) == null ? void 0 : _a.inline) || [];
2218
- resolved.depsExternal = ((_b = resolved.deps) == null ? void 0 : _b.external) || [];
2219
- resolved.environment = resolved.environment || "node";
2220
- resolved.threads = resolved.threads ?? true;
2221
- resolved.interpretDefault = resolved.interpretDefault ?? true;
2222
- resolved.include = resolved.include ?? defaultInclude;
2223
- resolved.exclude = resolved.exclude ?? defaultExclude;
2224
- const CI = !!process.env.CI;
2225
- const UPDATE_SNAPSHOT = resolved.update || process.env.UPDATE_SNAPSHOT;
2226
- resolved.snapshotOptions = {
2227
- updateSnapshot: CI && !UPDATE_SNAPSHOT ? "none" : UPDATE_SNAPSHOT ? "all" : "new"
2228
- };
2229
- if (process.env.VITEST_MAX_THREADS)
2230
- resolved.maxThreads = parseInt(process.env.VITEST_MAX_THREADS);
2231
- if (process.env.VITEST_MIN_THREADS)
2232
- resolved.minThreads = parseInt(process.env.VITEST_MIN_THREADS);
2233
- resolved.setupFiles = Array.from(resolved.setupFiles || []).map((i) => resolve(resolved.root, i));
2234
- if (resolved.api === true)
2235
- resolved.api = defaultPort;
2236
- }
2237
-
2238
- async function transformRequest(server, id) {
2239
- if (id.match(/\.(?:[cm]?[jt]sx?|json)$/)) {
2240
- return await server.transformRequest(id, { ssr: true });
2241
- } else {
2242
- const result = await server.transformRequest(id);
2243
- if (!result)
2244
- return void 0;
2245
- return await server.ssrTransform(result.code, result.map, id);
2246
- }
2247
- }
2248
-
2249
- function createPool(ctx) {
2250
- if (ctx.config.threads)
2251
- return createWorkerPool(ctx);
2252
- else
2253
- return createFakePool(ctx);
2254
- }
2255
- const workerPath = new URL("./dist/worker.js", pathToFileURL(distDir)).href;
2256
- function createFakePool(ctx) {
2257
- const runTestFiles = async (files, invalidates) => {
2258
- const { default: run } = await import(workerPath);
2259
- const { workerPort, port } = createChannel(ctx);
2260
- const data = {
2261
- port: workerPort,
2262
- config: ctx.config,
2263
- files,
2264
- invalidates
2265
- };
2266
- await run(data, { transferList: [workerPort] });
2267
- port.close();
2268
- workerPort.close();
2269
- };
2270
- return {
2271
- runTestFiles,
2272
- close: async () => {
2273
- }
2274
- };
2275
- }
2276
- function createWorkerPool(ctx) {
2277
- const options = {
2278
- filename: workerPath,
2279
- useAtomics: false
2280
- };
2281
- if (ctx.config.maxThreads != null)
2282
- options.maxThreads = ctx.config.maxThreads;
2283
- if (ctx.config.minThreads != null)
2284
- options.minThreads = ctx.config.minThreads;
2285
- const piscina = new Piscina(options);
2286
- const runTestFiles = async (files, invalidates) => {
2287
- await Promise.all(files.map(async (file) => {
2288
- const { workerPort, port } = createChannel(ctx);
2289
- const data = {
2290
- port: workerPort,
2291
- config: ctx.config,
2292
- files: [file],
2293
- invalidates
2294
- };
2295
- await piscina.run(data, { transferList: [workerPort] });
2296
- port.close();
2297
- workerPort.close();
2298
- }));
2299
- };
2300
- return {
2301
- runTestFiles,
2302
- close: () => piscina.destroy()
2303
- };
2304
- }
2305
- function createChannel(ctx) {
2306
- const channel = new MessageChannel();
2307
- const port = channel.port2;
2308
- const workerPort = channel.port1;
2309
- port.on("message", async ({ id, method, args = [] }) => {
2310
- async function send(fn) {
2311
- try {
2312
- port.postMessage({ id, result: await fn() });
2313
- } catch (e) {
2314
- port.postMessage({ id, error: e });
2315
- }
2316
- }
2317
- switch (method) {
2318
- case "processExit":
2319
- process.exit(args[0] || 1);
2320
- return;
2321
- case "snapshotSaved":
2322
- return send(() => ctx.snapshot.add(args[0]));
2323
- case "fetch":
2324
- return send(() => transformRequest(ctx.server, ...args));
2325
- case "onCollected":
2326
- ctx.state.collectFiles(args[0]);
2327
- ctx.reporters.forEach((r) => {
2328
- var _a;
2329
- return (_a = r.onStart) == null ? void 0 : _a.call(r, args[0].map((i) => i.filepath));
2330
- });
2331
- return;
2332
- case "onTaskUpdate":
2333
- ctx.state.updateTasks([args[0]]);
2334
- ctx.reporters.forEach((r) => {
2335
- var _a;
2336
- return (_a = r.onTaskUpdate) == null ? void 0 : _a.call(r, args[0]);
2337
- });
2338
- return;
2339
- case "log":
2340
- ctx.reporters.forEach((r) => {
2341
- var _a;
2342
- return (_a = r.onUserConsoleLog) == null ? void 0 : _a.call(r, args[0]);
2343
- });
2344
- return;
2345
- }
2346
- console.error("Unhandled message", method, args);
2347
- });
2348
- return { workerPort, port };
2349
- }
2350
-
2351
- function isTargetFile(id, config) {
2352
- if (mm.isMatch(id, config.exclude))
2353
- return false;
2354
- return mm.isMatch(id, config.include);
2355
- }
2356
- async function globTestFiles(config) {
2357
- var _a;
2358
- let testFilepaths = await fg(config.include, {
2359
- absolute: true,
2360
- cwd: config.root,
2361
- ignore: config.exclude
2362
- });
2363
- if ((_a = config.cliFilters) == null ? void 0 : _a.length)
2364
- testFilepaths = testFilepaths.filter((i) => config.cliFilters.some((f) => i.includes(f)));
2365
- return testFilepaths;
2366
- }
2367
-
2368
- const WATCHER_DEBOUNCE = 50;
2369
- async function startWatcher(ctx, pool) {
2370
- const { server } = ctx;
2371
- ctx.reporters.forEach((r) => {
2372
- var _a;
2373
- return (_a = r.onWatcherStart) == null ? void 0 : _a.call(r);
2374
- });
2375
- let timer;
2376
- const changedTests = new Set();
2377
- const seen = new Set();
2378
- let isFirstRun = true;
2379
- let promise;
2380
- server.watcher.on("change", (id) => {
2381
- id = slash(id);
2382
- getAffectedTests(ctx, id, changedTests, seen);
2383
- if (changedTests.size === 0)
2384
- return;
2385
- rerunFile(id);
2386
- });
2387
- server.watcher.on("unlink", (id) => {
2388
- id = slash(id);
2389
- seen.add(id);
2390
- if (id in ctx.state.filesMap) {
2391
- delete ctx.state.filesMap[id];
2392
- changedTests.delete(id);
2393
- }
2394
- });
2395
- server.watcher.on("add", async (id) => {
2396
- id = slash(id);
2397
- if (isTargetFile(id, ctx.config)) {
2398
- changedTests.add(id);
2399
- rerunFile(id);
2400
- }
2401
- });
2402
- async function rerunFile(id) {
2403
- await promise;
2404
- clearTimeout(timer);
2405
- timer = setTimeout(async () => {
2406
- if (changedTests.size === 0) {
2407
- seen.clear();
2408
- return;
2409
- }
2410
- isFirstRun = false;
2411
- ctx.state.getFiles().forEach((file) => {
2412
- var _a;
2413
- if (((_a = file.result) == null ? void 0 : _a.state) === "fail")
2414
- changedTests.add(file.filepath);
2415
- });
2416
- const invalidates = Array.from(seen);
2417
- const tests = Array.from(changedTests);
2418
- changedTests.clear();
2419
- seen.clear();
2420
- promise = start(tests, id, invalidates).then(() => {
2421
- promise = void 0;
2422
- });
2423
- await promise;
2424
- }, WATCHER_DEBOUNCE);
2425
- }
2426
- async function start(tests, id, invalidates) {
2427
- await Promise.all(ctx.reporters.map((r) => {
2428
- var _a;
2429
- return (_a = r.onWatcherRerun) == null ? void 0 : _a.call(r, tests, id);
2430
- }));
2431
- await pool.runTestFiles(tests, invalidates);
2432
- await Promise.all(ctx.reporters.map((r) => {
2433
- var _a;
2434
- return (_a = r.onFinished) == null ? void 0 : _a.call(r, ctx.state.getFiles(tests));
2435
- }));
2436
- await Promise.all(ctx.reporters.map((r) => {
2437
- var _a;
2438
- return (_a = r.onWatcherStart) == null ? void 0 : _a.call(r);
2439
- }));
2440
- }
2441
- if (process.stdin.isTTY) {
2442
- readline.emitKeypressEvents(process.stdin);
2443
- process.stdin.setRawMode(true);
2444
- process.stdin.on("keypress", (str) => {
2445
- if (str === "" || str === "")
2446
- process.exit();
2447
- if (promise)
2448
- return;
2449
- if (isFirstRun)
2450
- process.exit();
2451
- });
2452
- }
2453
- await new Promise(() => {
2454
- });
2455
- }
2456
- function getAffectedTests(ctx, id, set = new Set(), seen = new Set()) {
2457
- if (seen.has(id) || set.has(id) || id.includes("/node_modules/") || id.includes("/vitest/dist/"))
2458
- return set;
2459
- seen.add(id);
2460
- if (id in ctx.state.filesMap) {
2461
- set.add(id);
2462
- return set;
2463
- }
2464
- const mod = ctx.server.moduleGraph.getModuleById(id);
2465
- if (mod) {
2466
- mod.importers.forEach((i) => {
2467
- if (i.id)
2468
- getAffectedTests(ctx, i.id, set, seen);
2469
- });
2470
- }
2471
- return set;
2472
- }
2473
-
2474
- async function start(ctx) {
2475
- const { config } = ctx;
2476
- const testFilepaths = await globTestFiles(config);
2477
- if (!testFilepaths.length) {
2478
- console.error("No test files found");
2479
- process.exitCode = 1;
2480
- return;
2481
- }
2482
- const pool = createPool(ctx);
2483
- await pool.runTestFiles(testFilepaths);
2484
- if (hasFailed(ctx.state.getFiles()))
2485
- process.exitCode = 1;
2486
- await Promise.all(ctx.reporters.map((r) => {
2487
- var _a;
2488
- return (_a = r.onFinished) == null ? void 0 : _a.call(r, ctx.state.getFiles());
2489
- }));
2490
- if (config.watch)
2491
- await startWatcher(ctx, pool);
2492
- else
2493
- await pool.close();
2494
- }
2495
-
2496
- var __defProp = Object.defineProperty;
2497
- var __defProps = Object.defineProperties;
2498
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
2499
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
2500
- var __hasOwnProp = Object.prototype.hasOwnProperty;
2501
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
2502
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2503
- var __spreadValues = (a, b) => {
2504
- for (var prop in b || (b = {}))
2505
- if (__hasOwnProp.call(b, prop))
2506
- __defNormalProp(a, prop, b[prop]);
2507
- if (__getOwnPropSymbols)
2508
- for (var prop of __getOwnPropSymbols(b)) {
2509
- if (__propIsEnum.call(b, prop))
2510
- __defNormalProp(a, prop, b[prop]);
2511
- }
2512
- return a;
2513
- };
2514
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
2515
636
  const cli = cac("vitest");
2516
637
  cli.version(version).option("-r, --root <path>", "root path").option("-c, --config <path>", "path to config file").option("-u, --update", "update snapshot").option("-w, --watch", "watch mode").option("-o, --open", "open Vitest UI").option("--api", "listen to port and serve API").option("--threads", "enabled threads", { default: true }).option("--silent", "silent").option("--global", "inject apis globally").option("--dom", "mock browser api with happy-dom").option("--environment <env>", "runner environment", {
2517
638
  default: "node"
@@ -2526,22 +647,22 @@ async function dev(cliFilters, argv) {
2526
647
  argv.watch = !process.env.CI && !process.env.NODE_V8_COVERAGE;
2527
648
  await run(cliFilters, argv);
2528
649
  }
2529
- async function run(cliFilters, argv) {
650
+ async function run(cliFilters, options) {
2530
651
  process.env.VITEST = "true";
2531
652
  process.env.NODE_ENV = "test";
2532
- if (!argv.silent) {
653
+ if (!options.silent) {
2533
654
  console.log(c.magenta(c.bold("\nVitest is in closed beta exclusively for Sponsors")));
2534
655
  console.log(c.yellow("Learn more at https://vitest.dev\n"));
2535
656
  }
2536
- const ctx = await initVitest(__spreadProps(__spreadValues({}, argv), { cliFilters }));
657
+ const ctx = await createVitest(options);
2537
658
  process.__vitest__ = ctx;
2538
659
  try {
2539
- await start(ctx);
660
+ await ctx.run(cliFilters);
2540
661
  } catch (e) {
2541
662
  process.exitCode = 1;
2542
663
  throw e;
2543
664
  } finally {
2544
665
  if (!ctx.config.watch)
2545
- await ctx.server.close();
666
+ await ctx.close();
2546
667
  }
2547
668
  }