@rstest/core 0.6.5 → 0.6.7

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/155.js ADDED
@@ -0,0 +1,2561 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
3
+ import { __webpack_require__ } from "./rslib-runtime.js";
4
+ import { EventEmitter } from "events";
5
+ import { createRsbuild, loadConfig, logger, mergeRsbuildConfig } from "@rsbuild/core";
6
+ import { basename, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE, isTTY, dirname, posix, resolve as pathe_M_eThtNZ_resolve, pathe_M_eThtNZ_relative, DEFAULT_CONFIG_NAME, globalApis, formatTestPath, getAbsolutePath, filterProjects, join, formatRootStr, isDynamicPattern, glob, writeFile, castArray, src_logger, prettyTestPath, prettyTime, isDebug, isAbsolute, getTaskNameWithPrefix, formatError, normalize, TEMP_RSTEST_OUTPUT_DIR_GLOB } from "./946.js";
7
+ import { decode } from "./397.js";
8
+ function toArr(any) {
9
+ return null == any ? [] : Array.isArray(any) ? any : [
10
+ any
11
+ ];
12
+ }
13
+ function toVal(out, key, val, opts) {
14
+ var x, old = out[key], nxt = ~opts.string.indexOf(key) ? null == val || true === val ? '' : String(val) : 'boolean' == typeof val ? val : ~opts.boolean.indexOf(key) ? 'false' === val ? false : 'true' === val || (out._.push((x = +val, 0 * x === 0) ? x : val), !!val) : (x = +val, 0 * x === 0) ? x : val;
15
+ out[key] = null == old ? nxt : Array.isArray(old) ? old.concat(nxt) : [
16
+ old,
17
+ nxt
18
+ ];
19
+ }
20
+ function mri2(args, opts) {
21
+ args = args || [];
22
+ opts = opts || {};
23
+ var k, arr, arg, name, val, out = {
24
+ _: []
25
+ };
26
+ var i = 0, j = 0, idx = 0, len = args.length;
27
+ const alibi = void 0 !== opts.alias;
28
+ const strict = void 0 !== opts.unknown;
29
+ const defaults = void 0 !== opts.default;
30
+ opts.alias = opts.alias || {};
31
+ opts.string = toArr(opts.string);
32
+ opts.boolean = toArr(opts.boolean);
33
+ if (alibi) for(k in opts.alias){
34
+ arr = opts.alias[k] = toArr(opts.alias[k]);
35
+ for(i = 0; i < arr.length; i++)(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
36
+ }
37
+ for(i = opts.boolean.length; i-- > 0;){
38
+ arr = opts.alias[opts.boolean[i]] || [];
39
+ for(j = arr.length; j-- > 0;)opts.boolean.push(arr[j]);
40
+ }
41
+ for(i = opts.string.length; i-- > 0;){
42
+ arr = opts.alias[opts.string[i]] || [];
43
+ for(j = arr.length; j-- > 0;)opts.string.push(arr[j]);
44
+ }
45
+ if (defaults) for(k in opts.default){
46
+ name = typeof opts.default[k];
47
+ arr = opts.alias[k] = opts.alias[k] || [];
48
+ if (void 0 !== opts[name]) {
49
+ opts[name].push(k);
50
+ for(i = 0; i < arr.length; i++)opts[name].push(arr[i]);
51
+ }
52
+ }
53
+ const keys = strict ? Object.keys(opts.alias) : [];
54
+ for(i = 0; i < len; i++){
55
+ arg = args[i];
56
+ if ('--' === arg) {
57
+ out._ = out._.concat(args.slice(++i));
58
+ break;
59
+ }
60
+ for(j = 0; j < arg.length && 45 === arg.charCodeAt(j); j++);
61
+ if (0 === j) out._.push(arg);
62
+ else if ('no-' === arg.substring(j, j + 3)) {
63
+ name = arg.substring(j + 3);
64
+ if (strict && !~keys.indexOf(name)) return opts.unknown(arg);
65
+ out[name] = false;
66
+ } else {
67
+ for(idx = j + 1; idx < arg.length && 61 !== arg.charCodeAt(idx); idx++);
68
+ name = arg.substring(j, idx);
69
+ val = arg.substring(++idx) || i + 1 === len || 45 === ('' + args[i + 1]).charCodeAt(0) || args[++i];
70
+ arr = 2 === j ? [
71
+ name
72
+ ] : name;
73
+ for(idx = 0; idx < arr.length; idx++){
74
+ name = arr[idx];
75
+ if (strict && !~keys.indexOf(name)) return opts.unknown('-'.repeat(j) + name);
76
+ toVal(out, name, idx + 1 < arr.length || val, opts);
77
+ }
78
+ }
79
+ }
80
+ if (defaults) {
81
+ for(k in opts.default)if (void 0 === out[k]) out[k] = opts.default[k];
82
+ }
83
+ if (alibi) for(k in out){
84
+ arr = opts.alias[k] || [];
85
+ while(arr.length > 0)out[arr.shift()] = out[k];
86
+ }
87
+ return out;
88
+ }
89
+ const removeBrackets = (v)=>v.replace(/[<[].+/, "").trim();
90
+ const findAllBrackets = (v)=>{
91
+ const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
92
+ const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
93
+ const res = [];
94
+ const parse = (match)=>{
95
+ let variadic = false;
96
+ let value = match[1];
97
+ if (value.startsWith("...")) {
98
+ value = value.slice(3);
99
+ variadic = true;
100
+ }
101
+ return {
102
+ required: match[0].startsWith("<"),
103
+ value,
104
+ variadic
105
+ };
106
+ };
107
+ let angledMatch;
108
+ while(angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v))res.push(parse(angledMatch));
109
+ let squareMatch;
110
+ while(squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))res.push(parse(squareMatch));
111
+ return res;
112
+ };
113
+ const getMriOptions = (options)=>{
114
+ const result = {
115
+ alias: {},
116
+ boolean: []
117
+ };
118
+ for (const [index, option] of options.entries()){
119
+ if (option.names.length > 1) result.alias[option.names[0]] = option.names.slice(1);
120
+ if (option.isBoolean) if (option.negated) {
121
+ const hasStringTypeOption = options.some((o, i)=>i !== index && o.names.some((name)=>option.names.includes(name)) && "boolean" == typeof o.required);
122
+ if (!hasStringTypeOption) result.boolean.push(option.names[0]);
123
+ } else result.boolean.push(option.names[0]);
124
+ }
125
+ return result;
126
+ };
127
+ const findLongest = (arr)=>arr.sort((a, b)=>a.length > b.length ? -1 : 1)[0];
128
+ const padRight = (str, length)=>str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
129
+ const camelcase = (input)=>input.replace(/([a-z])-([a-z])/g, (_, p1, p2)=>p1 + p2.toUpperCase());
130
+ const setDotProp = (obj, keys, val)=>{
131
+ let i = 0;
132
+ let length = keys.length;
133
+ let t = obj;
134
+ let x;
135
+ for(; i < length; ++i){
136
+ x = t[keys[i]];
137
+ t = t[keys[i]] = i === length - 1 ? val : null != x ? x : !~keys[i + 1].indexOf(".") && +keys[i + 1] > -1 ? [] : {};
138
+ }
139
+ };
140
+ const setByType = (obj, transforms)=>{
141
+ for (const key of Object.keys(transforms)){
142
+ const transform = transforms[key];
143
+ if (transform.shouldTransform) {
144
+ obj[key] = Array.prototype.concat.call([], obj[key]);
145
+ if ("function" == typeof transform.transformFunction) obj[key] = obj[key].map(transform.transformFunction);
146
+ }
147
+ }
148
+ };
149
+ const getFileName = (input)=>{
150
+ const m = /([^\\\/]+)$/.exec(input);
151
+ return m ? m[1] : "";
152
+ };
153
+ const camelcaseOptionName = (name)=>name.split(".").map((v, i)=>0 === i ? camelcase(v) : v).join(".");
154
+ class CACError extends Error {
155
+ constructor(message){
156
+ super(message);
157
+ this.name = this.constructor.name;
158
+ if ("function" == typeof Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
159
+ else this.stack = new Error(message).stack;
160
+ }
161
+ }
162
+ class Option {
163
+ constructor(rawName, description, config){
164
+ this.rawName = rawName;
165
+ this.description = description;
166
+ this.config = Object.assign({}, config);
167
+ rawName = rawName.replace(/\.\*/g, "");
168
+ this.negated = false;
169
+ this.names = removeBrackets(rawName).split(",").map((v)=>{
170
+ let name = v.trim().replace(/^-{1,2}/, "");
171
+ if (name.startsWith("no-")) {
172
+ this.negated = true;
173
+ name = name.replace(/^no-/, "");
174
+ }
175
+ return camelcaseOptionName(name);
176
+ }).sort((a, b)=>a.length > b.length ? 1 : -1);
177
+ this.name = this.names[this.names.length - 1];
178
+ if (this.negated && null == this.config.default) this.config.default = true;
179
+ if (rawName.includes("<")) this.required = true;
180
+ else if (rawName.includes("[")) this.required = false;
181
+ else this.isBoolean = true;
182
+ }
183
+ }
184
+ const processArgs = process.argv;
185
+ const platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
186
+ class Command {
187
+ constructor(rawName, description, config = {}, cli){
188
+ this.rawName = rawName;
189
+ this.description = description;
190
+ this.config = config;
191
+ this.cli = cli;
192
+ this.options = [];
193
+ this.aliasNames = [];
194
+ this.name = removeBrackets(rawName);
195
+ this.args = findAllBrackets(rawName);
196
+ this.examples = [];
197
+ }
198
+ usage(text) {
199
+ this.usageText = text;
200
+ return this;
201
+ }
202
+ allowUnknownOptions() {
203
+ this.config.allowUnknownOptions = true;
204
+ return this;
205
+ }
206
+ ignoreOptionDefaultValue() {
207
+ this.config.ignoreOptionDefaultValue = true;
208
+ return this;
209
+ }
210
+ version(version, customFlags = "-v, --version") {
211
+ this.versionNumber = version;
212
+ this.option(customFlags, "Display version number");
213
+ return this;
214
+ }
215
+ example(example) {
216
+ this.examples.push(example);
217
+ return this;
218
+ }
219
+ option(rawName, description, config) {
220
+ const option = new Option(rawName, description, config);
221
+ this.options.push(option);
222
+ return this;
223
+ }
224
+ alias(name) {
225
+ this.aliasNames.push(name);
226
+ return this;
227
+ }
228
+ action(callback) {
229
+ this.commandAction = callback;
230
+ return this;
231
+ }
232
+ isMatched(name) {
233
+ return this.name === name || this.aliasNames.includes(name);
234
+ }
235
+ get isDefaultCommand() {
236
+ return "" === this.name || this.aliasNames.includes("!");
237
+ }
238
+ get isGlobalCommand() {
239
+ return this instanceof GlobalCommand;
240
+ }
241
+ hasOption(name) {
242
+ name = name.split(".")[0];
243
+ return this.options.find((option)=>option.names.includes(name));
244
+ }
245
+ outputHelp() {
246
+ const { name, commands } = this.cli;
247
+ const { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand;
248
+ let sections = [
249
+ {
250
+ body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
251
+ }
252
+ ];
253
+ sections.push({
254
+ title: "Usage",
255
+ body: ` $ ${name} ${this.usageText || this.rawName}`
256
+ });
257
+ const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
258
+ if (showCommands) {
259
+ const longestCommandName = findLongest(commands.map((command)=>command.rawName));
260
+ sections.push({
261
+ title: "Commands",
262
+ body: commands.map((command)=>` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`).join("\n")
263
+ });
264
+ sections.push({
265
+ title: "For more info, run any command with the `--help` flag",
266
+ body: commands.map((command)=>` $ ${name}${"" === command.name ? "" : ` ${command.name}`} --help`).join("\n")
267
+ });
268
+ }
269
+ let options = this.isGlobalCommand ? globalOptions : [
270
+ ...this.options,
271
+ ...globalOptions || []
272
+ ];
273
+ if (!this.isGlobalCommand && !this.isDefaultCommand) options = options.filter((option)=>"version" !== option.name);
274
+ if (options.length > 0) {
275
+ const longestOptionName = findLongest(options.map((option)=>option.rawName));
276
+ sections.push({
277
+ title: "Options",
278
+ body: options.map((option)=>` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${void 0 === option.config.default ? "" : `(default: ${option.config.default})`}`).join("\n")
279
+ });
280
+ }
281
+ if (this.examples.length > 0) sections.push({
282
+ title: "Examples",
283
+ body: this.examples.map((example)=>{
284
+ if ("function" == typeof example) return example(name);
285
+ return example;
286
+ }).join("\n")
287
+ });
288
+ if (helpCallback) sections = helpCallback(sections) || sections;
289
+ console.log(sections.map((section)=>section.title ? `${section.title}:
290
+ ${section.body}` : section.body).join("\n\n"));
291
+ }
292
+ outputVersion() {
293
+ const { name } = this.cli;
294
+ const { versionNumber } = this.cli.globalCommand;
295
+ if (versionNumber) console.log(`${name}/${versionNumber} ${platformInfo}`);
296
+ }
297
+ checkRequiredArgs() {
298
+ const minimalArgsCount = this.args.filter((arg)=>arg.required).length;
299
+ if (this.cli.args.length < minimalArgsCount) throw new CACError(`missing required args for command \`${this.rawName}\``);
300
+ }
301
+ checkUnknownOptions() {
302
+ const { options, globalCommand } = this.cli;
303
+ if (!this.config.allowUnknownOptions) {
304
+ for (const name of Object.keys(options))if ("--" !== name && !this.hasOption(name) && !globalCommand.hasOption(name)) throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
305
+ }
306
+ }
307
+ checkOptionValue() {
308
+ const { options: parsedOptions, globalCommand } = this.cli;
309
+ const options = [
310
+ ...globalCommand.options,
311
+ ...this.options
312
+ ];
313
+ for (const option of options){
314
+ const value = parsedOptions[option.name.split(".")[0]];
315
+ if (option.required) {
316
+ const hasNegated = options.some((o)=>o.negated && o.names.includes(option.name));
317
+ if (true === value || false === value && !hasNegated) throw new CACError(`option \`${option.rawName}\` value is missing`);
318
+ }
319
+ }
320
+ }
321
+ }
322
+ class GlobalCommand extends Command {
323
+ constructor(cli){
324
+ super("@@global@@", "", {}, cli);
325
+ }
326
+ }
327
+ var __assign = Object.assign;
328
+ class CAC extends EventEmitter {
329
+ constructor(name = ""){
330
+ super();
331
+ this.name = name;
332
+ this.commands = [];
333
+ this.rawArgs = [];
334
+ this.args = [];
335
+ this.options = {};
336
+ this.globalCommand = new GlobalCommand(this);
337
+ this.globalCommand.usage("<command> [options]");
338
+ }
339
+ usage(text) {
340
+ this.globalCommand.usage(text);
341
+ return this;
342
+ }
343
+ command(rawName, description, config) {
344
+ const command = new Command(rawName, description || "", config, this);
345
+ command.globalCommand = this.globalCommand;
346
+ this.commands.push(command);
347
+ return command;
348
+ }
349
+ option(rawName, description, config) {
350
+ this.globalCommand.option(rawName, description, config);
351
+ return this;
352
+ }
353
+ help(callback) {
354
+ this.globalCommand.option("-h, --help", "Display this message");
355
+ this.globalCommand.helpCallback = callback;
356
+ this.showHelpOnExit = true;
357
+ return this;
358
+ }
359
+ version(version, customFlags = "-v, --version") {
360
+ this.globalCommand.version(version, customFlags);
361
+ this.showVersionOnExit = true;
362
+ return this;
363
+ }
364
+ example(example) {
365
+ this.globalCommand.example(example);
366
+ return this;
367
+ }
368
+ outputHelp() {
369
+ if (this.matchedCommand) this.matchedCommand.outputHelp();
370
+ else this.globalCommand.outputHelp();
371
+ }
372
+ outputVersion() {
373
+ this.globalCommand.outputVersion();
374
+ }
375
+ setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
376
+ this.args = args;
377
+ this.options = options;
378
+ if (matchedCommand) this.matchedCommand = matchedCommand;
379
+ if (matchedCommandName) this.matchedCommandName = matchedCommandName;
380
+ return this;
381
+ }
382
+ unsetMatchedCommand() {
383
+ this.matchedCommand = void 0;
384
+ this.matchedCommandName = void 0;
385
+ }
386
+ parse(argv = processArgs, { run = true } = {}) {
387
+ this.rawArgs = argv;
388
+ if (!this.name) this.name = argv[1] ? getFileName(argv[1]) : "cli";
389
+ let shouldParse = true;
390
+ for (const command of this.commands){
391
+ const parsed = this.mri(argv.slice(2), command);
392
+ const commandName = parsed.args[0];
393
+ if (command.isMatched(commandName)) {
394
+ shouldParse = false;
395
+ const parsedInfo = __assign(__assign({}, parsed), {
396
+ args: parsed.args.slice(1)
397
+ });
398
+ this.setParsedInfo(parsedInfo, command, commandName);
399
+ this.emit(`command:${commandName}`, command);
400
+ }
401
+ }
402
+ if (shouldParse) {
403
+ for (const command of this.commands)if ("" === command.name) {
404
+ shouldParse = false;
405
+ const parsed = this.mri(argv.slice(2), command);
406
+ this.setParsedInfo(parsed, command);
407
+ this.emit("command:!", command);
408
+ }
409
+ }
410
+ if (shouldParse) {
411
+ const parsed = this.mri(argv.slice(2));
412
+ this.setParsedInfo(parsed);
413
+ }
414
+ if (this.options.help && this.showHelpOnExit) {
415
+ this.outputHelp();
416
+ run = false;
417
+ this.unsetMatchedCommand();
418
+ }
419
+ if (this.options.version && this.showVersionOnExit && null == this.matchedCommandName) {
420
+ this.outputVersion();
421
+ run = false;
422
+ this.unsetMatchedCommand();
423
+ }
424
+ const parsedArgv = {
425
+ args: this.args,
426
+ options: this.options
427
+ };
428
+ if (run) this.runMatchedCommand();
429
+ if (!this.matchedCommand && this.args[0]) this.emit("command:*");
430
+ return parsedArgv;
431
+ }
432
+ mri(argv, command) {
433
+ const cliOptions = [
434
+ ...this.globalCommand.options,
435
+ ...command ? command.options : []
436
+ ];
437
+ const mriOptions = getMriOptions(cliOptions);
438
+ let argsAfterDoubleDashes = [];
439
+ const doubleDashesIndex = argv.indexOf("--");
440
+ if (doubleDashesIndex > -1) {
441
+ argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
442
+ argv = argv.slice(0, doubleDashesIndex);
443
+ }
444
+ let parsed = mri2(argv, mriOptions);
445
+ parsed = Object.keys(parsed).reduce((res, name)=>__assign(__assign({}, res), {
446
+ [camelcaseOptionName(name)]: parsed[name]
447
+ }), {
448
+ _: []
449
+ });
450
+ const args = parsed._;
451
+ const options = {
452
+ "--": argsAfterDoubleDashes
453
+ };
454
+ const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
455
+ let transforms = Object.create(null);
456
+ for (const cliOption of cliOptions){
457
+ if (!ignoreDefault && void 0 !== cliOption.config.default) for (const name of cliOption.names)options[name] = cliOption.config.default;
458
+ if (Array.isArray(cliOption.config.type)) {
459
+ if (void 0 === transforms[cliOption.name]) {
460
+ transforms[cliOption.name] = Object.create(null);
461
+ transforms[cliOption.name]["shouldTransform"] = true;
462
+ transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
463
+ }
464
+ }
465
+ }
466
+ for (const key of Object.keys(parsed))if ("_" !== key) {
467
+ const keys = key.split(".");
468
+ setDotProp(options, keys, parsed[key]);
469
+ setByType(options, transforms);
470
+ }
471
+ return {
472
+ args,
473
+ options
474
+ };
475
+ }
476
+ runMatchedCommand() {
477
+ const { args, options, matchedCommand: command } = this;
478
+ if (!command || !command.commandAction) return;
479
+ command.checkUnknownOptions();
480
+ command.checkOptionValue();
481
+ command.checkRequiredArgs();
482
+ const actionArgs = [];
483
+ command.args.forEach((arg, index)=>{
484
+ if (arg.variadic) actionArgs.push(args.slice(index));
485
+ else actionArgs.push(args[index]);
486
+ });
487
+ actionArgs.push(options);
488
+ return command.commandAction.apply(this, actionArgs);
489
+ }
490
+ }
491
+ const cac = (name = "")=>new CAC(name);
492
+ const dist = cac;
493
+ function initNodeEnv() {
494
+ if (!process.env.NODE_ENV) process.env.NODE_ENV = 'test';
495
+ }
496
+ function prepareCli() {
497
+ initNodeEnv();
498
+ process.env.RSTEST = 'true';
499
+ const { npm_execpath } = process.env;
500
+ if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
501
+ }
502
+ function showRstest() {
503
+ src_logger.greet(" Rstest v0.6.7");
504
+ src_logger.log('');
505
+ }
506
+ const applyCommonOptions = (cli)=>{
507
+ cli.option('-c, --config <config>', 'Specify the configuration file, can be a relative or absolute path').option('--config-loader <loader>', 'Specify the loader to load the config file, can be `jiti` or `native`', {
508
+ default: 'jiti'
509
+ }).option('-r, --root <root>', 'Specify the project root directory, can be an absolute path or a path relative to cwd').option('--globals', 'Provide global APIs').option('--isolate', 'Run tests in an isolated environment').option('--include <include>', 'Match test files').option('--exclude <exclude>', 'Exclude files from test').option('-u, --update', 'Update snapshot files').option('--coverage', 'Enable code coverage collection').option('--project <name>', 'Run only projects that match the name, can be a full name or wildcards pattern').option('--passWithNoTests', 'Allows the test suite to pass when no files are found').option('--printConsoleTrace', 'Print console traces when calling any console method').option('--disableConsoleIntercept', 'Disable console intercept').option('--logHeapUsage', 'Log heap usage after each test').option('--slowTestThreshold <value>', 'The number of milliseconds after which a test or suite is considered slow').option('--reporter <reporter>', 'Specify the reporter to use').option('-t, --testNamePattern <value>', 'Run only tests with a name that matches the regex').option('--testEnvironment <name>', 'The environment that will be used for testing').option('--testTimeout <value>', 'Timeout of a test in milliseconds').option('--hookTimeout <value>', 'Timeout of hook in milliseconds').option('--hideSkippedTests', 'Hide skipped tests from the output').option('--retry <retry>', 'Number of times to retry a test if it fails').option('--bail [number]', 'Stop running tests after n failures. Set to 0 to run all tests regardless of failures').option('--maxConcurrency <value>', 'Maximum number of concurrent tests').option('--clearMocks', 'Automatically clear mock calls, instances, contexts and results before every test').option('--resetMocks', 'Automatically reset mock state before every test').option('--restoreMocks', 'Automatically restore mock state and implementation before every test').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all `process.env` values that were changed with `rstest.stubEnv` before every test');
510
+ };
511
+ const runRest = async ({ options, filters, command })=>{
512
+ let rstest;
513
+ try {
514
+ const { initCli } = await Promise.resolve().then(()=>({
515
+ initCli: init_initCli
516
+ }));
517
+ const { config, configFilePath, projects } = await initCli(options);
518
+ const { createRstest } = await Promise.resolve().then(()=>({
519
+ createRstest: core_createRstest
520
+ }));
521
+ rstest = createRstest({
522
+ config,
523
+ configFilePath,
524
+ projects
525
+ }, command, filters.map(normalize));
526
+ if ('watch' === command && configFilePath) {
527
+ const { watchFilesForRestart } = await import("./0~588.js").then((mod)=>({
528
+ watchFilesForRestart: mod.watchFilesForRestart
529
+ }));
530
+ watchFilesForRestart({
531
+ rstest,
532
+ options,
533
+ filters
534
+ });
535
+ }
536
+ await rstest.runTests();
537
+ } catch (err) {
538
+ for (const reporter of rstest?.context.reporters || [])reporter.onExit?.();
539
+ src_logger.error('Failed to run Rstest.');
540
+ src_logger.error(formatError(err));
541
+ process.exit(1);
542
+ }
543
+ };
544
+ function setupCommands() {
545
+ const cli = dist('rstest');
546
+ cli.help();
547
+ cli.version("0.6.7");
548
+ applyCommonOptions(cli);
549
+ cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
550
+ showRstest();
551
+ if (options.watch) await runRest({
552
+ options,
553
+ filters,
554
+ command: 'watch'
555
+ });
556
+ else await runRest({
557
+ options,
558
+ filters,
559
+ command: 'run'
560
+ });
561
+ });
562
+ cli.command('run [...filters]', 'run tests without watch mode').action(async (filters, options)=>{
563
+ showRstest();
564
+ await runRest({
565
+ options,
566
+ filters,
567
+ command: 'run'
568
+ });
569
+ });
570
+ cli.command('watch [...filters]', 'run tests in watch mode').action(async (filters, options)=>{
571
+ showRstest();
572
+ await runRest({
573
+ options,
574
+ filters,
575
+ command: 'watch'
576
+ });
577
+ });
578
+ cli.command('list [...filters]', 'lists all test files that Rstest will run').option('--filesOnly', 'only list the test files').option('--json [boolean/path]', 'print tests as JSON or write to a file').action(async (filters, options)=>{
579
+ try {
580
+ const { initCli } = await Promise.resolve().then(()=>({
581
+ initCli: init_initCli
582
+ }));
583
+ const { config, configFilePath, projects } = await initCli(options);
584
+ const { createRstest } = await Promise.resolve().then(()=>({
585
+ createRstest: core_createRstest
586
+ }));
587
+ const rstest = createRstest({
588
+ config,
589
+ configFilePath,
590
+ projects
591
+ }, 'list', filters.map(normalize));
592
+ await rstest.listTests({
593
+ filesOnly: options.filesOnly,
594
+ json: options.json
595
+ });
596
+ } catch (err) {
597
+ src_logger.error('Failed to run Rstest list.');
598
+ src_logger.error(formatError(err));
599
+ process.exit(1);
600
+ }
601
+ });
602
+ cli.parse();
603
+ }
604
+ const external_node_fs_ = __webpack_require__("node:fs");
605
+ const picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
606
+ var picocolors_default = /*#__PURE__*/ __webpack_require__.n(picocolors);
607
+ const findConfig = (basePath)=>DEFAULT_CONFIG_EXTENSIONS.map((ext)=>basePath + ext).find(external_node_fs_["default"].existsSync);
608
+ const resolveConfigPath = (root, customConfig)=>{
609
+ if (customConfig) {
610
+ const customConfigPath = isAbsolute(customConfig) ? customConfig : join(root, customConfig);
611
+ if (external_node_fs_["default"].existsSync(customConfigPath)) return customConfigPath;
612
+ throw `Cannot find config file: ${picocolors_default().dim(customConfigPath)}`;
613
+ }
614
+ const configFilePath = findConfig(join(root, DEFAULT_CONFIG_NAME));
615
+ if (configFilePath) return configFilePath;
616
+ return null;
617
+ };
618
+ async function config_loadConfig({ cwd = process.cwd(), path, envMode, configLoader }) {
619
+ const configFilePath = resolveConfigPath(cwd, path);
620
+ if (!configFilePath) {
621
+ src_logger.debug('no rstest config file found');
622
+ return {
623
+ content: {},
624
+ filePath: configFilePath
625
+ };
626
+ }
627
+ const { content } = await loadConfig({
628
+ cwd: dirname(configFilePath),
629
+ path: configFilePath,
630
+ envMode,
631
+ loader: configLoader
632
+ });
633
+ return {
634
+ content: content,
635
+ filePath: configFilePath
636
+ };
637
+ }
638
+ const mergeRstestConfig = (...configs)=>configs.reduce((result, config)=>{
639
+ const merged = mergeRsbuildConfig(result, {
640
+ ...config,
641
+ exclude: Array.isArray(config.exclude) ? {
642
+ patterns: config.exclude,
643
+ override: false
644
+ } : config.exclude
645
+ });
646
+ if (!Array.isArray(config.exclude) && config.exclude?.override) merged.exclude = {
647
+ patterns: config.exclude.patterns
648
+ };
649
+ merged.include = config.include ?? merged.include;
650
+ merged.reporters = config.reporters ?? merged.reporters;
651
+ if (merged.coverage) merged.coverage.reporters = config.coverage?.reporters ?? merged.coverage?.reporters;
652
+ return merged;
653
+ }, {});
654
+ const createDefaultConfig = ()=>({
655
+ root: process.cwd(),
656
+ name: 'rstest',
657
+ include: [
658
+ '**/*.{test,spec}.?(c|m)[jt]s?(x)'
659
+ ],
660
+ exclude: {
661
+ patterns: [
662
+ '**/node_modules/**',
663
+ '**/dist/**',
664
+ '**/.{idea,git,cache,output,temp}/**'
665
+ ],
666
+ override: false
667
+ },
668
+ setupFiles: [],
669
+ includeSource: [],
670
+ pool: {
671
+ type: 'forks'
672
+ },
673
+ isolate: true,
674
+ globals: false,
675
+ passWithNoTests: false,
676
+ update: false,
677
+ testTimeout: 5000,
678
+ hookTimeout: 10000,
679
+ testEnvironment: 'node',
680
+ retry: 0,
681
+ reporters: 'true' === process.env.GITHUB_ACTIONS ? [
682
+ 'default',
683
+ 'github-actions'
684
+ ] : [
685
+ 'default'
686
+ ],
687
+ clearMocks: false,
688
+ resetMocks: false,
689
+ restoreMocks: false,
690
+ slowTestThreshold: 300,
691
+ unstubGlobals: false,
692
+ unstubEnvs: false,
693
+ maxConcurrency: 5,
694
+ printConsoleTrace: false,
695
+ disableConsoleIntercept: false,
696
+ snapshotFormat: {},
697
+ env: {},
698
+ hideSkippedTests: false,
699
+ logHeapUsage: false,
700
+ bail: 0,
701
+ coverage: {
702
+ exclude: [
703
+ '**/node_modules/**',
704
+ '**/[.]*',
705
+ '**/dist/**',
706
+ '**/test/**',
707
+ '**/__tests__/**',
708
+ '**/__mocks__/**',
709
+ '**/*.d.ts',
710
+ '**/*.{test,spec}.[jt]s',
711
+ '**/*.{test,spec}.[cm][jt]s',
712
+ '**/*.{test,spec}.[jt]sx',
713
+ '**/*.{test,spec}.[cm][jt]sx'
714
+ ],
715
+ enabled: false,
716
+ provider: 'istanbul',
717
+ reporters: [
718
+ 'text',
719
+ 'html',
720
+ 'clover',
721
+ 'json'
722
+ ],
723
+ reportsDirectory: './coverage',
724
+ clean: true,
725
+ reportOnFailure: false
726
+ }
727
+ });
728
+ const withDefaultConfig = (config)=>{
729
+ const merged = mergeRstestConfig(createDefaultConfig(), config);
730
+ merged.setupFiles = castArray(merged.setupFiles);
731
+ merged.exclude.patterns.push(TEMP_RSTEST_OUTPUT_DIR_GLOB);
732
+ const reportsDirectory = formatRootStr(merged.coverage.reportsDirectory, merged.root);
733
+ merged.coverage.reportsDirectory = isAbsolute(reportsDirectory) ? reportsDirectory : pathe_M_eThtNZ_resolve(merged.root, reportsDirectory);
734
+ merged.pool = 'string' == typeof config.pool ? {
735
+ type: config.pool
736
+ } : merged.pool;
737
+ return {
738
+ ...merged,
739
+ include: merged.include.map((p)=>formatRootStr(p, merged.root)),
740
+ exclude: {
741
+ ...merged.exclude,
742
+ patterns: merged.exclude.patterns.map((p)=>formatRootStr(p, merged.root))
743
+ },
744
+ setupFiles: merged.setupFiles.map((p)=>formatRootStr(p, merged.root)),
745
+ includeSource: merged.includeSource.map((p)=>formatRootStr(p, merged.root))
746
+ };
747
+ };
748
+ async function resolveConfig(options) {
749
+ const { content: config, filePath: configFilePath } = await config_loadConfig({
750
+ cwd: options.root,
751
+ path: options.config,
752
+ configLoader: options.configLoader
753
+ });
754
+ const keys = [
755
+ 'root',
756
+ 'globals',
757
+ 'isolate',
758
+ 'passWithNoTests',
759
+ 'update',
760
+ 'testNamePattern',
761
+ 'testTimeout',
762
+ 'hookTimeout',
763
+ 'clearMocks',
764
+ 'resetMocks',
765
+ 'restoreMocks',
766
+ 'unstubEnvs',
767
+ 'unstubGlobals',
768
+ 'retry',
769
+ 'slowTestThreshold',
770
+ 'maxConcurrency',
771
+ 'printConsoleTrace',
772
+ 'disableConsoleIntercept',
773
+ 'testEnvironment',
774
+ 'hideSkippedTests',
775
+ 'logHeapUsage'
776
+ ];
777
+ for (const key of keys)if (void 0 !== options[key]) config[key] = options[key];
778
+ if (options.reporter) config.reporters = castArray(options.reporter);
779
+ if (void 0 !== options.bail && ('number' == typeof options.bail || 'boolean' == typeof options.bail)) config.bail = Number(options.bail);
780
+ if (void 0 !== options.coverage) {
781
+ config.coverage ??= {};
782
+ config.coverage.enabled = options.coverage;
783
+ }
784
+ if (options.exclude) config.exclude = castArray(options.exclude);
785
+ if (options.include) config.include = castArray(options.include);
786
+ return {
787
+ config,
788
+ configFilePath: configFilePath ?? void 0
789
+ };
790
+ }
791
+ async function resolveProjects({ config, root, options }) {
792
+ if (!config.projects) return [];
793
+ const getDefaultProjectName = (dir)=>{
794
+ const pkgJsonPath = pathe_M_eThtNZ_resolve(dir, 'package.json');
795
+ const name = (0, external_node_fs_.existsSync)(pkgJsonPath) ? JSON.parse((0, external_node_fs_.readFileSync)(pkgJsonPath, 'utf-8')).name : '';
796
+ if ('string' != typeof name || !name) return basename(dir);
797
+ return name;
798
+ };
799
+ const globProjects = async (patterns)=>{
800
+ const globOptions = {
801
+ absolute: true,
802
+ dot: true,
803
+ onlyFiles: false,
804
+ cwd: root,
805
+ expandDirectories: false,
806
+ ignore: [
807
+ '**/node_modules/**',
808
+ '**/.DS_Store'
809
+ ]
810
+ };
811
+ return glob(patterns, globOptions);
812
+ };
813
+ const { projectPaths, projectPatterns, projectConfigs } = (config.projects || []).reduce((total, p)=>{
814
+ if ('object' == typeof p) {
815
+ const projectRoot = p.root ? formatRootStr(p.root, root) : root;
816
+ total.projectConfigs.push({
817
+ config: {
818
+ root: projectRoot,
819
+ name: p.name ? p.name : getDefaultProjectName(projectRoot),
820
+ ...p
821
+ },
822
+ configFilePath: void 0
823
+ });
824
+ return total;
825
+ }
826
+ const projectStr = formatRootStr(p, root);
827
+ if (isDynamicPattern(projectStr)) total.projectPatterns.push(projectStr);
828
+ else {
829
+ const absolutePath = getAbsolutePath(root, projectStr);
830
+ if (!(0, external_node_fs_.existsSync)(absolutePath)) throw `Can't resolve project "${p}", please make sure "${p}" is a existing file or a directory.`;
831
+ total.projectPaths.push(absolutePath);
832
+ }
833
+ return total;
834
+ }, {
835
+ projectPaths: [],
836
+ projectPatterns: [],
837
+ projectConfigs: []
838
+ });
839
+ projectPaths.push(...await globProjects(projectPatterns));
840
+ const projects = await Promise.all(projectPaths.map(async (project)=>{
841
+ const isDirectory = (0, external_node_fs_.statSync)(project).isDirectory();
842
+ const root = isDirectory ? project : dirname(project);
843
+ const { config, configFilePath } = await resolveConfig({
844
+ ...options,
845
+ config: isDirectory ? void 0 : project,
846
+ root
847
+ });
848
+ config.name ??= getDefaultProjectName(root);
849
+ if (config.projects?.length && config.root !== root) src_logger.warn(`Projects cannot have nested projects, the "projects" field in project "${config.name}" will be ignored.`);
850
+ return {
851
+ config,
852
+ configFilePath
853
+ };
854
+ })).then((projects)=>filterProjects(projects.concat(projectConfigs), options));
855
+ if (!projects.length) {
856
+ let errorMsg = `No projects found, please make sure you have at least one valid project.
857
+ ${picocolors_default().gray('projects:')} ${JSON.stringify(config.projects, null, 2)}`;
858
+ if (options.project) errorMsg += `\n${picocolors_default().gray('projectName filter:')} ${JSON.stringify(options.project, null, 2)}`;
859
+ throw errorMsg;
860
+ }
861
+ const names = new Set();
862
+ projects.forEach((project)=>{
863
+ if (names.has(project.config.name)) {
864
+ const conflictProjects = projects.filter((p)=>p.config.name === project.config.name);
865
+ throw `Project name "${project.config.name}" is already used. Please ensure all projects have unique names.
866
+ Conflicting projects:
867
+ ${conflictProjects.map((p)=>`- ${p.configFilePath || p.config.root}`).join('\n')}
868
+ `;
869
+ }
870
+ names.add(project.config.name);
871
+ });
872
+ return projects;
873
+ }
874
+ async function init_initCli(options) {
875
+ const cwd = process.cwd();
876
+ const root = options.root ? getAbsolutePath(cwd, options.root) : cwd;
877
+ const { config, configFilePath } = await resolveConfig({
878
+ ...options,
879
+ root
880
+ });
881
+ const projects = await resolveProjects({
882
+ config,
883
+ root,
884
+ options
885
+ });
886
+ return {
887
+ config,
888
+ configFilePath,
889
+ projects
890
+ };
891
+ }
892
+ async function runCLI() {
893
+ prepareCli();
894
+ try {
895
+ setupCommands();
896
+ } catch (err) {
897
+ src_logger.error('Failed to start Rstest CLI.');
898
+ src_logger.error(err);
899
+ }
900
+ }
901
+ class SnapshotManager {
902
+ summary;
903
+ extension = ".snap";
904
+ constructor(options){
905
+ this.options = options;
906
+ this.clear();
907
+ }
908
+ clear() {
909
+ this.summary = emptySummary(this.options);
910
+ }
911
+ add(result) {
912
+ addSnapshotResult(this.summary, result);
913
+ }
914
+ resolvePath(testPath, context) {
915
+ const resolver = this.options.resolveSnapshotPath || (()=>join(join(dirname(testPath), "__snapshots__"), `${basename(testPath)}${this.extension}`));
916
+ const path = resolver(testPath, this.extension, context);
917
+ return path;
918
+ }
919
+ resolveRawPath(testPath, rawPath) {
920
+ return isAbsolute(rawPath) ? rawPath : pathe_M_eThtNZ_resolve(dirname(testPath), rawPath);
921
+ }
922
+ }
923
+ function emptySummary(options) {
924
+ const summary = {
925
+ added: 0,
926
+ failure: false,
927
+ filesAdded: 0,
928
+ filesRemoved: 0,
929
+ filesRemovedList: [],
930
+ filesUnmatched: 0,
931
+ filesUpdated: 0,
932
+ matched: 0,
933
+ total: 0,
934
+ unchecked: 0,
935
+ uncheckedKeysByFile: [],
936
+ unmatched: 0,
937
+ updated: 0,
938
+ didUpdate: "all" === options.updateSnapshot
939
+ };
940
+ return summary;
941
+ }
942
+ function addSnapshotResult(summary, result) {
943
+ if (result.added) summary.filesAdded++;
944
+ if (result.fileDeleted) summary.filesRemoved++;
945
+ if (result.unmatched) summary.filesUnmatched++;
946
+ if (result.updated) summary.filesUpdated++;
947
+ summary.added += result.added;
948
+ summary.matched += result.matched;
949
+ summary.unchecked += result.unchecked;
950
+ if (result.uncheckedKeys && result.uncheckedKeys.length > 0) summary.uncheckedKeysByFile.push({
951
+ filePath: result.filepath,
952
+ keys: result.uncheckedKeys
953
+ });
954
+ summary.unmatched += result.unmatched;
955
+ summary.updated += result.updated;
956
+ summary.total += result.added + result.matched + result.unmatched + result.updated;
957
+ }
958
+ const dist_r = Object.create(null), dist_i = (e)=>globalThis.process?.env || {
959
+ MODE: "production",
960
+ DEV: false,
961
+ PROD: true,
962
+ BASE_URL: "/",
963
+ ASSET_PREFIX: "auto"
964
+ }, dist_o = new Proxy(dist_r, {
965
+ get (e, s) {
966
+ return dist_i()[s] ?? dist_r[s];
967
+ },
968
+ has (e, s) {
969
+ const E = dist_i();
970
+ return s in E || s in dist_r;
971
+ },
972
+ set (e, s, E) {
973
+ const B = dist_i(!0);
974
+ return B[s] = E, !0;
975
+ },
976
+ deleteProperty (e, s) {
977
+ if (!s) return !1;
978
+ const E = dist_i(!0);
979
+ return delete E[s], !0;
980
+ },
981
+ ownKeys () {
982
+ const e = dist_i(!0);
983
+ return Object.keys(e);
984
+ }
985
+ }), dist_t = typeof process < "u" && process.env && process.env.NODE_ENV || "", f = [
986
+ [
987
+ "APPVEYOR"
988
+ ],
989
+ [
990
+ "AWS_AMPLIFY",
991
+ "AWS_APP_ID",
992
+ {
993
+ ci: !0
994
+ }
995
+ ],
996
+ [
997
+ "AZURE_PIPELINES",
998
+ "SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"
999
+ ],
1000
+ [
1001
+ "AZURE_STATIC",
1002
+ "INPUT_AZURE_STATIC_WEB_APPS_API_TOKEN"
1003
+ ],
1004
+ [
1005
+ "APPCIRCLE",
1006
+ "AC_APPCIRCLE"
1007
+ ],
1008
+ [
1009
+ "BAMBOO",
1010
+ "bamboo_planKey"
1011
+ ],
1012
+ [
1013
+ "BITBUCKET",
1014
+ "BITBUCKET_COMMIT"
1015
+ ],
1016
+ [
1017
+ "BITRISE",
1018
+ "BITRISE_IO"
1019
+ ],
1020
+ [
1021
+ "BUDDY",
1022
+ "BUDDY_WORKSPACE_ID"
1023
+ ],
1024
+ [
1025
+ "BUILDKITE"
1026
+ ],
1027
+ [
1028
+ "CIRCLE",
1029
+ "CIRCLECI"
1030
+ ],
1031
+ [
1032
+ "CIRRUS",
1033
+ "CIRRUS_CI"
1034
+ ],
1035
+ [
1036
+ "CLOUDFLARE_PAGES",
1037
+ "CF_PAGES",
1038
+ {
1039
+ ci: !0
1040
+ }
1041
+ ],
1042
+ [
1043
+ "CLOUDFLARE_WORKERS",
1044
+ "WORKERS_CI",
1045
+ {
1046
+ ci: !0
1047
+ }
1048
+ ],
1049
+ [
1050
+ "CODEBUILD",
1051
+ "CODEBUILD_BUILD_ARN"
1052
+ ],
1053
+ [
1054
+ "CODEFRESH",
1055
+ "CF_BUILD_ID"
1056
+ ],
1057
+ [
1058
+ "DRONE"
1059
+ ],
1060
+ [
1061
+ "DRONE",
1062
+ "DRONE_BUILD_EVENT"
1063
+ ],
1064
+ [
1065
+ "DSARI"
1066
+ ],
1067
+ [
1068
+ "GITHUB_ACTIONS"
1069
+ ],
1070
+ [
1071
+ "GITLAB",
1072
+ "GITLAB_CI"
1073
+ ],
1074
+ [
1075
+ "GITLAB",
1076
+ "CI_MERGE_REQUEST_ID"
1077
+ ],
1078
+ [
1079
+ "GOCD",
1080
+ "GO_PIPELINE_LABEL"
1081
+ ],
1082
+ [
1083
+ "LAYERCI"
1084
+ ],
1085
+ [
1086
+ "HUDSON",
1087
+ "HUDSON_URL"
1088
+ ],
1089
+ [
1090
+ "JENKINS",
1091
+ "JENKINS_URL"
1092
+ ],
1093
+ [
1094
+ "MAGNUM"
1095
+ ],
1096
+ [
1097
+ "NETLIFY"
1098
+ ],
1099
+ [
1100
+ "NETLIFY",
1101
+ "NETLIFY_LOCAL",
1102
+ {
1103
+ ci: !1
1104
+ }
1105
+ ],
1106
+ [
1107
+ "NEVERCODE"
1108
+ ],
1109
+ [
1110
+ "RENDER"
1111
+ ],
1112
+ [
1113
+ "SAIL",
1114
+ "SAILCI"
1115
+ ],
1116
+ [
1117
+ "SEMAPHORE"
1118
+ ],
1119
+ [
1120
+ "SCREWDRIVER"
1121
+ ],
1122
+ [
1123
+ "SHIPPABLE"
1124
+ ],
1125
+ [
1126
+ "SOLANO",
1127
+ "TDDIUM"
1128
+ ],
1129
+ [
1130
+ "STRIDER"
1131
+ ],
1132
+ [
1133
+ "TEAMCITY",
1134
+ "TEAMCITY_VERSION"
1135
+ ],
1136
+ [
1137
+ "TRAVIS"
1138
+ ],
1139
+ [
1140
+ "VERCEL",
1141
+ "NOW_BUILDER"
1142
+ ],
1143
+ [
1144
+ "VERCEL",
1145
+ "VERCEL",
1146
+ {
1147
+ ci: !1
1148
+ }
1149
+ ],
1150
+ [
1151
+ "VERCEL",
1152
+ "VERCEL_ENV",
1153
+ {
1154
+ ci: !1
1155
+ }
1156
+ ],
1157
+ [
1158
+ "APPCENTER",
1159
+ "APPCENTER_BUILD_ID"
1160
+ ],
1161
+ [
1162
+ "CODESANDBOX",
1163
+ "CODESANDBOX_SSE",
1164
+ {
1165
+ ci: !1
1166
+ }
1167
+ ],
1168
+ [
1169
+ "CODESANDBOX",
1170
+ "CODESANDBOX_HOST",
1171
+ {
1172
+ ci: !1
1173
+ }
1174
+ ],
1175
+ [
1176
+ "STACKBLITZ"
1177
+ ],
1178
+ [
1179
+ "STORMKIT"
1180
+ ],
1181
+ [
1182
+ "CLEAVR"
1183
+ ],
1184
+ [
1185
+ "ZEABUR"
1186
+ ],
1187
+ [
1188
+ "CODESPHERE",
1189
+ "CODESPHERE_APP_ID",
1190
+ {
1191
+ ci: !0
1192
+ }
1193
+ ],
1194
+ [
1195
+ "RAILWAY",
1196
+ "RAILWAY_PROJECT_ID"
1197
+ ],
1198
+ [
1199
+ "RAILWAY",
1200
+ "RAILWAY_SERVICE_ID"
1201
+ ],
1202
+ [
1203
+ "DENO-DEPLOY",
1204
+ "DENO_DEPLOYMENT_ID"
1205
+ ],
1206
+ [
1207
+ "FIREBASE_APP_HOSTING",
1208
+ "FIREBASE_APP_HOSTING",
1209
+ {
1210
+ ci: !0
1211
+ }
1212
+ ]
1213
+ ];
1214
+ function dist_b() {
1215
+ if (globalThis.process?.env) for (const e of f){
1216
+ const s = e[1] || e[0];
1217
+ if (globalThis.process?.env[s]) return {
1218
+ name: e[0].toLowerCase(),
1219
+ ...e[2]
1220
+ };
1221
+ }
1222
+ return globalThis.process?.env?.SHELL === "/bin/jsh" && globalThis.process?.versions?.webcontainer ? {
1223
+ name: "stackblitz",
1224
+ ci: !1
1225
+ } : {
1226
+ name: "",
1227
+ ci: !1
1228
+ };
1229
+ }
1230
+ const l = dist_b();
1231
+ l.name;
1232
+ function n(e) {
1233
+ return e ? "false" !== e : !1;
1234
+ }
1235
+ const I = globalThis.process?.platform || "", T = n(dist_o.CI) || !1 !== l.ci, R = n(globalThis.process?.stdout && globalThis.process?.stdout.isTTY), A = (n(dist_o.DEBUG), "test" === dist_t || n(dist_o.TEST), n(dist_o.MINIMAL), /^win/i.test(I)), C = (/^linux/i.test(I), /^darwin/i.test(I), !n(dist_o.NO_COLOR) && (n(dist_o.FORCE_COLOR) || (R || A) && dist_o.TERM), (globalThis.process?.versions?.node || "").replace(/^v/, "") || null), W = (Number(C?.split(".")[0]), globalThis.process || Object.create(null)), dist_ = {
1236
+ versions: {}
1237
+ }, O = (new Proxy(W, {
1238
+ get (e, s) {
1239
+ if ("env" === s) return dist_o;
1240
+ if (s in e) return e[s];
1241
+ if (s in dist_) return dist_[s];
1242
+ }
1243
+ }), globalThis.process?.release?.name === "node"), c = !!globalThis.Bun || !!globalThis.process?.versions?.bun, D = !!globalThis.Deno, L = !!globalThis.fastly, S = !!globalThis.Netlify, u = !!globalThis.EdgeRuntime, N = globalThis.navigator?.userAgent === "Cloudflare-Workers", F = [
1244
+ [
1245
+ S,
1246
+ "netlify"
1247
+ ],
1248
+ [
1249
+ u,
1250
+ "edge-light"
1251
+ ],
1252
+ [
1253
+ N,
1254
+ "workerd"
1255
+ ],
1256
+ [
1257
+ L,
1258
+ "fastly"
1259
+ ],
1260
+ [
1261
+ D,
1262
+ "deno"
1263
+ ],
1264
+ [
1265
+ c,
1266
+ "bun"
1267
+ ],
1268
+ [
1269
+ O,
1270
+ "node"
1271
+ ]
1272
+ ];
1273
+ function G() {
1274
+ const e = F.find((s)=>s[0]);
1275
+ if (e) return {
1276
+ name: e[1]
1277
+ };
1278
+ }
1279
+ const P = G();
1280
+ P?.name;
1281
+ var UNKNOWN_FUNCTION = '<unknown>';
1282
+ function stack_trace_parser_esm_parse(stackString) {
1283
+ var lines = stackString.split('\n');
1284
+ return lines.reduce(function(stack, line) {
1285
+ var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
1286
+ if (parseResult) stack.push(parseResult);
1287
+ return stack;
1288
+ }, []);
1289
+ }
1290
+ var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
1291
+ var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
1292
+ function parseChrome(line) {
1293
+ var parts = chromeRe.exec(line);
1294
+ if (!parts) return null;
1295
+ var isNative = parts[2] && 0 === parts[2].indexOf('native');
1296
+ var isEval = parts[2] && 0 === parts[2].indexOf('eval');
1297
+ var submatch = chromeEvalRe.exec(parts[2]);
1298
+ if (isEval && null != submatch) {
1299
+ parts[2] = submatch[1];
1300
+ parts[3] = submatch[2];
1301
+ parts[4] = submatch[3];
1302
+ }
1303
+ return {
1304
+ file: isNative ? null : parts[2],
1305
+ methodName: parts[1] || UNKNOWN_FUNCTION,
1306
+ arguments: isNative ? [
1307
+ parts[2]
1308
+ ] : [],
1309
+ lineNumber: parts[3] ? +parts[3] : null,
1310
+ column: parts[4] ? +parts[4] : null
1311
+ };
1312
+ }
1313
+ var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1314
+ function parseWinjs(line) {
1315
+ var parts = winjsRe.exec(line);
1316
+ if (!parts) return null;
1317
+ return {
1318
+ file: parts[2],
1319
+ methodName: parts[1] || UNKNOWN_FUNCTION,
1320
+ arguments: [],
1321
+ lineNumber: +parts[3],
1322
+ column: parts[4] ? +parts[4] : null
1323
+ };
1324
+ }
1325
+ var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
1326
+ var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
1327
+ function parseGecko(line) {
1328
+ var parts = geckoRe.exec(line);
1329
+ if (!parts) return null;
1330
+ var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
1331
+ var submatch = geckoEvalRe.exec(parts[3]);
1332
+ if (isEval && null != submatch) {
1333
+ parts[3] = submatch[1];
1334
+ parts[4] = submatch[2];
1335
+ parts[5] = null;
1336
+ }
1337
+ return {
1338
+ file: parts[3],
1339
+ methodName: parts[1] || UNKNOWN_FUNCTION,
1340
+ arguments: parts[2] ? parts[2].split(',') : [],
1341
+ lineNumber: parts[4] ? +parts[4] : null,
1342
+ column: parts[5] ? +parts[5] : null
1343
+ };
1344
+ }
1345
+ var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
1346
+ function parseJSC(line) {
1347
+ var parts = javaScriptCoreRe.exec(line);
1348
+ if (!parts) return null;
1349
+ return {
1350
+ file: parts[3],
1351
+ methodName: parts[1] || UNKNOWN_FUNCTION,
1352
+ arguments: [],
1353
+ lineNumber: +parts[4],
1354
+ column: parts[5] ? +parts[5] : null
1355
+ };
1356
+ }
1357
+ var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1358
+ function parseNode(line) {
1359
+ var parts = nodeRe.exec(line);
1360
+ if (!parts) return null;
1361
+ return {
1362
+ file: parts[2],
1363
+ methodName: parts[1] || UNKNOWN_FUNCTION,
1364
+ arguments: [],
1365
+ lineNumber: +parts[3],
1366
+ column: parts[4] ? +parts[4] : null
1367
+ };
1368
+ }
1369
+ const getSummaryStatusString = (tasks, name = 'tests', showTotal = true)=>{
1370
+ if (0 === tasks.length) return picocolors_default().dim(`no ${name}`);
1371
+ const passed = tasks.filter((result)=>'pass' === result.status);
1372
+ const failed = tasks.filter((result)=>'fail' === result.status);
1373
+ const skipped = tasks.filter((result)=>'skip' === result.status);
1374
+ const todo = tasks.filter((result)=>'todo' === result.status);
1375
+ const status = [
1376
+ failed.length ? picocolors_default().bold(picocolors_default().red(`${failed.length} failed`)) : null,
1377
+ passed.length ? picocolors_default().bold(picocolors_default().green(`${passed.length} passed`)) : null,
1378
+ skipped.length ? picocolors_default().yellow(`${skipped.length} skipped`) : null,
1379
+ todo.length ? picocolors_default().gray(`${todo.length} todo`) : null
1380
+ ].filter(Boolean);
1381
+ return status.join(picocolors_default().dim(' | ')) + (showTotal && status.length > 1 ? picocolors_default().gray(` (${tasks.length})`) : '');
1382
+ };
1383
+ const printSnapshotSummaryLog = (snapshots, rootDir)=>{
1384
+ const summary = [];
1385
+ if (snapshots.added) summary.push(picocolors_default().bold(picocolors_default().green(`${snapshots.added} written`)));
1386
+ if (snapshots.unmatched) summary.push(picocolors_default().bold(picocolors_default().red(`${snapshots.unmatched} failed`)));
1387
+ if (snapshots.updated) summary.push(picocolors_default().bold(picocolors_default().green(`${snapshots.updated} updated `)));
1388
+ if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(picocolors_default().bold(picocolors_default().green(`${snapshots.filesRemoved} files removed `)));
1389
+ else summary.push(picocolors_default().bold(picocolors_default().yellow(`${snapshots.filesRemoved} files obsolete `)));
1390
+ if (snapshots.filesRemovedList?.length) {
1391
+ const [head, ...tail] = snapshots.filesRemovedList;
1392
+ summary.push(`${picocolors_default().gray("➜")} ${formatTestPath(rootDir, head)}`);
1393
+ for (const key of tail)summary.push(` ${formatTestPath(rootDir, key)}`);
1394
+ }
1395
+ if (snapshots.unchecked) {
1396
+ if (snapshots.didUpdate) summary.push(picocolors_default().bold(picocolors_default().green(`${snapshots.unchecked} removed`)));
1397
+ else summary.push(picocolors_default().bold(picocolors_default().yellow(`${snapshots.unchecked} obsolete`)));
1398
+ for (const uncheckedFile of snapshots.uncheckedKeysByFile){
1399
+ summary.push(`${picocolors_default().gray("➜")} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
1400
+ for (const key of uncheckedFile.keys)summary.push(` ${key}`);
1401
+ }
1402
+ }
1403
+ for (const [index, snapshot] of summary.entries()){
1404
+ const title = 0 === index ? 'Snapshots' : '';
1405
+ src_logger.log(`${picocolors_default().gray(title.padStart(12))} ${snapshot}`);
1406
+ }
1407
+ };
1408
+ const TestFileSummaryLabel = picocolors_default().gray('Test Files'.padStart(11));
1409
+ const TestSummaryLabel = picocolors_default().gray('Tests'.padStart(11));
1410
+ const DurationLabel = picocolors_default().gray('Duration'.padStart(11));
1411
+ const printSummaryLog = ({ results, testResults, snapshotSummary, duration, rootPath })=>{
1412
+ src_logger.log('');
1413
+ printSnapshotSummaryLog(snapshotSummary, rootPath);
1414
+ src_logger.log(`${TestFileSummaryLabel} ${getSummaryStatusString(results)}`);
1415
+ src_logger.log(`${TestSummaryLabel} ${getSummaryStatusString(testResults)}`);
1416
+ src_logger.log(`${DurationLabel} ${prettyTime(duration.totalTime)} ${picocolors_default().gray(`(build ${prettyTime(duration.buildTime)}, tests ${prettyTime(duration.testTime)})`)}`);
1417
+ src_logger.log('');
1418
+ };
1419
+ const printSummaryErrorLogs = async ({ testResults, results, rootPath, getSourcemap, filterRerunTestPaths })=>{
1420
+ const failedTests = [
1421
+ ...results.filter((i)=>'fail' === i.status && i.errors?.length && (filterRerunTestPaths ? filterRerunTestPaths.includes(i.testPath) : true)),
1422
+ ...testResults.filter((i)=>'fail' === i.status && (filterRerunTestPaths ? filterRerunTestPaths.includes(i.testPath) : true))
1423
+ ];
1424
+ if (0 === failedTests.length) return;
1425
+ src_logger.log('');
1426
+ src_logger.log(picocolors_default().bold('Summary of all failing tests:'));
1427
+ src_logger.log('');
1428
+ for (const test of failedTests){
1429
+ const relativePath = posix.relative(rootPath, test.testPath);
1430
+ const nameStr = getTaskNameWithPrefix(test);
1431
+ src_logger.log(`${picocolors_default().bgRed(' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${picocolors_default().dim(">")} ${nameStr}` : ''}`);
1432
+ if (test.errors) {
1433
+ const { printError } = await Promise.resolve().then(()=>({
1434
+ printError: error_printError
1435
+ }));
1436
+ for (const error of test.errors)await printError(error, getSourcemap, rootPath);
1437
+ }
1438
+ }
1439
+ };
1440
+ const external_node_util_ = __webpack_require__("node:util");
1441
+ const DEFAULT_RENDER_INTERVAL_MS = 1000;
1442
+ const ESC = '\x1B[';
1443
+ const CLEAR_LINE = `${ESC}K`;
1444
+ const MOVE_CURSOR_ONE_ROW_UP = `${ESC}1A`;
1445
+ const SYNC_START = `${ESC}?2026h`;
1446
+ const SYNC_END = `${ESC}?2026l`;
1447
+ class WindowRenderer {
1448
+ options;
1449
+ streams;
1450
+ buffer = [];
1451
+ renderInterval = void 0;
1452
+ renderScheduled = false;
1453
+ windowHeight = 0;
1454
+ finished = false;
1455
+ cleanups = [];
1456
+ constructor(options){
1457
+ this.options = {
1458
+ interval: DEFAULT_RENDER_INTERVAL_MS,
1459
+ ...options
1460
+ };
1461
+ this.streams = {
1462
+ output: options.logger.outputStream.write.bind(options.logger.outputStream),
1463
+ error: options.logger.errorStream.write.bind(options.logger.errorStream)
1464
+ };
1465
+ this.cleanups.push(this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'));
1466
+ this.start();
1467
+ }
1468
+ start() {
1469
+ this.finished = false;
1470
+ this.renderInterval = setInterval(()=>this.schedule(), this.options.interval).unref();
1471
+ }
1472
+ stop() {
1473
+ this.cleanups.splice(0).map((fn)=>fn());
1474
+ clearInterval(this.renderInterval);
1475
+ }
1476
+ finish() {
1477
+ this.finished = true;
1478
+ this.flushBuffer();
1479
+ clearInterval(this.renderInterval);
1480
+ }
1481
+ schedule() {
1482
+ if (!this.renderScheduled) {
1483
+ this.renderScheduled = true;
1484
+ this.flushBuffer();
1485
+ setTimeout(()=>{
1486
+ this.renderScheduled = false;
1487
+ }, 100).unref();
1488
+ }
1489
+ }
1490
+ flushBuffer() {
1491
+ if (0 === this.buffer.length) return this.render();
1492
+ let current;
1493
+ for (const next of this.buffer.splice(0)){
1494
+ if (!current) {
1495
+ current = next;
1496
+ continue;
1497
+ }
1498
+ if (current.type !== next.type) {
1499
+ this.render(current.message, current.type);
1500
+ current = next;
1501
+ continue;
1502
+ }
1503
+ current.message += next.message;
1504
+ }
1505
+ if (current) this.render(current?.message, current?.type);
1506
+ }
1507
+ render(message, type = 'output') {
1508
+ if (this.finished) {
1509
+ this.clearWindow();
1510
+ return this.write(message || '', type);
1511
+ }
1512
+ const windowContent = this.options.getWindow();
1513
+ const rowCount = getRenderedRowCount(windowContent, this.options.logger.getColumns());
1514
+ let padding = this.windowHeight - rowCount;
1515
+ if (padding > 0 && message) padding -= getRenderedRowCount([
1516
+ message
1517
+ ], this.options.logger.getColumns());
1518
+ this.write(SYNC_START);
1519
+ this.clearWindow();
1520
+ if (message) this.write(message, type);
1521
+ if (padding > 0) this.write('\n'.repeat(padding));
1522
+ this.write(windowContent.join('\n'));
1523
+ this.write(SYNC_END);
1524
+ this.windowHeight = rowCount + Math.max(0, padding);
1525
+ }
1526
+ clearWindow() {
1527
+ if (0 === this.windowHeight) return;
1528
+ this.write(CLEAR_LINE);
1529
+ for(let i = 1; i < this.windowHeight; i++)this.write(`${MOVE_CURSOR_ONE_ROW_UP}${CLEAR_LINE}`);
1530
+ this.windowHeight = 0;
1531
+ }
1532
+ interceptStream(stream, type) {
1533
+ const original = stream.write.bind(stream);
1534
+ stream.write = (chunk, _, callback)=>{
1535
+ if (chunk) if (this.finished) this.write(chunk.toString(), type);
1536
+ else this.buffer.push({
1537
+ type,
1538
+ message: chunk.toString()
1539
+ });
1540
+ callback?.();
1541
+ };
1542
+ return function restore() {
1543
+ stream.write = original;
1544
+ };
1545
+ }
1546
+ write(message, type = 'output') {
1547
+ this.streams[type](message);
1548
+ }
1549
+ }
1550
+ function getRenderedRowCount(rows, columns) {
1551
+ let count = 0;
1552
+ for (const row of rows){
1553
+ const text = (0, external_node_util_.stripVTControlCharacters)(row);
1554
+ count += Math.max(1, Math.ceil(text.length / columns));
1555
+ }
1556
+ return count;
1557
+ }
1558
+ class StatusRenderer {
1559
+ rootPath;
1560
+ renderer;
1561
+ runningModules = new Map();
1562
+ testModules = [];
1563
+ startTime = void 0;
1564
+ constructor(rootPath){
1565
+ this.rootPath = rootPath;
1566
+ this.renderer = new WindowRenderer({
1567
+ getWindow: ()=>this.getContent(),
1568
+ logger: {
1569
+ outputStream: process.stdout,
1570
+ errorStream: process.stderr,
1571
+ getColumns: ()=>'columns' in process.stdout ? process.stdout.columns : 80
1572
+ }
1573
+ });
1574
+ }
1575
+ getContent() {
1576
+ this.startTime ??= Date.now();
1577
+ const now = Date.now();
1578
+ const summary = [];
1579
+ const shouldDisplayRunningTests = (runningTests)=>runningTests[0]?.startTime && now - runningTests[0].startTime > 2000;
1580
+ for (const [module, { runningTests }] of this.runningModules.entries()){
1581
+ const relativePath = pathe_M_eThtNZ_relative(this.rootPath, module);
1582
+ summary.push(`${picocolors_default().bgYellow(picocolors_default().bold(' RUNS '))} ${prettyTestPath(relativePath)}`);
1583
+ if (runningTests.length && shouldDisplayRunningTests(runningTests)) {
1584
+ let caseLog = ` ${picocolors_default().gray("➜")} ${getTaskNameWithPrefix(runningTests[0])} ${picocolors_default().magenta(prettyTime(now - runningTests[0].startTime))}`;
1585
+ if (runningTests.length > 1) caseLog += picocolors_default().gray(` and ${runningTests.length - 1} more cases`);
1586
+ summary.push(caseLog);
1587
+ }
1588
+ }
1589
+ summary.push('');
1590
+ if (0 === this.testModules.length) summary.push(`${TestFileSummaryLabel} ${this.runningModules.size} total`);
1591
+ else summary.push(`${TestFileSummaryLabel} ${getSummaryStatusString(this.testModules, '', false)} ${picocolors_default().dim('|')} ${this.runningModules.size + this.testModules.length} total`);
1592
+ const testResults = Array.from(this.runningModules.values()).flatMap(({ results })=>results).concat(this.testModules.flatMap((mod)=>mod.results));
1593
+ if (testResults.length) summary.push(`${TestSummaryLabel} ${getSummaryStatusString(testResults, '', false)}`);
1594
+ summary.push(`${DurationLabel} ${prettyTime(Date.now() - this.startTime)}`);
1595
+ summary.push('');
1596
+ return summary;
1597
+ }
1598
+ onTestFileStart(testPath) {
1599
+ this.runningModules.set(testPath, {
1600
+ runningTests: [],
1601
+ results: []
1602
+ });
1603
+ this.renderer?.schedule();
1604
+ }
1605
+ onTestCaseResult(result) {
1606
+ const currentModule = this.runningModules.get(result.testPath);
1607
+ if (currentModule) {
1608
+ const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== result.testId);
1609
+ this.runningModules.set(result.testPath, {
1610
+ runningTests: filteredRunningTests,
1611
+ results: [
1612
+ ...currentModule.results,
1613
+ result
1614
+ ]
1615
+ });
1616
+ } else this.runningModules.set(result.testPath, {
1617
+ runningTests: [],
1618
+ results: [
1619
+ result
1620
+ ]
1621
+ });
1622
+ this.renderer?.schedule();
1623
+ }
1624
+ onTestCaseStart(test) {
1625
+ const currentModule = this.runningModules.get(test.testPath);
1626
+ if (currentModule) {
1627
+ const filteredRunningTests = currentModule.runningTests.filter((t)=>t.testId !== test.testId);
1628
+ this.runningModules.set(test.testPath, {
1629
+ runningTests: [
1630
+ ...filteredRunningTests,
1631
+ test
1632
+ ],
1633
+ results: currentModule.results
1634
+ });
1635
+ } else this.runningModules.set(test.testPath, {
1636
+ runningTests: [
1637
+ test
1638
+ ],
1639
+ results: []
1640
+ });
1641
+ }
1642
+ onTestFileResult(test) {
1643
+ this.runningModules.delete(test.testPath);
1644
+ this.testModules.push(test);
1645
+ this.renderer?.schedule();
1646
+ }
1647
+ clear() {
1648
+ this.testModules.length = 0;
1649
+ this.runningModules.clear();
1650
+ this.startTime = void 0;
1651
+ this.renderer?.finish();
1652
+ }
1653
+ }
1654
+ const statusStr = {
1655
+ fail: '✗',
1656
+ pass: '✓',
1657
+ todo: '-',
1658
+ skip: '-'
1659
+ };
1660
+ const statusColorfulStr = {
1661
+ fail: picocolors_default().red(statusStr.fail),
1662
+ pass: picocolors_default().green(statusStr.pass),
1663
+ todo: picocolors_default().gray(statusStr.todo),
1664
+ skip: picocolors_default().gray(statusStr.skip)
1665
+ };
1666
+ const logCase = (result, options)=>{
1667
+ const isSlowCase = (result.duration || 0) > options.slowTestThreshold;
1668
+ if (options.hideSkippedTests && 'skip' === result.status) return;
1669
+ const icon = isSlowCase && 'pass' === result.status ? picocolors_default().yellow(statusStr[result.status]) : statusColorfulStr[result.status];
1670
+ const nameStr = getTaskNameWithPrefix(result);
1671
+ const duration = void 0 !== result.duration ? ` (${prettyTime(result.duration)})` : '';
1672
+ const retry = result.retryCount ? picocolors_default().yellow(` (retry x${result.retryCount})`) : '';
1673
+ const heap = result.heap ? ` ${picocolors_default().magenta(formatHeapUsed(result.heap))}` : '';
1674
+ src_logger.log(` ${icon} ${nameStr}${picocolors_default().gray(duration)}${retry}${heap}`);
1675
+ if (result.errors) for (const error of result.errors)console.error(picocolors_default().red(` ${error.message}`));
1676
+ };
1677
+ const formatHeapUsed = (heap)=>`${Math.floor(heap / 1024 / 1024)} MB heap used`;
1678
+ const logFileTitle = (test, relativePath, alwaysShowTime = false)=>{
1679
+ let title = ` ${picocolors_default().bold(statusColorfulStr[test.status])} ${prettyTestPath(relativePath)}`;
1680
+ const formatDuration = (duration)=>picocolors_default().green(prettyTime(duration));
1681
+ title += ` ${picocolors_default().gray(`(${test.results.length})`)}`;
1682
+ if (alwaysShowTime) title += ` ${formatDuration(test.duration)}`;
1683
+ if (test.heap) title += ` ${picocolors_default().magenta(formatHeapUsed(test.heap))}`;
1684
+ src_logger.log(title);
1685
+ };
1686
+ class DefaultReporter {
1687
+ rootPath;
1688
+ config;
1689
+ options = {};
1690
+ statusRenderer;
1691
+ constructor({ rootPath, options, config }){
1692
+ this.rootPath = rootPath;
1693
+ this.config = config;
1694
+ this.options = options;
1695
+ if (isTTY()) this.statusRenderer = new StatusRenderer(rootPath);
1696
+ }
1697
+ onTestFileStart(test) {
1698
+ this.statusRenderer?.onTestFileStart(test.testPath);
1699
+ }
1700
+ onTestFileResult(test) {
1701
+ this.statusRenderer?.onTestFileResult(test);
1702
+ const relativePath = pathe_M_eThtNZ_relative(this.rootPath, test.testPath);
1703
+ const { slowTestThreshold } = this.config;
1704
+ logFileTitle(test, relativePath);
1705
+ for (const result of test.results){
1706
+ const isDisplayed = 'fail' === result.status || (result.duration ?? 0) > slowTestThreshold || (result.retryCount ?? 0) > 0;
1707
+ isDisplayed && logCase(result, {
1708
+ slowTestThreshold,
1709
+ hideSkippedTests: this.config.hideSkippedTests
1710
+ });
1711
+ }
1712
+ }
1713
+ onTestCaseResult(result) {
1714
+ this.statusRenderer?.onTestCaseResult(result);
1715
+ }
1716
+ onTestCaseStart(test) {
1717
+ this.statusRenderer?.onTestCaseStart(test);
1718
+ }
1719
+ onUserConsoleLog(log) {
1720
+ const shouldLog = this.config.onConsoleLog?.(log.content) ?? true;
1721
+ if (!shouldLog) return;
1722
+ const titles = [];
1723
+ const testPath = pathe_M_eThtNZ_relative(this.rootPath, log.testPath);
1724
+ if (log.trace) {
1725
+ const [frame] = stack_trace_parser_esm_parse(log.trace);
1726
+ const filePath = pathe_M_eThtNZ_relative(this.rootPath, frame.file || '');
1727
+ if (filePath !== testPath) titles.push(testPath);
1728
+ titles.push(`${filePath}:${frame.lineNumber}:${frame.column}`);
1729
+ } else titles.push(testPath);
1730
+ src_logger.log('');
1731
+ src_logger.log(`${log.name}${picocolors_default().gray(picocolors_default().dim(` | ${titles.join(picocolors_default().gray(picocolors_default().dim(' | ')))}`))}`);
1732
+ src_logger.log(log.content);
1733
+ src_logger.log('');
1734
+ }
1735
+ async onExit() {
1736
+ this.statusRenderer?.clear();
1737
+ }
1738
+ async onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary, filterRerunTestPaths }) {
1739
+ this.statusRenderer?.clear();
1740
+ if (false === this.options.summary) return;
1741
+ await printSummaryErrorLogs({
1742
+ testResults,
1743
+ results,
1744
+ rootPath: this.rootPath,
1745
+ getSourcemap,
1746
+ filterRerunTestPaths
1747
+ });
1748
+ printSummaryLog({
1749
+ results,
1750
+ testResults,
1751
+ duration,
1752
+ rootPath: this.rootPath,
1753
+ snapshotSummary
1754
+ });
1755
+ }
1756
+ }
1757
+ class GithubActionsReporter {
1758
+ onWritePath;
1759
+ rootPath;
1760
+ constructor({ options, rootPath }){
1761
+ this.onWritePath = options.onWritePath;
1762
+ this.rootPath = rootPath;
1763
+ }
1764
+ log(message) {
1765
+ console.log(`${message}\n`);
1766
+ }
1767
+ async onTestRunEnd({ results, testResults, getSourcemap }) {
1768
+ const failedTests = [
1769
+ ...results.filter((i)=>'fail' === i.status && i.errors?.length),
1770
+ ...testResults.filter((i)=>'fail' === i.status)
1771
+ ];
1772
+ if (0 === failedTests.length) return;
1773
+ const { parseErrorStacktrace } = await Promise.resolve().then(()=>({
1774
+ parseErrorStacktrace: error_parseErrorStacktrace
1775
+ }));
1776
+ const logs = [];
1777
+ for (const test of failedTests){
1778
+ const { testPath } = test;
1779
+ const nameStr = getTaskNameWithPrefix(test);
1780
+ const shortPath = pathe_M_eThtNZ_relative(this.rootPath, testPath);
1781
+ const title = `${shortPath} > ${nameStr}`;
1782
+ for (const error of test.errors || []){
1783
+ let file = testPath;
1784
+ let line = 1;
1785
+ let column = 1;
1786
+ const message = `${error.message}${error.diff ? `\n${error.diff}` : ''}`;
1787
+ const type = 'error';
1788
+ if (error.stack) {
1789
+ const stackFrames = await parseErrorStacktrace({
1790
+ stack: error.stack,
1791
+ fullStack: error.fullStack,
1792
+ getSourcemap
1793
+ });
1794
+ if (stackFrames[0]) {
1795
+ file = stackFrames[0].file || test.testPath;
1796
+ line = stackFrames[0].lineNumber || 1;
1797
+ column = stackFrames[0].column || 1;
1798
+ }
1799
+ }
1800
+ logs.push(`::${type} file=${this.onWritePath?.(file) || file},line=${line},col=${column},title=${escapeData(title)}::${escapeData(message)}`);
1801
+ }
1802
+ }
1803
+ this.log('::group::Error for GitHub Actions');
1804
+ for (const log of logs)this.log(log);
1805
+ this.log('::endgroup::');
1806
+ }
1807
+ }
1808
+ function escapeData(s) {
1809
+ return s.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/:/g, '%3A').replace(/,/g, '%2C');
1810
+ }
1811
+ function ansiRegex({ onlyFirst = false } = {}) {
1812
+ const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
1813
+ const pattern = [
1814
+ `[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
1815
+ '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))'
1816
+ ].join('|');
1817
+ return new RegExp(pattern, onlyFirst ? void 0 : 'g');
1818
+ }
1819
+ const regex = ansiRegex();
1820
+ function stripAnsi(string) {
1821
+ if ('string' != typeof string) throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
1822
+ return string.replace(regex, '');
1823
+ }
1824
+ const schemeRegex = /^[\w+.-]+:\/\//;
1825
+ const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
1826
+ const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
1827
+ function isAbsoluteUrl(input) {
1828
+ return schemeRegex.test(input);
1829
+ }
1830
+ function isSchemeRelativeUrl(input) {
1831
+ return input.startsWith('//');
1832
+ }
1833
+ function isAbsolutePath(input) {
1834
+ return input.startsWith('/');
1835
+ }
1836
+ function isFileUrl(input) {
1837
+ return input.startsWith('file:');
1838
+ }
1839
+ function isRelative(input) {
1840
+ return /^[.?#]/.test(input);
1841
+ }
1842
+ function parseAbsoluteUrl(input) {
1843
+ const match = urlRegex.exec(input);
1844
+ return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
1845
+ }
1846
+ function parseFileUrl(input) {
1847
+ const match = fileRegex.exec(input);
1848
+ const path = match[2];
1849
+ return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
1850
+ }
1851
+ function makeUrl(scheme, user, host, port, path, query, hash) {
1852
+ return {
1853
+ scheme,
1854
+ user,
1855
+ host,
1856
+ port,
1857
+ path,
1858
+ query,
1859
+ hash,
1860
+ type: 7
1861
+ };
1862
+ }
1863
+ function parseUrl(input) {
1864
+ if (isSchemeRelativeUrl(input)) {
1865
+ const url = parseAbsoluteUrl('http:' + input);
1866
+ url.scheme = '';
1867
+ url.type = 6;
1868
+ return url;
1869
+ }
1870
+ if (isAbsolutePath(input)) {
1871
+ const url = parseAbsoluteUrl('http://foo.com' + input);
1872
+ url.scheme = '';
1873
+ url.host = '';
1874
+ url.type = 5;
1875
+ return url;
1876
+ }
1877
+ if (isFileUrl(input)) return parseFileUrl(input);
1878
+ if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);
1879
+ const url = parseAbsoluteUrl('http://foo.com/' + input);
1880
+ url.scheme = '';
1881
+ url.host = '';
1882
+ url.type = input ? input.startsWith('?') ? 3 : input.startsWith('#') ? 2 : 4 : 1;
1883
+ return url;
1884
+ }
1885
+ function stripPathFilename(path) {
1886
+ if (path.endsWith('/..')) return path;
1887
+ const index = path.lastIndexOf('/');
1888
+ return path.slice(0, index + 1);
1889
+ }
1890
+ function mergePaths(url, base) {
1891
+ normalizePath(base, base.type);
1892
+ if ('/' === url.path) url.path = base.path;
1893
+ else url.path = stripPathFilename(base.path) + url.path;
1894
+ }
1895
+ function normalizePath(url, type) {
1896
+ const rel = type <= 4;
1897
+ const pieces = url.path.split('/');
1898
+ let pointer = 1;
1899
+ let positive = 0;
1900
+ let addTrailingSlash = false;
1901
+ for(let i = 1; i < pieces.length; i++){
1902
+ const piece = pieces[i];
1903
+ if (!piece) {
1904
+ addTrailingSlash = true;
1905
+ continue;
1906
+ }
1907
+ addTrailingSlash = false;
1908
+ if ('.' !== piece) {
1909
+ if ('..' === piece) {
1910
+ if (positive) {
1911
+ addTrailingSlash = true;
1912
+ positive--;
1913
+ pointer--;
1914
+ } else if (rel) pieces[pointer++] = piece;
1915
+ continue;
1916
+ }
1917
+ pieces[pointer++] = piece;
1918
+ positive++;
1919
+ }
1920
+ }
1921
+ let path = '';
1922
+ for(let i = 1; i < pointer; i++)path += '/' + pieces[i];
1923
+ if (!path || addTrailingSlash && !path.endsWith('/..')) path += '/';
1924
+ url.path = path;
1925
+ }
1926
+ function resolve_uri_resolve(input, base) {
1927
+ if (!input && !base) return '';
1928
+ const url = parseUrl(input);
1929
+ let inputType = url.type;
1930
+ if (base && 7 !== inputType) {
1931
+ const baseUrl = parseUrl(base);
1932
+ const baseType = baseUrl.type;
1933
+ switch(inputType){
1934
+ case 1:
1935
+ url.hash = baseUrl.hash;
1936
+ case 2:
1937
+ url.query = baseUrl.query;
1938
+ case 3:
1939
+ case 4:
1940
+ mergePaths(url, baseUrl);
1941
+ case 5:
1942
+ url.user = baseUrl.user;
1943
+ url.host = baseUrl.host;
1944
+ url.port = baseUrl.port;
1945
+ case 6:
1946
+ url.scheme = baseUrl.scheme;
1947
+ }
1948
+ if (baseType > inputType) inputType = baseType;
1949
+ }
1950
+ normalizePath(url, inputType);
1951
+ const queryHash = url.query + url.hash;
1952
+ switch(inputType){
1953
+ case 2:
1954
+ case 3:
1955
+ return queryHash;
1956
+ case 4:
1957
+ {
1958
+ const path = url.path.slice(1);
1959
+ if (!path) return queryHash || '.';
1960
+ if (isRelative(base || input) && !isRelative(path)) return './' + path + queryHash;
1961
+ return path + queryHash;
1962
+ }
1963
+ case 5:
1964
+ return url.path + queryHash;
1965
+ default:
1966
+ return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
1967
+ }
1968
+ }
1969
+ function stripFilename(path) {
1970
+ if (!path) return "";
1971
+ const index = path.lastIndexOf("/");
1972
+ return path.slice(0, index + 1);
1973
+ }
1974
+ function trace_mapping_resolver(mapUrl, sourceRoot) {
1975
+ const from = stripFilename(mapUrl);
1976
+ const prefix = sourceRoot ? sourceRoot + "/" : "";
1977
+ return (source)=>resolve_uri_resolve(prefix + (source || ""), from);
1978
+ }
1979
+ var COLUMN = 0;
1980
+ var SOURCES_INDEX = 1;
1981
+ var SOURCE_LINE = 2;
1982
+ var SOURCE_COLUMN = 3;
1983
+ var NAMES_INDEX = 4;
1984
+ function maybeSort(mappings, owned) {
1985
+ const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
1986
+ if (unsortedIndex === mappings.length) return mappings;
1987
+ if (!owned) mappings = mappings.slice();
1988
+ for(let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1))mappings[i] = sortSegments(mappings[i], owned);
1989
+ return mappings;
1990
+ }
1991
+ function nextUnsortedSegmentLine(mappings, start) {
1992
+ for(let i = start; i < mappings.length; i++)if (!isSorted(mappings[i])) return i;
1993
+ return mappings.length;
1994
+ }
1995
+ function isSorted(line) {
1996
+ for(let j = 1; j < line.length; j++)if (line[j][COLUMN] < line[j - 1][COLUMN]) return false;
1997
+ return true;
1998
+ }
1999
+ function sortSegments(line, owned) {
2000
+ if (!owned) line = line.slice();
2001
+ return line.sort(sortComparator);
2002
+ }
2003
+ function sortComparator(a, b) {
2004
+ return a[COLUMN] - b[COLUMN];
2005
+ }
2006
+ var found = false;
2007
+ function binarySearch(haystack, needle, low, high) {
2008
+ while(low <= high){
2009
+ const mid = low + (high - low >> 1);
2010
+ const cmp = haystack[mid][COLUMN] - needle;
2011
+ if (0 === cmp) {
2012
+ found = true;
2013
+ return mid;
2014
+ }
2015
+ if (cmp < 0) low = mid + 1;
2016
+ else high = mid - 1;
2017
+ }
2018
+ found = false;
2019
+ return low - 1;
2020
+ }
2021
+ function upperBound(haystack, needle, index) {
2022
+ for(let i = index + 1; i < haystack.length && haystack[i][COLUMN] === needle; index = i++);
2023
+ return index;
2024
+ }
2025
+ function lowerBound(haystack, needle, index) {
2026
+ for(let i = index - 1; i >= 0 && haystack[i][COLUMN] === needle; index = i--);
2027
+ return index;
2028
+ }
2029
+ function memoizedState() {
2030
+ return {
2031
+ lastKey: -1,
2032
+ lastNeedle: -1,
2033
+ lastIndex: -1
2034
+ };
2035
+ }
2036
+ function memoizedBinarySearch(haystack, needle, state, key) {
2037
+ const { lastKey, lastNeedle, lastIndex } = state;
2038
+ let low = 0;
2039
+ let high = haystack.length - 1;
2040
+ if (key === lastKey) {
2041
+ if (needle === lastNeedle) {
2042
+ found = -1 !== lastIndex && haystack[lastIndex][COLUMN] === needle;
2043
+ return lastIndex;
2044
+ }
2045
+ if (needle >= lastNeedle) low = -1 === lastIndex ? 0 : lastIndex;
2046
+ else high = lastIndex;
2047
+ }
2048
+ state.lastKey = key;
2049
+ state.lastNeedle = needle;
2050
+ return state.lastIndex = binarySearch(haystack, needle, low, high);
2051
+ }
2052
+ function trace_mapping_parse(map) {
2053
+ return "string" == typeof map ? JSON.parse(map) : map;
2054
+ }
2055
+ var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
2056
+ var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
2057
+ var LEAST_UPPER_BOUND = -1;
2058
+ var GREATEST_LOWER_BOUND = 1;
2059
+ var TraceMap = class {
2060
+ constructor(map, mapUrl){
2061
+ const isString = "string" == typeof map;
2062
+ if (!isString && map._decodedMemo) return map;
2063
+ const parsed = trace_mapping_parse(map);
2064
+ const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
2065
+ this.version = version;
2066
+ this.file = file;
2067
+ this.names = names || [];
2068
+ this.sourceRoot = sourceRoot;
2069
+ this.sources = sources;
2070
+ this.sourcesContent = sourcesContent;
2071
+ this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
2072
+ const resolve = trace_mapping_resolver(mapUrl, sourceRoot);
2073
+ this.resolvedSources = sources.map(resolve);
2074
+ const { mappings } = parsed;
2075
+ if ("string" == typeof mappings) {
2076
+ this._encoded = mappings;
2077
+ this._decoded = void 0;
2078
+ } else if (Array.isArray(mappings)) {
2079
+ this._encoded = void 0;
2080
+ this._decoded = maybeSort(mappings, isString);
2081
+ } else if (parsed.sections) throw new Error("TraceMap passed sectioned source map, please use FlattenMap export instead");
2082
+ else throw new Error(`invalid source map: ${JSON.stringify(parsed)}`);
2083
+ this._decodedMemo = memoizedState();
2084
+ this._bySources = void 0;
2085
+ this._bySourceMemos = void 0;
2086
+ }
2087
+ };
2088
+ function cast(map) {
2089
+ return map;
2090
+ }
2091
+ function decodedMappings(map) {
2092
+ var _a;
2093
+ return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded));
2094
+ }
2095
+ function originalPositionFor(map, needle) {
2096
+ let { line, column, bias } = needle;
2097
+ line--;
2098
+ if (line < 0) throw new Error(LINE_GTR_ZERO);
2099
+ if (column < 0) throw new Error(COL_GTR_EQ_ZERO);
2100
+ const decoded = decodedMappings(map);
2101
+ if (line >= decoded.length) return OMapping(null, null, null, null);
2102
+ const segments = decoded[line];
2103
+ const index = traceSegmentInternal(segments, cast(map)._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
2104
+ if (-1 === index) return OMapping(null, null, null, null);
2105
+ const segment = segments[index];
2106
+ if (1 === segment.length) return OMapping(null, null, null, null);
2107
+ const { names, resolvedSources } = map;
2108
+ return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], 5 === segment.length ? names[segment[NAMES_INDEX]] : null);
2109
+ }
2110
+ function OMapping(source, line, column, name) {
2111
+ return {
2112
+ source,
2113
+ line,
2114
+ column,
2115
+ name
2116
+ };
2117
+ }
2118
+ function traceSegmentInternal(segments, memo, line, column, bias) {
2119
+ let index = memoizedBinarySearch(segments, column, memo, line);
2120
+ if (found) index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index);
2121
+ else if (bias === LEAST_UPPER_BOUND) index++;
2122
+ if (-1 === index || index === segments.length) return -1;
2123
+ return index;
2124
+ }
2125
+ const hintNotDefinedError = (message)=>{
2126
+ const [, varName] = message.match(/(\w+) is not defined/) || [];
2127
+ if (varName) {
2128
+ if (globalApis.includes(varName)) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you forget to enable "globals" configuration?`);
2129
+ if ([
2130
+ 'jest',
2131
+ 'vitest'
2132
+ ].includes(varName)) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you mean rstest?`);
2133
+ if ('React' === varName) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you forget to install "${picocolors_default().yellow('@rsbuild/plugin-react')}" plugin?`);
2134
+ }
2135
+ return message;
2136
+ };
2137
+ async function error_printError(error, getSourcemap, rootPath) {
2138
+ const errorName = error.name || 'Unknown Error';
2139
+ if (error.message.includes('Vitest failed to access its internal state')) {
2140
+ const tips = [
2141
+ 'Error: not support import `vitest` in Rstest test environment.\n',
2142
+ 'Solution:',
2143
+ ` - Update your code to use imports from "${picocolors_default().yellow('@rstest/core')}" instead of "${picocolors_default().yellow('vitest')}".`,
2144
+ ' - Enable `globals` configuration and use global API.'
2145
+ ];
2146
+ src_logger.log(`${picocolors_default().red(tips.join('\n'))}\n`);
2147
+ return;
2148
+ }
2149
+ if (error.message.includes('is not defined')) error.message = hintNotDefinedError(error.message);
2150
+ src_logger.log(`${picocolors_default().red(picocolors_default().bold(errorName))}${picocolors_default().red(`: ${error.message}`)}\n`);
2151
+ if (error.diff) {
2152
+ src_logger.log(error.diff);
2153
+ src_logger.log();
2154
+ }
2155
+ if (error.stack) {
2156
+ const stackFrames = await error_parseErrorStacktrace({
2157
+ stack: error.stack,
2158
+ fullStack: error.fullStack,
2159
+ getSourcemap
2160
+ });
2161
+ if (!stackFrames.length && !(error.fullStack || isDebug()) && !error.stack.endsWith(error.message)) src_logger.log(picocolors_default().gray("No error stack found, set 'DEBUG=rstest' to show fullStack."));
2162
+ if (stackFrames[0]) await printCodeFrame(stackFrames[0]);
2163
+ printStack(stackFrames, rootPath);
2164
+ }
2165
+ }
2166
+ async function printCodeFrame(frame) {
2167
+ const filePath = frame.file?.startsWith('file') ? new URL(frame.file) : frame.file;
2168
+ if (!filePath) return;
2169
+ const source = external_node_fs_["default"].existsSync(filePath) ? external_node_fs_["default"].readFileSync(filePath, 'utf-8') : void 0;
2170
+ if (!source) return;
2171
+ const { codeFrameColumns } = await import("./0~919.js").then(__webpack_require__.bind(__webpack_require__, "../../node_modules/.pnpm/@babel+code-frame@7.27.1/node_modules/@babel/code-frame/lib/index.js"));
2172
+ const result = codeFrameColumns(source, {
2173
+ start: {
2174
+ line: frame.lineNumber,
2175
+ column: frame.column
2176
+ }
2177
+ }, {
2178
+ highlightCode: true,
2179
+ linesBelow: 2
2180
+ });
2181
+ src_logger.log(result);
2182
+ src_logger.log('');
2183
+ }
2184
+ function formatStack(frame, rootPath) {
2185
+ return '<unknown>' !== frame.methodName ? `at ${frame.methodName} (${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column})` : `at ${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column}`;
2186
+ }
2187
+ function printStack(stackFrames, rootPath) {
2188
+ for (const frame of stackFrames)src_logger.log(picocolors_default().gray(` ${formatStack(frame, rootPath)}`));
2189
+ stackFrames.length && src_logger.log();
2190
+ }
2191
+ const stackIgnores = [
2192
+ /\/@rstest\/core/,
2193
+ /rstest\/packages\/core\/dist/,
2194
+ /node_modules\/tinypool/,
2195
+ /node_modules\/chai/,
2196
+ /node_modules\/@vitest\/expect/,
2197
+ /node_modules\/@vitest\/snapshot/,
2198
+ /node:\w+/,
2199
+ /webpack\/runtime/,
2200
+ /webpack\\runtime/,
2201
+ '<anonymous>'
2202
+ ];
2203
+ async function error_parseErrorStacktrace({ stack, getSourcemap, fullStack = isDebug() }) {
2204
+ const stackFrames = await Promise.all(stack_trace_parser_esm_parse(stack).filter((frame)=>fullStack ? true : frame.file && !stackIgnores.some((entry)=>frame.file?.match(entry))).map(async (frame)=>{
2205
+ const sourcemap = await getSourcemap(frame.file);
2206
+ if (sourcemap) {
2207
+ const traceMap = new TraceMap(sourcemap);
2208
+ const { line, column, source, name } = originalPositionFor(traceMap, {
2209
+ line: frame.lineNumber,
2210
+ column: frame.column
2211
+ });
2212
+ if (!source) return null;
2213
+ return {
2214
+ ...frame,
2215
+ file: source,
2216
+ lineNumber: line,
2217
+ name,
2218
+ column
2219
+ };
2220
+ }
2221
+ return frame;
2222
+ })).then((frames)=>frames.filter((frame)=>null !== frame));
2223
+ return stackFrames;
2224
+ }
2225
+ class JUnitReporter {
2226
+ rootPath;
2227
+ outputPath;
2228
+ constructor({ rootPath, options: { outputPath } = {} }){
2229
+ this.rootPath = rootPath;
2230
+ this.outputPath = outputPath;
2231
+ }
2232
+ sanitizeXml(text) {
2233
+ let result = '';
2234
+ for (const ch of stripAnsi(text)){
2235
+ const cp = ch.codePointAt(0);
2236
+ const valid = 0x09 === cp || 0x0a === cp || 0x0d === cp || cp >= 0x20 && cp <= 0xd7ff || cp >= 0xe000 && cp <= 0xfffd || cp >= 0x10000 && cp <= 0x10ffff;
2237
+ if (valid) result += ch;
2238
+ }
2239
+ return result;
2240
+ }
2241
+ escapeXml(text) {
2242
+ const sanitized = this.sanitizeXml(text);
2243
+ return sanitized.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
2244
+ }
2245
+ async createJUnitTestCase(test, getSourcemap) {
2246
+ const testCase = {
2247
+ name: getTaskNameWithPrefix(test),
2248
+ classname: pathe_M_eThtNZ_relative(this.rootPath, test.testPath),
2249
+ time: (test.duration || 0) / 1000,
2250
+ status: test.status
2251
+ };
2252
+ if (test.errors && test.errors.length > 0) testCase.errors = await Promise.all(test.errors.map(async (error)=>{
2253
+ let details = `${error.message}${error.diff ? `\n${error.diff}` : ''}`;
2254
+ const stackFrames = error.stack ? await error_parseErrorStacktrace({
2255
+ stack: error.stack,
2256
+ fullStack: error.fullStack,
2257
+ getSourcemap
2258
+ }) : [];
2259
+ if (stackFrames[0]) details += `\n${formatStack(stackFrames[0], this.rootPath)}`;
2260
+ return {
2261
+ message: this.escapeXml(error.message),
2262
+ type: error.name || 'Error',
2263
+ details: this.escapeXml(details)
2264
+ };
2265
+ }));
2266
+ return testCase;
2267
+ }
2268
+ async createJUnitTestSuite(fileResult, getSourcemap) {
2269
+ const testCases = await Promise.all(fileResult.results.map(async (test)=>this.createJUnitTestCase(test, getSourcemap)));
2270
+ const failures = testCases.filter((test)=>'fail' === test.status).length;
2271
+ const errors = 0;
2272
+ const skipped = testCases.filter((test)=>'skip' === test.status || 'todo' === test.status).length;
2273
+ const totalTime = testCases.reduce((sum, test)=>sum + test.time, 0);
2274
+ return {
2275
+ name: pathe_M_eThtNZ_relative(this.rootPath, fileResult.testPath),
2276
+ tests: testCases.length,
2277
+ failures,
2278
+ errors,
2279
+ skipped,
2280
+ time: totalTime,
2281
+ timestamp: new Date().toISOString(),
2282
+ testcases: testCases
2283
+ };
2284
+ }
2285
+ generateJUnitXml(report) {
2286
+ const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?>';
2287
+ const testsuitesXml = `
2288
+ <testsuites name="${this.escapeXml(report.testsuites.name)}" tests="${report.testsuites.tests}" failures="${report.testsuites.failures}" errors="${report.testsuites.errors}" skipped="${report.testsuites.skipped}" time="${report.testsuites.time}" timestamp="${this.escapeXml(report.testsuites.timestamp)}">`;
2289
+ const testsuiteXmls = report.testsuites.testsuite.map((suite)=>{
2290
+ const testsuiteStart = `
2291
+ <testsuite name="${this.escapeXml(suite.name)}" tests="${suite.tests}" failures="${suite.failures}" errors="${suite.errors}" skipped="${suite.skipped}" time="${suite.time}" timestamp="${this.escapeXml(suite.timestamp)}">`;
2292
+ const testcaseXmls = suite.testcases.map((testcase)=>{
2293
+ let testcaseXml = `
2294
+ <testcase name="${this.escapeXml(testcase.name)}" classname="${this.escapeXml(testcase.classname)}" time="${testcase.time}">`;
2295
+ if ('skip' === testcase.status || 'todo' === testcase.status) testcaseXml += `
2296
+ <skipped/>`;
2297
+ else if ('fail' === testcase.status && testcase.errors) testcase.errors.forEach((error)=>{
2298
+ testcaseXml += `
2299
+ <failure message="${error.message}" type="${error.type}">${error.details || ''}</failure>`;
2300
+ });
2301
+ testcaseXml += `
2302
+ </testcase>`;
2303
+ return testcaseXml;
2304
+ }).join('');
2305
+ const testsuiteEnd = `
2306
+ </testsuite>`;
2307
+ return testsuiteStart + testcaseXmls + testsuiteEnd;
2308
+ }).join('');
2309
+ const testsuitesEnd = `
2310
+ </testsuites>`;
2311
+ return xmlDeclaration + testsuitesXml + testsuiteXmls + testsuitesEnd;
2312
+ }
2313
+ async onTestRunEnd({ results, testResults, duration, getSourcemap }) {
2314
+ const testSuites = await Promise.all(results.map(async (fileResult)=>this.createJUnitTestSuite(fileResult, getSourcemap)));
2315
+ const totalTests = testResults.length;
2316
+ const totalFailures = testResults.filter((test)=>'fail' === test.status).length;
2317
+ const totalErrors = 0;
2318
+ const totalSkipped = testResults.filter((test)=>'skip' === test.status || 'todo' === test.status).length;
2319
+ const totalTime = duration.testTime / 1000;
2320
+ const report = {
2321
+ testsuites: {
2322
+ name: 'rstest tests',
2323
+ tests: totalTests,
2324
+ failures: totalFailures,
2325
+ errors: totalErrors,
2326
+ skipped: totalSkipped,
2327
+ time: totalTime,
2328
+ timestamp: new Date().toISOString(),
2329
+ testsuite: testSuites
2330
+ }
2331
+ };
2332
+ const xmlContent = this.generateJUnitXml(report);
2333
+ if (this.outputPath) try {
2334
+ await writeFile(this.outputPath, xmlContent, 'utf-8');
2335
+ console.log(`JUnit XML report written to: ${this.outputPath}`);
2336
+ } catch (error) {
2337
+ console.error(`Failed to write JUnit XML report to ${this.outputPath}:`, error);
2338
+ console.log('JUnit XML Report:');
2339
+ console.log(xmlContent);
2340
+ }
2341
+ else console.log(xmlContent);
2342
+ }
2343
+ }
2344
+ class VerboseReporter extends DefaultReporter {
2345
+ onTestFileResult(test) {
2346
+ this.statusRenderer?.onTestFileResult(test);
2347
+ const relativePath = pathe_M_eThtNZ_relative(this.rootPath, test.testPath);
2348
+ const { slowTestThreshold } = this.config;
2349
+ logFileTitle(test, relativePath, true);
2350
+ for (const result of test.results)logCase(result, {
2351
+ slowTestThreshold,
2352
+ hideSkippedTests: this.config.hideSkippedTests
2353
+ });
2354
+ }
2355
+ }
2356
+ class TestStateManager {
2357
+ runningModules = new Map();
2358
+ testModules = [];
2359
+ onTestFileStart(testPath) {
2360
+ this.runningModules.set(testPath, []);
2361
+ }
2362
+ onTestCaseResult(result) {
2363
+ this.runningModules.set(result.testPath, [
2364
+ ...this.runningModules.get(result.testPath) || [],
2365
+ result
2366
+ ]);
2367
+ }
2368
+ getCountOfFailedTests() {
2369
+ const testResults = Array.from(this.runningModules.values()).flat().concat(this.testModules.flatMap((mod)=>mod.results));
2370
+ return testResults.filter((t)=>'fail' === t.status).length;
2371
+ }
2372
+ onTestFileResult(test) {
2373
+ this.runningModules.delete(test.testPath);
2374
+ this.testModules.push(test);
2375
+ }
2376
+ reset() {
2377
+ this.runningModules.clear();
2378
+ this.testModules = [];
2379
+ }
2380
+ }
2381
+ function formatEnvironmentName(name) {
2382
+ return name.replace(/[^a-zA-Z0-9\-_$]/g, '_');
2383
+ }
2384
+ class Rstest {
2385
+ cwd;
2386
+ command;
2387
+ fileFilters;
2388
+ configFilePath;
2389
+ reporters;
2390
+ snapshotManager;
2391
+ version;
2392
+ rootPath;
2393
+ originalConfig;
2394
+ normalizedConfig;
2395
+ reporterResults = {
2396
+ results: [],
2397
+ testResults: []
2398
+ };
2399
+ stateManager = new TestStateManager();
2400
+ projects = [];
2401
+ constructor({ cwd = process.cwd(), command, fileFilters, configFilePath, projects }, userConfig){
2402
+ this.cwd = cwd;
2403
+ this.command = command;
2404
+ this.fileFilters = fileFilters;
2405
+ this.configFilePath = configFilePath;
2406
+ const rootPath = userConfig.root ? getAbsolutePath(cwd, userConfig.root) : cwd;
2407
+ const rstestConfig = withDefaultConfig({
2408
+ ...userConfig,
2409
+ root: rootPath
2410
+ });
2411
+ const reporters = 'list' !== command ? createReporters(rstestConfig.reporters, {
2412
+ rootPath,
2413
+ config: rstestConfig
2414
+ }) : [];
2415
+ const snapshotManager = new SnapshotManager({
2416
+ updateSnapshot: rstestConfig.update ? 'all' : T ? 'none' : 'new'
2417
+ });
2418
+ this.reporters = reporters;
2419
+ this.snapshotManager = snapshotManager;
2420
+ this.version = "0.6.7";
2421
+ this.rootPath = rootPath;
2422
+ this.originalConfig = userConfig;
2423
+ this.normalizedConfig = rstestConfig;
2424
+ this.projects = projects.length ? projects.map((project)=>{
2425
+ project.config.root = getAbsolutePath(rootPath, project.config.root);
2426
+ const config = withDefaultConfig(project.config);
2427
+ config.isolate = rstestConfig.isolate;
2428
+ config.coverage = rstestConfig.coverage;
2429
+ config.bail = rstestConfig.bail;
2430
+ config.source ??= {};
2431
+ if (config.source.tsconfigPath) config.source.tsconfigPath = getAbsolutePath(config.root, config.source.tsconfigPath);
2432
+ else {
2433
+ const tsconfigPath = join(config.root, TS_CONFIG_FILE);
2434
+ if ((0, external_node_fs_.existsSync)(tsconfigPath)) config.source.tsconfigPath = tsconfigPath;
2435
+ }
2436
+ return {
2437
+ configFilePath: project.configFilePath,
2438
+ rootPath: config.root,
2439
+ name: config.name,
2440
+ environmentName: formatEnvironmentName(config.name),
2441
+ normalizedConfig: config
2442
+ };
2443
+ }) : [
2444
+ {
2445
+ configFilePath,
2446
+ rootPath,
2447
+ name: rstestConfig.name,
2448
+ environmentName: formatEnvironmentName(rstestConfig.name),
2449
+ normalizedConfig: rstestConfig
2450
+ }
2451
+ ];
2452
+ }
2453
+ updateReporterResultState(results, testResults, deletedEntries = []) {
2454
+ results.forEach((item)=>{
2455
+ const existingIndex = this.reporterResults.results.findIndex((r)=>r.testPath === item.testPath);
2456
+ if (-1 !== existingIndex) this.reporterResults.results[existingIndex] = item;
2457
+ else this.reporterResults.results.push(item);
2458
+ });
2459
+ const testPathsToUpdate = new Set(testResults.map((r)=>r.testPath));
2460
+ this.reporterResults.testResults = this.reporterResults.testResults.filter((r)=>!testPathsToUpdate.has(r.testPath));
2461
+ this.reporterResults.testResults.push(...testResults);
2462
+ if (deletedEntries.length > 0) {
2463
+ const deletedPathsSet = new Set(deletedEntries);
2464
+ this.reporterResults.results = this.reporterResults.results.filter((r)=>!deletedPathsSet.has(r.testPath));
2465
+ this.reporterResults.testResults = this.reporterResults.testResults.filter((r)=>!deletedPathsSet.has(r.testPath));
2466
+ }
2467
+ }
2468
+ }
2469
+ const reportersMap = {
2470
+ default: DefaultReporter,
2471
+ verbose: VerboseReporter,
2472
+ 'github-actions': GithubActionsReporter,
2473
+ junit: JUnitReporter
2474
+ };
2475
+ function createReporters(reporters, initOptions = {}) {
2476
+ const result = castArray(reporters).map((reporter)=>{
2477
+ if ('string' == typeof reporter || Array.isArray(reporter)) {
2478
+ const [name, options = {}] = 'string' == typeof reporter ? [
2479
+ reporter,
2480
+ {}
2481
+ ] : reporter;
2482
+ if (name in reportersMap) {
2483
+ const Reporter = reportersMap[name];
2484
+ return new Reporter({
2485
+ ...initOptions,
2486
+ options
2487
+ });
2488
+ }
2489
+ throw new Error(`Reporter ${reporter} not found. Please install it or use a built-in reporter.`);
2490
+ }
2491
+ return reporter;
2492
+ });
2493
+ return result;
2494
+ }
2495
+ function core_createRstest({ config, projects, configFilePath }, command, fileFilters) {
2496
+ const context = new Rstest({
2497
+ cwd: process.cwd(),
2498
+ command,
2499
+ fileFilters,
2500
+ configFilePath,
2501
+ projects
2502
+ }, config);
2503
+ const runTests = async ()=>{
2504
+ const { runTests } = await import("./0~173.js").then((mod)=>({
2505
+ runTests: mod.runTests
2506
+ }));
2507
+ await runTests(context);
2508
+ };
2509
+ const listTests = async (options)=>{
2510
+ const { listTests } = await import("./0~634.js").then((mod)=>({
2511
+ listTests: mod.listTests
2512
+ }));
2513
+ await listTests(context, options);
2514
+ };
2515
+ return {
2516
+ context,
2517
+ runTests,
2518
+ listTests
2519
+ };
2520
+ }
2521
+ const check = (name)=>{
2522
+ if (!globalThis.RSTEST_API?.[name]) throw new Error(`Rstest API '${name}' is not registered yet, please make sure you are running in a rstest environment.`);
2523
+ };
2524
+ const wrapRstestAPI = (name)=>{
2525
+ const fn = (...args)=>{
2526
+ check(name);
2527
+ return globalThis.RSTEST_API[name].call(globalThis.RSTEST_API[name], ...args);
2528
+ };
2529
+ return new Proxy(fn, {
2530
+ get (_target, key, receiver) {
2531
+ check(name);
2532
+ return Reflect.get(globalThis.RSTEST_API?.[name] || {}, key, receiver);
2533
+ }
2534
+ });
2535
+ };
2536
+ const wrapRstestUtilitiesAPI = (name)=>new Proxy({}, {
2537
+ get (_target, key, receiver) {
2538
+ check(name);
2539
+ return Reflect.get(globalThis.RSTEST_API?.[name] || {}, key, receiver);
2540
+ }
2541
+ });
2542
+ const expect = wrapRstestAPI('expect');
2543
+ const assert = wrapRstestAPI('assert');
2544
+ const it = wrapRstestAPI('it');
2545
+ const public_test = wrapRstestAPI('test');
2546
+ const describe = wrapRstestAPI('describe');
2547
+ const beforeAll = wrapRstestAPI('beforeAll');
2548
+ const afterAll = wrapRstestAPI('afterAll');
2549
+ const beforeEach = wrapRstestAPI('beforeEach');
2550
+ const afterEach = wrapRstestAPI('afterEach');
2551
+ const public_rstest = wrapRstestUtilitiesAPI('rstest');
2552
+ const rs = wrapRstestUtilitiesAPI('rs');
2553
+ const onTestFinished = wrapRstestAPI('onTestFinished');
2554
+ const onTestFailed = wrapRstestAPI('onTestFailed');
2555
+ function defineConfig(config) {
2556
+ return config;
2557
+ }
2558
+ function defineProject(config) {
2559
+ return config;
2560
+ }
2561
+ export { EventEmitter, afterAll, afterEach, assert, beforeAll, beforeEach, config_loadConfig as loadConfig, core_createRstest as createRstest, createRsbuild, defineConfig, defineProject, describe, error_printError, expect, init_initCli as initCli, it, logger, mergeRstestConfig, onTestFailed, onTestFinished, public_rstest as rstest, public_test as test, rs, runCLI, runRest };