@rstest/core 0.3.0 → 0.3.2

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/LICENSE.md CHANGED
@@ -928,6 +928,20 @@ Licensed under MIT license in the repository at git+https://github.com/errwischt
928
928
  > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
929
929
  > SOFTWARE.
930
930
 
931
+ ### strip-ansi
932
+
933
+ Licensed under MIT license.
934
+
935
+ > MIT License
936
+ >
937
+ > Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
938
+ >
939
+ > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
940
+ >
941
+ > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
942
+ >
943
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
944
+
931
945
  ### supports-color
932
946
 
933
947
  Licensed under MIT license.
package/dist/223.js CHANGED
@@ -51,7 +51,7 @@ export const __webpack_modules__ = {
51
51
  };
52
52
  }
53
53
  async function resolveProjects({ config, root, options }) {
54
- if (!config.projects || !config.projects.length) return [];
54
+ if (!config.projects) return [];
55
55
  const getDefaultProjectName = (dir)=>{
56
56
  const pkgJsonPath = (0, pathe__WEBPACK_IMPORTED_MODULE_1__.resolve)(dir, 'package.json');
57
57
  const name = (0, node_fs__WEBPACK_IMPORTED_MODULE_0__.existsSync)(pkgJsonPath) ? JSON.parse((0, node_fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync)(pkgJsonPath, 'utf-8')).name : '';
@@ -72,8 +72,21 @@ export const __webpack_modules__ = {
72
72
  };
73
73
  return (0, tinyglobby__WEBPACK_IMPORTED_MODULE_4__.glob)(patterns, globOptions);
74
74
  };
75
- const { projectPaths, projectPatterns } = (config.projects || []).reduce((total, p)=>{
76
- const projectStr = p.replace('<rootDir>', root);
75
+ const formatRootStr = (rootStr)=>rootStr.replace('<rootDir>', root);
76
+ const { projectPaths, projectPatterns, projectConfigs } = (config.projects || []).reduce((total, p)=>{
77
+ if ('object' == typeof p) {
78
+ const projectRoot = p.root ? formatRootStr(p.root) : root;
79
+ total.projectConfigs.push({
80
+ config: {
81
+ root: projectRoot,
82
+ name: p.name ? p.name : getDefaultProjectName(projectRoot),
83
+ ...p
84
+ },
85
+ configFilePath: void 0
86
+ });
87
+ return total;
88
+ }
89
+ const projectStr = formatRootStr(p);
77
90
  if ((0, tinyglobby__WEBPACK_IMPORTED_MODULE_4__.ey)(projectStr)) total.projectPatterns.push(projectStr);
78
91
  else {
79
92
  const absolutePath = (0, _utils__WEBPACK_IMPORTED_MODULE_3__.FI)(root, projectStr);
@@ -83,7 +96,8 @@ export const __webpack_modules__ = {
83
96
  return total;
84
97
  }, {
85
98
  projectPaths: [],
86
- projectPatterns: []
99
+ projectPatterns: [],
100
+ projectConfigs: []
87
101
  });
88
102
  projectPaths.push(...await globProjects(projectPatterns));
89
103
  const projects = await Promise.all(projectPaths.map(async (project)=>{
@@ -99,7 +113,13 @@ export const __webpack_modules__ = {
99
113
  config,
100
114
  configFilePath
101
115
  };
102
- }));
116
+ })).then((projects)=>(0, _utils__WEBPACK_IMPORTED_MODULE_3__.zz)(projects.concat(projectConfigs), options));
117
+ if (!projects.length) {
118
+ let errorMsg = `No projects found, please make sure you have at least one valid project.
119
+ ${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.gray('projects:')} ${JSON.stringify(config.projects, null, 2)}`;
120
+ if (options.project) errorMsg += `\n${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.gray('projectName filter:')} ${JSON.stringify(options.project, null, 2)}`;
121
+ throw errorMsg;
122
+ }
103
123
  const names = new Set();
104
124
  projects.forEach((project)=>{
105
125
  if (names.has(project.config.name)) {
@@ -1,167 +1,18 @@
1
1
  import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
- export const __webpack_id__ = "12";
3
+ export const __webpack_id__ = "263";
4
4
  export const __webpack_ids__ = [
5
- "12"
5
+ "263"
6
6
  ];
7
7
  export const __webpack_modules__ = {
8
- "../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
- __webpack_require__.d(__webpack_exports__, {
10
- q: ()=>parse
11
- });
12
- var UNKNOWN_FUNCTION = '<unknown>';
13
- function parse(stackString) {
14
- var lines = stackString.split('\n');
15
- return lines.reduce(function(stack, line) {
16
- var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
17
- if (parseResult) stack.push(parseResult);
18
- return stack;
19
- }, []);
20
- }
21
- var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
22
- var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
23
- function parseChrome(line) {
24
- var parts = chromeRe.exec(line);
25
- if (!parts) return null;
26
- var isNative = parts[2] && 0 === parts[2].indexOf('native');
27
- var isEval = parts[2] && 0 === parts[2].indexOf('eval');
28
- var submatch = chromeEvalRe.exec(parts[2]);
29
- if (isEval && null != submatch) {
30
- parts[2] = submatch[1];
31
- parts[3] = submatch[2];
32
- parts[4] = submatch[3];
33
- }
34
- return {
35
- file: isNative ? null : parts[2],
36
- methodName: parts[1] || UNKNOWN_FUNCTION,
37
- arguments: isNative ? [
38
- parts[2]
39
- ] : [],
40
- lineNumber: parts[3] ? +parts[3] : null,
41
- column: parts[4] ? +parts[4] : null
42
- };
43
- }
44
- var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
45
- function parseWinjs(line) {
46
- var parts = winjsRe.exec(line);
47
- if (!parts) return null;
48
- return {
49
- file: parts[2],
50
- methodName: parts[1] || UNKNOWN_FUNCTION,
51
- arguments: [],
52
- lineNumber: +parts[3],
53
- column: parts[4] ? +parts[4] : null
54
- };
55
- }
56
- var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
57
- var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
58
- function parseGecko(line) {
59
- var parts = geckoRe.exec(line);
60
- if (!parts) return null;
61
- var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
62
- var submatch = geckoEvalRe.exec(parts[3]);
63
- if (isEval && null != submatch) {
64
- parts[3] = submatch[1];
65
- parts[4] = submatch[2];
66
- parts[5] = null;
67
- }
68
- return {
69
- file: parts[3],
70
- methodName: parts[1] || UNKNOWN_FUNCTION,
71
- arguments: parts[2] ? parts[2].split(',') : [],
72
- lineNumber: parts[4] ? +parts[4] : null,
73
- column: parts[5] ? +parts[5] : null
74
- };
75
- }
76
- var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
77
- function parseJSC(line) {
78
- var parts = javaScriptCoreRe.exec(line);
79
- if (!parts) return null;
80
- return {
81
- file: parts[3],
82
- methodName: parts[1] || UNKNOWN_FUNCTION,
83
- arguments: [],
84
- lineNumber: +parts[4],
85
- column: parts[5] ? +parts[5] : null
86
- };
87
- }
88
- var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
89
- function parseNode(line) {
90
- var parts = nodeRe.exec(line);
91
- if (!parts) return null;
92
- return {
93
- file: parts[2],
94
- methodName: parts[1] || UNKNOWN_FUNCTION,
95
- arguments: [],
96
- lineNumber: +parts[3],
97
- column: parts[4] ? +parts[4] : null
98
- };
99
- }
100
- },
101
8
  "./src/core/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
102
9
  __webpack_require__.d(__webpack_exports__, {
103
10
  createRstest: ()=>createRstest
104
11
  });
105
- var external_pathe_ = __webpack_require__("pathe");
106
- class SnapshotManager {
107
- summary;
108
- extension = ".snap";
109
- constructor(options){
110
- this.options = options;
111
- this.clear();
112
- }
113
- clear() {
114
- this.summary = emptySummary(this.options);
115
- }
116
- add(result) {
117
- addSnapshotResult(this.summary, result);
118
- }
119
- resolvePath(testPath, context) {
120
- const resolver = this.options.resolveSnapshotPath || (()=>(0, external_pathe_.join)((0, external_pathe_.join)((0, external_pathe_.dirname)(testPath), "__snapshots__"), `${(0, external_pathe_.basename)(testPath)}${this.extension}`));
121
- const path = resolver(testPath, this.extension, context);
122
- return path;
123
- }
124
- resolveRawPath(testPath, rawPath) {
125
- return (0, external_pathe_.isAbsolute)(rawPath) ? rawPath : (0, external_pathe_.resolve)((0, external_pathe_.dirname)(testPath), rawPath);
126
- }
127
- }
128
- function emptySummary(options) {
129
- const summary = {
130
- added: 0,
131
- failure: false,
132
- filesAdded: 0,
133
- filesRemoved: 0,
134
- filesRemovedList: [],
135
- filesUnmatched: 0,
136
- filesUpdated: 0,
137
- matched: 0,
138
- total: 0,
139
- unchecked: 0,
140
- uncheckedKeysByFile: [],
141
- unmatched: 0,
142
- updated: 0,
143
- didUpdate: "all" === options.updateSnapshot
144
- };
145
- return summary;
146
- }
147
- function addSnapshotResult(summary, result) {
148
- if (result.added) summary.filesAdded++;
149
- if (result.fileDeleted) summary.filesRemoved++;
150
- if (result.unmatched) summary.filesUnmatched++;
151
- if (result.updated) summary.filesUpdated++;
152
- summary.added += result.added;
153
- summary.matched += result.matched;
154
- summary.unchecked += result.unchecked;
155
- if (result.uncheckedKeys && result.uncheckedKeys.length > 0) summary.uncheckedKeysByFile.push({
156
- filePath: result.filepath,
157
- keys: result.uncheckedKeys
158
- });
159
- summary.unmatched += result.unmatched;
160
- summary.updated += result.updated;
161
- summary.total += result.added + result.matched + result.unmatched + result.updated;
162
- }
12
+ var manager = __webpack_require__("../../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/manager.js");
163
13
  var external_std_env_ = __webpack_require__("std-env");
164
14
  var src_config = __webpack_require__("./src/config.ts");
15
+ var external_pathe_ = __webpack_require__("pathe");
165
16
  var stack_trace_parser_esm = __webpack_require__("../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js");
166
17
  var utils = __webpack_require__("./src/utils/index.ts");
167
18
  var external_node_util_ = __webpack_require__("node:util");
@@ -381,10 +232,7 @@ export const __webpack_modules__ = {
381
232
  const nameStr = (0, utils.fN)(test);
382
233
  utils.vF.log(`${utils.yW.bgRed(' FAIL ')} ${(0, utils.EQ)(relativePath)} ${nameStr.length ? `${utils.yW.dim(utils.vO)} ${nameStr}` : ''}`);
383
234
  if (test.errors) {
384
- const { printError } = await Promise.all([
385
- __webpack_require__.e("829"),
386
- __webpack_require__.e("704")
387
- ]).then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
235
+ const { printError } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
388
236
  for (const error of test.errors)await printError(error, getSourcemap, rootPath);
389
237
  }
390
238
  }
@@ -503,10 +351,7 @@ export const __webpack_modules__ = {
503
351
  ...testResults.filter((i)=>'fail' === i.status)
504
352
  ];
505
353
  if (0 === failedTests.length) return;
506
- const { parseErrorStacktrace } = await Promise.all([
507
- __webpack_require__.e("829"),
508
- __webpack_require__.e("704")
509
- ]).then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
354
+ const { parseErrorStacktrace } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
510
355
  const logs = [];
511
356
  for (const test of failedTests){
512
357
  const { testPath } = test;
@@ -542,6 +387,128 @@ export const __webpack_modules__ = {
542
387
  function escapeData(s) {
543
388
  return s.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A').replace(/:/g, '%3A').replace(/,/g, '%2C');
544
389
  }
390
+ var promises_ = __webpack_require__("node:fs/promises");
391
+ var strip_ansi = __webpack_require__("../../node_modules/.pnpm/strip-ansi@7.1.0/node_modules/strip-ansi/index.js");
392
+ var utils_error = __webpack_require__("./src/utils/error.ts");
393
+ class JUnitReporter {
394
+ rootPath;
395
+ outputPath;
396
+ constructor({ rootPath, options: { outputPath } = {} }){
397
+ this.rootPath = rootPath;
398
+ this.outputPath = outputPath;
399
+ }
400
+ sanitizeXml(text) {
401
+ let result = '';
402
+ for (const ch of (0, strip_ansi.A)(text)){
403
+ const cp = ch.codePointAt(0);
404
+ const valid = 0x09 === cp || 0x0a === cp || 0x0d === cp || cp >= 0x20 && cp <= 0xd7ff || cp >= 0xe000 && cp <= 0xfffd || cp >= 0x10000 && cp <= 0x10ffff;
405
+ if (valid) result += ch;
406
+ }
407
+ return result;
408
+ }
409
+ escapeXml(text) {
410
+ const sanitized = this.sanitizeXml(text);
411
+ return sanitized.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
412
+ }
413
+ async createJUnitTestCase(test, getSourcemap) {
414
+ const testCase = {
415
+ name: (0, utils.fN)(test),
416
+ classname: (0, external_pathe_.relative)(this.rootPath, test.testPath),
417
+ time: (test.duration || 0) / 1000,
418
+ status: test.status
419
+ };
420
+ if (test.errors && test.errors.length > 0) testCase.errors = await Promise.all(test.errors.map(async (error)=>{
421
+ let details = `${error.message}${error.diff ? `\n${error.diff}` : ''}`;
422
+ const stackFrames = error.stack ? await (0, utils_error.parseErrorStacktrace)({
423
+ stack: error.stack,
424
+ fullStack: error.fullStack,
425
+ getSourcemap
426
+ }) : [];
427
+ if (stackFrames[0]) details += `\n${(0, utils_error.C)(stackFrames[0], this.rootPath)}`;
428
+ return {
429
+ message: this.escapeXml(error.message),
430
+ type: error.name || 'Error',
431
+ details: this.escapeXml(details)
432
+ };
433
+ }));
434
+ return testCase;
435
+ }
436
+ async createJUnitTestSuite(fileResult, getSourcemap) {
437
+ const testCases = await Promise.all(fileResult.results.map(async (test)=>this.createJUnitTestCase(test, getSourcemap)));
438
+ const failures = testCases.filter((test)=>'fail' === test.status).length;
439
+ const errors = 0;
440
+ const skipped = testCases.filter((test)=>'skip' === test.status || 'todo' === test.status).length;
441
+ const totalTime = testCases.reduce((sum, test)=>sum + test.time, 0);
442
+ return {
443
+ name: (0, external_pathe_.relative)(this.rootPath, fileResult.testPath),
444
+ tests: testCases.length,
445
+ failures,
446
+ errors,
447
+ skipped,
448
+ time: totalTime,
449
+ timestamp: new Date().toISOString(),
450
+ testcases: testCases
451
+ };
452
+ }
453
+ generateJUnitXml(report) {
454
+ const xmlDeclaration = '<?xml version="1.0" encoding="UTF-8"?>';
455
+ const testsuitesXml = `
456
+ <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)}">`;
457
+ const testsuiteXmls = report.testsuites.testsuite.map((suite)=>{
458
+ const testsuiteStart = `
459
+ <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)}">`;
460
+ const testcaseXmls = suite.testcases.map((testcase)=>{
461
+ let testcaseXml = `
462
+ <testcase name="${this.escapeXml(testcase.name)}" classname="${this.escapeXml(testcase.classname)}" time="${testcase.time}">`;
463
+ if ('skip' === testcase.status || 'todo' === testcase.status) testcaseXml += `
464
+ <skipped/>`;
465
+ else if ('fail' === testcase.status && testcase.errors) testcase.errors.forEach((error)=>{
466
+ testcaseXml += `
467
+ <failure message="${error.message}" type="${error.type}">${error.details || ''}</failure>`;
468
+ });
469
+ testcaseXml += `
470
+ </testcase>`;
471
+ return testcaseXml;
472
+ }).join('');
473
+ const testsuiteEnd = `
474
+ </testsuite>`;
475
+ return testsuiteStart + testcaseXmls + testsuiteEnd;
476
+ }).join('');
477
+ const testsuitesEnd = `
478
+ </testsuites>`;
479
+ return xmlDeclaration + testsuitesXml + testsuiteXmls + testsuitesEnd;
480
+ }
481
+ async onTestRunEnd({ results, testResults, duration, getSourcemap }) {
482
+ const testSuites = await Promise.all(results.map(async (fileResult)=>this.createJUnitTestSuite(fileResult, getSourcemap)));
483
+ const totalTests = testResults.length;
484
+ const totalFailures = testResults.filter((test)=>'fail' === test.status).length;
485
+ const totalErrors = 0;
486
+ const totalSkipped = testResults.filter((test)=>'skip' === test.status || 'todo' === test.status).length;
487
+ const totalTime = duration.testTime / 1000;
488
+ const report = {
489
+ testsuites: {
490
+ name: 'rstest tests',
491
+ tests: totalTests,
492
+ failures: totalFailures,
493
+ errors: totalErrors,
494
+ skipped: totalSkipped,
495
+ time: totalTime,
496
+ timestamp: new Date().toISOString(),
497
+ testsuite: testSuites
498
+ }
499
+ };
500
+ const xmlContent = this.generateJUnitXml(report);
501
+ if (this.outputPath) try {
502
+ await (0, promises_.writeFile)(this.outputPath, xmlContent, 'utf-8');
503
+ console.log(`JUnit XML report written to: ${this.outputPath}`);
504
+ } catch (error) {
505
+ console.error(`Failed to write JUnit XML report to ${this.outputPath}:`, error);
506
+ console.log('JUnit XML Report:');
507
+ console.log(xmlContent);
508
+ }
509
+ else console.log(xmlContent);
510
+ }
511
+ }
545
512
  class VerboseReporter extends DefaultReporter {
546
513
  onTestFileResult(test) {
547
514
  this.statusRenderer?.removeRunningModule(test.testPath);
@@ -583,17 +550,18 @@ export const __webpack_modules__ = {
583
550
  rootPath,
584
551
  config: rstestConfig
585
552
  }) : [];
586
- const snapshotManager = new SnapshotManager({
553
+ const snapshotManager = new manager.CW({
587
554
  updateSnapshot: rstestConfig.update ? 'all' : external_std_env_.isCI ? 'none' : 'new'
588
555
  });
589
556
  this.reporters = reporters;
590
557
  this.snapshotManager = snapshotManager;
591
- this.version = "0.3.0";
558
+ this.version = "0.3.2";
592
559
  this.rootPath = rootPath;
593
560
  this.originalConfig = userConfig;
594
561
  this.normalizedConfig = rstestConfig;
595
562
  this.projects = projects.length ? projects.map((project)=>{
596
563
  const config = (0, src_config.wX)(project.config);
564
+ config.isolate = rstestConfig.isolate;
597
565
  return {
598
566
  configFilePath: project.configFilePath,
599
567
  rootPath: config.root,
@@ -630,7 +598,8 @@ export const __webpack_modules__ = {
630
598
  const reportersMap = {
631
599
  default: DefaultReporter,
632
600
  verbose: VerboseReporter,
633
- 'github-actions': GithubActionsReporter
601
+ 'github-actions': GithubActionsReporter,
602
+ junit: JUnitReporter
634
603
  };
635
604
  function createReporters(reporters, initOptions = {}) {
636
605
  const result = (0, helper.bg)(reporters).map((reporter)=>{
@@ -680,5 +649,103 @@ export const __webpack_modules__ = {
680
649
  listTests
681
650
  };
682
651
  }
652
+ },
653
+ "./src/utils/error.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
654
+ __webpack_require__.d(__webpack_exports__, {
655
+ C: ()=>formatStack,
656
+ parseErrorStacktrace: ()=>parseErrorStacktrace,
657
+ printError: ()=>printError
658
+ });
659
+ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:fs");
660
+ var _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.30/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs");
661
+ var stacktrace_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js");
662
+ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/utils/index.ts");
663
+ async function printError(error, getSourcemap, rootPath) {
664
+ const errorName = error.name || 'Unknown Error';
665
+ if (error.message.includes('Vitest failed to access its internal state')) {
666
+ const tips = [
667
+ 'Error: not support import `vitest` in Rstest test environment.\n',
668
+ 'Solution:',
669
+ ` - Update your code to use imports from "${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.yellow('@rstest/core')}" instead of "${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.yellow('vitest')}".`,
670
+ ' - Enable `globals` configuration and use global API.'
671
+ ];
672
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(`${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(tips.join('\n'))}\n`);
673
+ return;
674
+ }
675
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(`${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(_utils__WEBPACK_IMPORTED_MODULE_3__.yW.bold(errorName))}${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(`: ${error.message}`)}\n`);
676
+ if (error.diff) {
677
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(error.diff);
678
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log();
679
+ }
680
+ if (error.stack) {
681
+ const stackFrames = await parseErrorStacktrace({
682
+ stack: error.stack,
683
+ fullStack: error.fullStack,
684
+ getSourcemap
685
+ });
686
+ if (!stackFrames.length && error.stack.length) _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(_utils__WEBPACK_IMPORTED_MODULE_3__.yW.gray("No error stack found, set 'DEBUG=rstest' to show fullStack."));
687
+ if (stackFrames[0]) await printCodeFrame(stackFrames[0]);
688
+ printStack(stackFrames, rootPath);
689
+ }
690
+ }
691
+ async function printCodeFrame(frame) {
692
+ const filePath = frame.file?.startsWith('file') ? new URL(frame.file) : frame.file;
693
+ if (!filePath) return;
694
+ const source = node_fs__WEBPACK_IMPORTED_MODULE_0__["default"].existsSync(filePath) ? node_fs__WEBPACK_IMPORTED_MODULE_0__["default"].readFileSync(filePath, 'utf-8') : void 0;
695
+ if (!source) return;
696
+ const { codeFrameColumns } = await __webpack_require__.e("171").then(__webpack_require__.bind(__webpack_require__, "../../node_modules/.pnpm/@babel+code-frame@7.27.1/node_modules/@babel/code-frame/lib/index.js"));
697
+ const result = codeFrameColumns(source, {
698
+ start: {
699
+ line: frame.lineNumber,
700
+ column: frame.column
701
+ }
702
+ }, {
703
+ highlightCode: true,
704
+ linesBelow: 2
705
+ });
706
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(result);
707
+ _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log('');
708
+ }
709
+ function formatStack(frame, rootPath) {
710
+ return '<unknown>' !== frame.methodName ? `at ${frame.methodName} (${(0, _utils__WEBPACK_IMPORTED_MODULE_3__.XJ)(rootPath, frame.file)}:${frame.lineNumber}:${frame.column})` : `at ${(0, _utils__WEBPACK_IMPORTED_MODULE_3__.XJ)(rootPath, frame.file)}:${frame.lineNumber}:${frame.column}`;
711
+ }
712
+ function printStack(stackFrames, rootPath) {
713
+ for (const frame of stackFrames)_utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(_utils__WEBPACK_IMPORTED_MODULE_3__.yW.gray(` ${formatStack(frame, rootPath)}`));
714
+ stackFrames.length && _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log();
715
+ }
716
+ const stackIgnores = [
717
+ /\/@rstest\/core/,
718
+ /rstest\/packages\/core\/dist/,
719
+ /node_modules\/tinypool/,
720
+ /node_modules\/chai/,
721
+ /node_modules\/@vitest\/expect/,
722
+ /node_modules\/@vitest\/snapshot/,
723
+ /node:\w+/,
724
+ /webpack\/runtime/,
725
+ /webpack\\runtime/,
726
+ '<anonymous>'
727
+ ];
728
+ async function parseErrorStacktrace({ stack, getSourcemap, fullStack = (0, _utils__WEBPACK_IMPORTED_MODULE_3__._o)() }) {
729
+ const stackFrames = await Promise.all((0, stacktrace_parser__WEBPACK_IMPORTED_MODULE_2__.q)(stack).filter((frame)=>fullStack ? true : frame.file && !stackIgnores.some((entry)=>frame.file?.match(entry))).map(async (frame)=>{
730
+ const sourcemap = getSourcemap(frame.file);
731
+ if (sourcemap) {
732
+ const traceMap = new _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__.YX(sourcemap);
733
+ const { line, column, source, name } = (0, _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__.sP)(traceMap, {
734
+ line: frame.lineNumber,
735
+ column: frame.column
736
+ });
737
+ if (!source) return null;
738
+ return {
739
+ ...frame,
740
+ file: source,
741
+ lineNumber: line,
742
+ name,
743
+ column
744
+ };
745
+ }
746
+ return frame;
747
+ })).then((frames)=>frames.filter((frame)=>null !== frame));
748
+ return stackFrames;
749
+ }
683
750
  }
684
751
  };
package/dist/33.js CHANGED
@@ -162,7 +162,8 @@ export const __webpack_modules__ = {
162
162
  include,
163
163
  exclude,
164
164
  includeSource,
165
- root,
165
+ rootPath,
166
+ projectRoot: root,
166
167
  fileFilters: context.fileFilters || []
167
168
  });
168
169
  entriesCache.set(name, {
@@ -180,7 +181,10 @@ export const __webpack_modules__ = {
180
181
  }));
181
182
  const rsbuildInstance = await (0, rsbuild.zh)(context, globTestSourceEntries, setupFiles);
182
183
  const { getRsbuildStats, closeServer } = await (0, rsbuild.XD)({
183
- normalizedConfig: context.normalizedConfig,
184
+ inspectedConfig: {
185
+ ...context.normalizedConfig,
186
+ projects: context.projects.map((p)=>p.normalizedConfig)
187
+ },
184
188
  globTestSourceEntries: 'watch' === command ? globTestSourceEntries : async (name)=>{
185
189
  if (entriesCache.has(name)) return entriesCache.get(name).entries;
186
190
  return globTestSourceEntries(name);
@@ -1,10 +1,103 @@
1
1
  import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
- export const __webpack_id__ = "829";
3
+ export const __webpack_id__ = "465";
4
4
  export const __webpack_ids__ = [
5
- "829"
5
+ "465"
6
6
  ];
7
7
  export const __webpack_modules__ = {
8
+ "../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
+ __webpack_require__.d(__webpack_exports__, {
10
+ q: ()=>parse
11
+ });
12
+ var UNKNOWN_FUNCTION = '<unknown>';
13
+ function parse(stackString) {
14
+ var lines = stackString.split('\n');
15
+ return lines.reduce(function(stack, line) {
16
+ var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
17
+ if (parseResult) stack.push(parseResult);
18
+ return stack;
19
+ }, []);
20
+ }
21
+ var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
22
+ var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
23
+ function parseChrome(line) {
24
+ var parts = chromeRe.exec(line);
25
+ if (!parts) return null;
26
+ var isNative = parts[2] && 0 === parts[2].indexOf('native');
27
+ var isEval = parts[2] && 0 === parts[2].indexOf('eval');
28
+ var submatch = chromeEvalRe.exec(parts[2]);
29
+ if (isEval && null != submatch) {
30
+ parts[2] = submatch[1];
31
+ parts[3] = submatch[2];
32
+ parts[4] = submatch[3];
33
+ }
34
+ return {
35
+ file: isNative ? null : parts[2],
36
+ methodName: parts[1] || UNKNOWN_FUNCTION,
37
+ arguments: isNative ? [
38
+ parts[2]
39
+ ] : [],
40
+ lineNumber: parts[3] ? +parts[3] : null,
41
+ column: parts[4] ? +parts[4] : null
42
+ };
43
+ }
44
+ var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
45
+ function parseWinjs(line) {
46
+ var parts = winjsRe.exec(line);
47
+ if (!parts) return null;
48
+ return {
49
+ file: parts[2],
50
+ methodName: parts[1] || UNKNOWN_FUNCTION,
51
+ arguments: [],
52
+ lineNumber: +parts[3],
53
+ column: parts[4] ? +parts[4] : null
54
+ };
55
+ }
56
+ var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
57
+ var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
58
+ function parseGecko(line) {
59
+ var parts = geckoRe.exec(line);
60
+ if (!parts) return null;
61
+ var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
62
+ var submatch = geckoEvalRe.exec(parts[3]);
63
+ if (isEval && null != submatch) {
64
+ parts[3] = submatch[1];
65
+ parts[4] = submatch[2];
66
+ parts[5] = null;
67
+ }
68
+ return {
69
+ file: parts[3],
70
+ methodName: parts[1] || UNKNOWN_FUNCTION,
71
+ arguments: parts[2] ? parts[2].split(',') : [],
72
+ lineNumber: parts[4] ? +parts[4] : null,
73
+ column: parts[5] ? +parts[5] : null
74
+ };
75
+ }
76
+ var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
77
+ function parseJSC(line) {
78
+ var parts = javaScriptCoreRe.exec(line);
79
+ if (!parts) return null;
80
+ return {
81
+ file: parts[3],
82
+ methodName: parts[1] || UNKNOWN_FUNCTION,
83
+ arguments: [],
84
+ lineNumber: +parts[4],
85
+ column: parts[5] ? +parts[5] : null
86
+ };
87
+ }
88
+ var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
89
+ function parseNode(line) {
90
+ var parts = nodeRe.exec(line);
91
+ if (!parts) return null;
92
+ return {
93
+ file: parts[2],
94
+ methodName: parts[1] || UNKNOWN_FUNCTION,
95
+ arguments: [],
96
+ lineNumber: +parts[3],
97
+ column: parts[4] ? +parts[4] : null
98
+ };
99
+ }
100
+ },
8
101
  "../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.30/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs": function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
9
102
  __webpack_require__.d(__webpack_exports__, {
10
103
  YX: ()=>TraceMap,
@@ -414,5 +507,86 @@ export const __webpack_modules__ = {
414
507
  if (-1 === index || index === segments.length) return -1;
415
508
  return index;
416
509
  }
510
+ },
511
+ "../../node_modules/.pnpm/@vitest+snapshot@3.2.4/node_modules/@vitest/snapshot/dist/manager.js": function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
512
+ __webpack_require__.d(__webpack_exports__, {
513
+ CW: ()=>SnapshotManager
514
+ });
515
+ var pathe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("pathe");
516
+ class SnapshotManager {
517
+ summary;
518
+ extension = ".snap";
519
+ constructor(options){
520
+ this.options = options;
521
+ this.clear();
522
+ }
523
+ clear() {
524
+ this.summary = emptySummary(this.options);
525
+ }
526
+ add(result) {
527
+ addSnapshotResult(this.summary, result);
528
+ }
529
+ resolvePath(testPath, context) {
530
+ const resolver = this.options.resolveSnapshotPath || (()=>(0, pathe__WEBPACK_IMPORTED_MODULE_0__.join)((0, pathe__WEBPACK_IMPORTED_MODULE_0__.join)((0, pathe__WEBPACK_IMPORTED_MODULE_0__.dirname)(testPath), "__snapshots__"), `${(0, pathe__WEBPACK_IMPORTED_MODULE_0__.basename)(testPath)}${this.extension}`));
531
+ const path = resolver(testPath, this.extension, context);
532
+ return path;
533
+ }
534
+ resolveRawPath(testPath, rawPath) {
535
+ return (0, pathe__WEBPACK_IMPORTED_MODULE_0__.isAbsolute)(rawPath) ? rawPath : (0, pathe__WEBPACK_IMPORTED_MODULE_0__.resolve)((0, pathe__WEBPACK_IMPORTED_MODULE_0__.dirname)(testPath), rawPath);
536
+ }
537
+ }
538
+ function emptySummary(options) {
539
+ const summary = {
540
+ added: 0,
541
+ failure: false,
542
+ filesAdded: 0,
543
+ filesRemoved: 0,
544
+ filesRemovedList: [],
545
+ filesUnmatched: 0,
546
+ filesUpdated: 0,
547
+ matched: 0,
548
+ total: 0,
549
+ unchecked: 0,
550
+ uncheckedKeysByFile: [],
551
+ unmatched: 0,
552
+ updated: 0,
553
+ didUpdate: "all" === options.updateSnapshot
554
+ };
555
+ return summary;
556
+ }
557
+ function addSnapshotResult(summary, result) {
558
+ if (result.added) summary.filesAdded++;
559
+ if (result.fileDeleted) summary.filesRemoved++;
560
+ if (result.unmatched) summary.filesUnmatched++;
561
+ if (result.updated) summary.filesUpdated++;
562
+ summary.added += result.added;
563
+ summary.matched += result.matched;
564
+ summary.unchecked += result.unchecked;
565
+ if (result.uncheckedKeys && result.uncheckedKeys.length > 0) summary.uncheckedKeysByFile.push({
566
+ filePath: result.filepath,
567
+ keys: result.uncheckedKeys
568
+ });
569
+ summary.unmatched += result.unmatched;
570
+ summary.updated += result.updated;
571
+ summary.total += result.added + result.matched + result.unmatched + result.updated;
572
+ }
573
+ },
574
+ "../../node_modules/.pnpm/strip-ansi@7.1.0/node_modules/strip-ansi/index.js": function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
575
+ __webpack_require__.d(__webpack_exports__, {
576
+ A: ()=>stripAnsi
577
+ });
578
+ function ansiRegex({ onlyFirst = false } = {}) {
579
+ const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
580
+ const pattern = [
581
+ `[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
582
+ '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))'
583
+ ].join('|');
584
+ return new RegExp(pattern, onlyFirst ? void 0 : 'g');
585
+ }
586
+ const regex = ansiRegex();
587
+ function stripAnsi(string) {
588
+ if ('string' != typeof string) throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
589
+ return string.replace(regex, '');
590
+ }
417
591
  }
418
592
  };
package/dist/971.js CHANGED
@@ -23,7 +23,8 @@ export const __webpack_modules__ = {
23
23
  const entries = await (0, _utils__WEBPACK_IMPORTED_MODULE_3__.tG)({
24
24
  include,
25
25
  exclude,
26
- root,
26
+ rootPath,
27
+ projectRoot: root,
27
28
  fileFilters: context.fileFilters || [],
28
29
  includeSource
29
30
  });
@@ -40,7 +41,10 @@ export const __webpack_modules__ = {
40
41
  const rsbuildInstance = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.zh)(context, globTestSourceEntries, setupFiles);
41
42
  const { getRsbuildStats, closeServer } = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.XD)({
42
43
  globTestSourceEntries,
43
- normalizedConfig: context.normalizedConfig,
44
+ inspectedConfig: {
45
+ ...context.normalizedConfig,
46
+ projects: context.projects.map((p)=>p.normalizedConfig)
47
+ },
44
48
  setupFiles,
45
49
  rsbuildInstance,
46
50
  rootPath
@@ -88,10 +92,7 @@ export const __webpack_modules__ = {
88
92
  const hasError = list.some((file)=>file.errors?.length);
89
93
  const showProject = context.projects.length > 1;
90
94
  if (hasError) {
91
- const { printError } = await Promise.all([
92
- __webpack_require__.e("829"),
93
- __webpack_require__.e("704")
94
- ]).then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
95
+ const { printError } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
95
96
  process.exitCode = 1;
96
97
  for (const file of list){
97
98
  const relativePath = (0, node_path__WEBPACK_IMPORTED_MODULE_1__.relative)(rootPath, file.testPath);
package/dist/985.js CHANGED
@@ -544,7 +544,7 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
544
544
  deletedEntries
545
545
  };
546
546
  };
547
- const createRsbuildServer = async ({ globTestSourceEntries, setupFiles, rsbuildInstance, normalizedConfig })=>{
547
+ const createRsbuildServer = async ({ globTestSourceEntries, setupFiles, rsbuildInstance, inspectedConfig })=>{
548
548
  let rspackCompiler;
549
549
  const rstestCompilerPlugin = {
550
550
  name: 'rstest:compiler',
@@ -563,7 +563,7 @@ global.__rstest_clean_core_cache__ = __rstest_clean_core_cache__;
563
563
  if ((0, utils._o)()) await rsbuildInstance.inspectConfig({
564
564
  writeToDisk: true,
565
565
  extraConfigs: {
566
- rstest: normalizedConfig
566
+ rstest: inspectedConfig
567
567
  }
568
568
  });
569
569
  if (!rspackCompiler) throw new Error('rspackCompiler was not initialized');
package/dist/index.js CHANGED
@@ -2677,14 +2677,17 @@ ${section.body}` : section.body).join("\n\n"));
2677
2677
  const applyCommonOptions = (cli)=>{
2678
2678
  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`', {
2679
2679
  default: 'jiti'
2680
- }).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('--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('--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('--retry <retry>', 'Number of times to retry a test if it fails').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');
2680
+ }).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('--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('--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('--retry <retry>', 'Number of times to retry a test if it fails').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');
2681
2681
  };
2682
2682
  const runRest = async ({ options, filters, command })=>{
2683
2683
  let rstest;
2684
2684
  try {
2685
2685
  const { initCli } = await __webpack_require__.e("223").then(__webpack_require__.bind(__webpack_require__, "./src/cli/init.ts"));
2686
2686
  const { config, configFilePath, projects } = await initCli(options);
2687
- const { createRstest } = await __webpack_require__.e("12").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2687
+ const { createRstest } = await Promise.all([
2688
+ __webpack_require__.e("465"),
2689
+ __webpack_require__.e("263")
2690
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2688
2691
  rstest = createRstest({
2689
2692
  config,
2690
2693
  configFilePath,
@@ -2709,7 +2712,7 @@ ${section.body}` : section.body).join("\n\n"));
2709
2712
  function setupCommands() {
2710
2713
  const cli = dist('rstest');
2711
2714
  cli.help();
2712
- cli.version("0.3.0");
2715
+ cli.version("0.3.2");
2713
2716
  applyCommonOptions(cli);
2714
2717
  cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
2715
2718
  (0, prepare.N)();
@@ -2744,7 +2747,10 @@ ${section.body}` : section.body).join("\n\n"));
2744
2747
  try {
2745
2748
  const { initCli } = await __webpack_require__.e("223").then(__webpack_require__.bind(__webpack_require__, "./src/cli/init.ts"));
2746
2749
  const { config, configFilePath, projects } = await initCli(options);
2747
- const { createRstest } = await __webpack_require__.e("12").then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2750
+ const { createRstest } = await Promise.all([
2751
+ __webpack_require__.e("465"),
2752
+ __webpack_require__.e("263")
2753
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/core/index.ts"));
2748
2754
  const rstest = createRstest({
2749
2755
  config,
2750
2756
  configFilePath,
@@ -2779,7 +2785,7 @@ ${section.body}` : section.body).join("\n\n"));
2779
2785
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
2780
2786
  }
2781
2787
  function showRstest() {
2782
- _utils_logger__WEBPACK_IMPORTED_MODULE_0__.vF.greet(" Rstest v0.3.0");
2788
+ _utils_logger__WEBPACK_IMPORTED_MODULE_0__.vF.greet(" Rstest v0.3.2");
2783
2789
  _utils_logger__WEBPACK_IMPORTED_MODULE_0__.vF.log('');
2784
2790
  }
2785
2791
  },
@@ -3070,6 +3076,7 @@ ${section.body}` : section.body).join("\n\n"));
3070
3076
  _o: ()=>logger._o,
3071
3077
  pr: ()=>getSetupFiles,
3072
3078
  Kv: ()=>helper.Kv,
3079
+ zz: ()=>filterProjects,
3073
3080
  mT: ()=>logger.mT,
3074
3081
  t: ()=>constants.t,
3075
3082
  kV: ()=>helper.kV,
@@ -3097,11 +3104,22 @@ ${section.body}` : section.body).join("\n\n"));
3097
3104
  });
3098
3105
  });
3099
3106
  };
3107
+ const filterProjects = (projects, options)=>{
3108
+ if (options.project) {
3109
+ const regexes = (0, helper.bg)(options.project).map((pattern)=>{
3110
+ const isNeg = pattern.startsWith('!');
3111
+ const escaped = (isNeg ? pattern.slice(1) : pattern).split('*').map((part)=>part.replace(/[.+?^${}()|[\]\\]/g, '\\$&')).join('.*');
3112
+ return new RegExp(isNeg ? `^(?!${escaped})` : `^${escaped}$`);
3113
+ });
3114
+ return projects.filter((proj)=>regexes.some((re)=>re.test(proj.config.name)));
3115
+ }
3116
+ return projects;
3117
+ };
3100
3118
  const hasInSourceTestCode = (code)=>code.includes('import.meta.rstest');
3101
3119
  const formatTestEntryName = (name)=>name.replace(/\.*[/\\]/g, '_').replace(/\./g, '~');
3102
- const getTestEntries = async ({ include, exclude, root, fileFilters, includeSource })=>{
3120
+ const getTestEntries = async ({ include, exclude, rootPath, projectRoot, fileFilters, includeSource })=>{
3103
3121
  const testFiles = await (0, dist.glob)(include, {
3104
- cwd: root,
3122
+ cwd: projectRoot,
3105
3123
  absolute: true,
3106
3124
  ignore: exclude,
3107
3125
  dot: true,
@@ -3109,7 +3127,7 @@ ${section.body}` : section.body).join("\n\n"));
3109
3127
  });
3110
3128
  if (includeSource?.length) {
3111
3129
  const sourceFiles = await (0, dist.glob)(includeSource, {
3112
- cwd: root,
3130
+ cwd: projectRoot,
3113
3131
  absolute: true,
3114
3132
  ignore: exclude,
3115
3133
  dot: true,
@@ -3124,8 +3142,8 @@ ${section.body}` : section.body).join("\n\n"));
3124
3142
  }
3125
3143
  }));
3126
3144
  }
3127
- return Object.fromEntries(filterFiles(testFiles, fileFilters, root).map((entry)=>{
3128
- const relativePath = external_pathe_["default"].relative(root, entry);
3145
+ return Object.fromEntries(filterFiles(testFiles, fileFilters, rootPath).map((entry)=>{
3146
+ const relativePath = external_pathe_["default"].relative(rootPath, entry);
3129
3147
  return [
3130
3148
  formatTestEntryName(relativePath),
3131
3149
  entry
@@ -1062,6 +1062,28 @@ declare interface JestAssertion<T = any> extends jest.Matchers<void, T>, CustomM
1062
1062
  nthReturnedWith: <E>(nthCall: number, value: E) => void;
1063
1063
  }
1064
1064
 
1065
+ declare class JUnitReporter implements Reporter {
1066
+ private rootPath;
1067
+ private outputPath?;
1068
+ constructor({ rootPath, options: { outputPath }, }: {
1069
+ rootPath: string;
1070
+ options?: {
1071
+ outputPath?: string;
1072
+ };
1073
+ });
1074
+ private sanitizeXml;
1075
+ private escapeXml;
1076
+ private createJUnitTestCase;
1077
+ private createJUnitTestSuite;
1078
+ private generateJUnitXml;
1079
+ onTestRunEnd({ results, testResults, duration, getSourcemap, }: {
1080
+ getSourcemap: GetSourcemap;
1081
+ results: TestFileResult[];
1082
+ testResults: TestResult[];
1083
+ duration: Duration;
1084
+ }): Promise<void>;
1085
+ }
1086
+
1065
1087
  declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
1066
1088
 
1067
1089
  declare interface MatcherHintOptions {
@@ -1577,6 +1599,10 @@ declare type NormalizedProcedure<T extends Procedure> = (...args: Parameters<T>)
1577
1599
 
1578
1600
  declare type NormalizedProcedure_2<T extends Procedure_2> = (...args: Parameters<T>) => ReturnType<T>;
1579
1601
 
1602
+ declare type NormalizedProjectConfig = Required<Omit<RstestConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1603
+ [key in OptionalKeys]?: RstestConfig[key];
1604
+ };
1605
+
1580
1606
  declare interface OldPlugin {
1581
1607
  print: (val: unknown, print: Print, indent: Indent, options: PluginOptions, colors: Colors) => string;
1582
1608
  test: Test;
@@ -1650,12 +1676,14 @@ declare type Procedure = (...args: any[]) => any;
1650
1676
 
1651
1677
  declare type Procedure_2 = (...args: any[]) => any;
1652
1678
 
1679
+ export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate'>;
1680
+
1653
1681
  declare type ProjectContext = {
1654
1682
  name: string;
1655
1683
  environmentName: string;
1656
1684
  rootPath: string;
1657
1685
  configFilePath?: string;
1658
- normalizedConfig: NormalizedConfig;
1686
+ normalizedConfig: NormalizedProjectConfig;
1659
1687
  };
1660
1688
 
1661
1689
  declare type Promisify<O> = { [K in keyof O] : O[K] extends (...args: infer A) => infer R ? Promisify<O[K]> & ((...args: A) => Promise<R>) : O[K] };
@@ -1721,6 +1749,7 @@ declare const reportersMap: {
1721
1749
  default: typeof DefaultReporter;
1722
1750
  verbose: typeof VerboseReporter;
1723
1751
  'github-actions': typeof GithubActionsReporter;
1752
+ junit: typeof JUnitReporter;
1724
1753
  };
1725
1754
 
1726
1755
  declare type ReporterWithOptions<Name extends BuiltInReporterNames = BuiltInReporterNames> = Name extends keyof BuiltinReporterOptions ? [Name, Partial<BuiltinReporterOptions[Name]>] : [Name, Record<string, unknown>];
@@ -2353,7 +2382,7 @@ declare type TestPath = string;
2353
2382
  *
2354
2383
  * eg. ['packages/*', 'examples/node/rstest.config.ts']
2355
2384
  */
2356
- declare type TestProject = string;
2385
+ declare type TestProject = string | ProjectConfig;
2357
2386
 
2358
2387
  export declare type TestResult = {
2359
2388
  status: TestResultStatus;
@@ -985,6 +985,28 @@ declare interface JestAssertion<T = any> extends jest.Matchers<void, T>, CustomM
985
985
  nthReturnedWith: <E>(nthCall: number, value: E) => void;
986
986
  }
987
987
 
988
+ declare class JUnitReporter implements Reporter {
989
+ private rootPath;
990
+ private outputPath?;
991
+ constructor({ rootPath, options: { outputPath }, }: {
992
+ rootPath: string;
993
+ options?: {
994
+ outputPath?: string;
995
+ };
996
+ });
997
+ private sanitizeXml;
998
+ private escapeXml;
999
+ private createJUnitTestCase;
1000
+ private createJUnitTestSuite;
1001
+ private generateJUnitXml;
1002
+ onTestRunEnd({ results, testResults, duration, getSourcemap, }: {
1003
+ getSourcemap: GetSourcemap;
1004
+ results: TestFileResult[];
1005
+ testResults: TestResult[];
1006
+ duration: Duration;
1007
+ }): Promise<void>;
1008
+ }
1009
+
988
1010
  declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
989
1011
 
990
1012
  declare interface MatcherHintOptions {
@@ -1358,6 +1380,10 @@ declare type NormalizedFixtures = Record<string, NormalizedFixture>;
1358
1380
 
1359
1381
  declare type NormalizedProcedure<T extends Procedure> = (...args: Parameters<T>) => ReturnType<T>;
1360
1382
 
1383
+ declare type NormalizedProjectConfig = Required<Omit<RstestConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1384
+ [key in OptionalKeys]?: RstestConfig[key];
1385
+ };
1386
+
1361
1387
  declare interface OldPlugin {
1362
1388
  print: (val: unknown, print: Print, indent: Indent, options: PluginOptions, colors: Colors) => string;
1363
1389
  test: Test;
@@ -1425,12 +1451,14 @@ declare function printWithType<T>(name: string, value: T, print: (value: T) => s
1425
1451
 
1426
1452
  declare type Procedure = (...args: any[]) => any;
1427
1453
 
1454
+ declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate'>;
1455
+
1428
1456
  declare type ProjectContext = {
1429
1457
  name: string;
1430
1458
  environmentName: string;
1431
1459
  rootPath: string;
1432
1460
  configFilePath?: string;
1433
- normalizedConfig: NormalizedConfig;
1461
+ normalizedConfig: NormalizedProjectConfig;
1434
1462
  };
1435
1463
 
1436
1464
  declare type Promisify<O> = { [K in keyof O] : O[K] extends (...args: infer A) => infer R ? Promisify<O[K]> & ((...args: A) => Promise<R>) : O[K] };
@@ -1496,6 +1524,7 @@ declare const reportersMap: {
1496
1524
  default: typeof DefaultReporter;
1497
1525
  verbose: typeof VerboseReporter;
1498
1526
  'github-actions': typeof GithubActionsReporter;
1527
+ junit: typeof JUnitReporter;
1499
1528
  };
1500
1529
 
1501
1530
  declare type ReporterWithOptions<Name extends BuiltInReporterNames = BuiltInReporterNames> = Name extends keyof BuiltinReporterOptions ? [Name, Partial<BuiltinReporterOptions[Name]>] : [Name, Record<string, unknown>];
@@ -2057,7 +2086,7 @@ declare type TestPath = string;
2057
2086
  *
2058
2087
  * eg. ['packages/*', 'examples/node/rstest.config.ts']
2059
2088
  */
2060
- declare type TestProject = string;
2089
+ declare type TestProject = string | ProjectConfig;
2061
2090
 
2062
2091
  declare type TestResult = {
2063
2092
  status: TestResultStatus;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/core",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "The Rsbuild-based test tool.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/web-infra-dev/rstest/issues"
@@ -74,6 +74,7 @@
74
74
  "rslog": "^1.2.11",
75
75
  "source-map-support": "^0.5.21",
76
76
  "stacktrace-parser": "0.1.11",
77
+ "strip-ansi": "^7.1.0",
77
78
  "tinyglobby": "^0.2.14",
78
79
  "tinyspy": "^4.0.3",
79
80
  "@rstest/tsconfig": "0.0.1"
package/dist/704.js DELETED
@@ -1,103 +0,0 @@
1
- import 'module';
2
- /*#__PURE__*/ import.meta.url;
3
- export const __webpack_id__ = "704";
4
- export const __webpack_ids__ = [
5
- "704"
6
- ];
7
- export const __webpack_modules__ = {
8
- "./src/utils/error.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
9
- __webpack_require__.d(__webpack_exports__, {
10
- parseErrorStacktrace: ()=>parseErrorStacktrace,
11
- printError: ()=>printError
12
- });
13
- var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:fs");
14
- var _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.30/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs");
15
- var stacktrace_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js");
16
- var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/utils/index.ts");
17
- async function printError(error, getSourcemap, rootPath) {
18
- const errorName = error.name || 'Unknown Error';
19
- if (error.message.includes('Vitest failed to access its internal state')) {
20
- const tips = [
21
- 'Error: not support import `vitest` in Rstest test environment.\n',
22
- 'Solution:',
23
- ` - Update your code to use imports from "${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.yellow('@rstest/core')}" instead of "${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.yellow('vitest')}".`,
24
- ' - Enable `globals` configuration and use global API.'
25
- ];
26
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(`${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(tips.join('\n'))}\n`);
27
- return;
28
- }
29
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(`${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(_utils__WEBPACK_IMPORTED_MODULE_3__.yW.bold(errorName))}${_utils__WEBPACK_IMPORTED_MODULE_3__.yW.red(`: ${error.message}`)}\n`);
30
- if (error.diff) {
31
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(error.diff);
32
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log();
33
- }
34
- if (error.stack) {
35
- const stackFrames = await parseErrorStacktrace({
36
- stack: error.stack,
37
- fullStack: error.fullStack,
38
- getSourcemap
39
- });
40
- if (stackFrames[0]) await printCodeFrame(stackFrames[0]);
41
- printStack(stackFrames, rootPath);
42
- }
43
- }
44
- async function printCodeFrame(frame) {
45
- const filePath = frame.file?.startsWith('file') ? new URL(frame.file) : frame.file;
46
- if (!filePath) return;
47
- const source = node_fs__WEBPACK_IMPORTED_MODULE_0__["default"].existsSync(filePath) ? node_fs__WEBPACK_IMPORTED_MODULE_0__["default"].readFileSync(filePath, 'utf-8') : void 0;
48
- if (!source) return;
49
- const { codeFrameColumns } = await __webpack_require__.e("171").then(__webpack_require__.bind(__webpack_require__, "../../node_modules/.pnpm/@babel+code-frame@7.27.1/node_modules/@babel/code-frame/lib/index.js"));
50
- const result = codeFrameColumns(source, {
51
- start: {
52
- line: frame.lineNumber,
53
- column: frame.column
54
- }
55
- }, {
56
- highlightCode: true,
57
- linesBelow: 2
58
- });
59
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(result);
60
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log('');
61
- }
62
- function printStack(stackFrames, rootPath) {
63
- for (const frame of stackFrames){
64
- const msg = '<unknown>' !== frame.methodName ? `at ${frame.methodName} (${(0, _utils__WEBPACK_IMPORTED_MODULE_3__.XJ)(rootPath, frame.file)}:${frame.lineNumber}:${frame.column})` : `at ${(0, _utils__WEBPACK_IMPORTED_MODULE_3__.XJ)(rootPath, frame.file)}:${frame.lineNumber}:${frame.column}`;
65
- _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log(_utils__WEBPACK_IMPORTED_MODULE_3__.yW.gray(` ${msg}`));
66
- }
67
- stackFrames.length && _utils__WEBPACK_IMPORTED_MODULE_3__.vF.log();
68
- }
69
- const stackIgnores = [
70
- /\/@rstest\/core/,
71
- /rstest\/packages\/core\/dist/,
72
- /node_modules\/tinypool/,
73
- /node_modules\/chai/,
74
- /node_modules\/@vitest\/expect/,
75
- /node_modules\/@vitest\/snapshot/,
76
- /node:\w+/,
77
- /webpack\/runtime/,
78
- /webpack\\runtime/,
79
- '<anonymous>'
80
- ];
81
- async function parseErrorStacktrace({ stack, getSourcemap, fullStack }) {
82
- return Promise.all((0, stacktrace_parser__WEBPACK_IMPORTED_MODULE_2__.q)(stack).filter((frame)=>fullStack ? true : frame.file && !stackIgnores.some((entry)=>frame.file?.match(entry))).map(async (frame)=>{
83
- const sourcemap = getSourcemap(frame.file);
84
- if (sourcemap) {
85
- const traceMap = new _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__.YX(sourcemap);
86
- const { line, column, source, name } = (0, _jridgewell_trace_mapping__WEBPACK_IMPORTED_MODULE_1__.sP)(traceMap, {
87
- line: frame.lineNumber,
88
- column: frame.column
89
- });
90
- if (!source) return null;
91
- return {
92
- ...frame,
93
- file: source,
94
- lineNumber: line,
95
- name,
96
- column
97
- };
98
- }
99
- return frame;
100
- })).then((frames)=>frames.filter((frame)=>null !== frame));
101
- }
102
- }
103
- };