vitest 0.0.77 → 0.0.81

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