@rstest/core 0.7.1 → 0.7.3

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/0~923.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
3
  import { __webpack_require__ } from "./rslib-runtime.js";
4
- import { posix, src_logger } from "./946.js";
5
- import { pathToFileURL } from "./770.js";
4
+ import { posix, logger_logger } from "./946.js";
5
+ import { pathToFileURL } from "./404.js";
6
6
  import { node_vm, interopModule, shouldInterop } from "./0~346.js";
7
- const external_node_path_ = __webpack_require__("node:path");
7
+ const external_node_path_ = __webpack_require__("path");
8
8
  var loadEsModule_EsmMode = /*#__PURE__*/ function(EsmMode) {
9
9
  EsmMode[EsmMode["Unknown"] = 0] = "Unknown";
10
10
  EsmMode[EsmMode["Evaluated"] = 1] = "Evaluated";
@@ -27,7 +27,7 @@ const defineRstestDynamicImport = ({ distPath, testPath, assetFiles, interopDefa
27
27
  esmMode
28
28
  });
29
29
  } catch (err) {
30
- src_logger.error(`load file ${joinedPath} failed:\n`, err instanceof Error ? err.message : err);
30
+ logger_logger.error(`load file ${joinedPath} failed:\n`, err instanceof Error ? err.message : err);
31
31
  }
32
32
  const resolvedPath = (0, external_node_path_.isAbsolute)(specifier) ? pathToFileURL(specifier) : import.meta.resolve(specifier, pathToFileURL(testPath));
33
33
  const modulePath = 'string' == typeof resolvedPath ? resolvedPath : resolvedPath.pathname;
@@ -2,8 +2,9 @@ import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
3
  import { __webpack_require__ } from "./rslib-runtime.js";
4
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";
5
+ import { createRsbuild, loadConfig, logger as core_logger, mergeRsbuildConfig } from "@rsbuild/core";
6
+ import { DEFAULT_CONFIG_NAME, posix, globalApis, resolve as pathe_M_eThtNZ_resolve, pathe_M_eThtNZ_relative, filterProjects, join, glob, prettyTestPath, prettyTime, isAbsolute, TEMP_RSTEST_OUTPUT_DIR_GLOB, formatTestPath, TS_CONFIG_FILE, basename, logger_logger, dirname, isTTY, getAbsolutePath, bgColor, formatRootStr, isDynamicPattern, writeFile, castArray, isDebug, getTaskNameWithPrefix, DEFAULT_CONFIG_EXTENSIONS, formatError, normalize } from "./946.js";
7
+ import { parse as stack_trace_parser_esm_parse } from "./672.js";
7
8
  import { decode } from "./397.js";
8
9
  function toArr(any) {
9
10
  return null == any ? [] : Array.isArray(any) ? any : [
@@ -497,16 +498,16 @@ function prepareCli() {
497
498
  initNodeEnv();
498
499
  process.env.RSTEST = 'true';
499
500
  const { npm_execpath } = process.env;
500
- if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) console.log();
501
+ if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) logger_logger.log();
501
502
  }
502
503
  function showRstest() {
503
- src_logger.greet(" Rstest v0.7.1");
504
- src_logger.log('');
504
+ logger_logger.greet(" Rstest v0.7.3");
505
+ logger_logger.log('');
505
506
  }
506
507
  const applyCommonOptions = (cli)=>{
507
508
  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
509
  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
+ }).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').option('--includeTaskLocation', 'Collect test and suite locations. This might increase the running time.');
510
511
  };
511
512
  const runRest = async ({ options, filters, command })=>{
512
513
  let rstest;
@@ -536,15 +537,15 @@ const runRest = async ({ options, filters, command })=>{
536
537
  await rstest.runTests();
537
538
  } catch (err) {
538
539
  for (const reporter of rstest?.context.reporters || [])reporter.onExit?.();
539
- src_logger.error('Failed to run Rstest.');
540
- src_logger.error(formatError(err));
540
+ logger_logger.error('Failed to run Rstest.');
541
+ logger_logger.error(formatError(err));
541
542
  process.exit(1);
542
543
  }
543
544
  };
544
545
  function setupCommands() {
545
546
  const cli = dist('rstest');
546
547
  cli.help();
547
- cli.version("0.7.1");
548
+ cli.version("0.7.3");
548
549
  applyCommonOptions(cli);
549
550
  cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
550
551
  showRstest();
@@ -575,12 +576,13 @@ function setupCommands() {
575
576
  command: 'watch'
576
577
  });
577
578
  });
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
+ 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').option('--includeSuites', 'include suites in output').option('--printLocation', 'print test case location').action(async (filters, options)=>{
579
580
  try {
580
581
  const { initCli } = await Promise.resolve().then(()=>({
581
582
  initCli: init_initCli
582
583
  }));
583
584
  const { config, configFilePath, projects } = await initCli(options);
585
+ if (options.printLocation) config.includeTaskLocation = true;
584
586
  const { createRstest } = await Promise.resolve().then(()=>({
585
587
  createRstest: core_createRstest
586
588
  }));
@@ -591,11 +593,13 @@ function setupCommands() {
591
593
  }, 'list', filters.map(normalize));
592
594
  await rstest.listTests({
593
595
  filesOnly: options.filesOnly,
594
- json: options.json
596
+ json: options.json,
597
+ includeSuites: options.includeSuites,
598
+ printLocation: options.printLocation
595
599
  });
596
600
  } catch (err) {
597
- src_logger.error('Failed to run Rstest list.');
598
- src_logger.error(formatError(err));
601
+ logger_logger.error('Failed to run Rstest list.');
602
+ logger_logger.error(formatError(err));
599
603
  process.exit(1);
600
604
  }
601
605
  });
@@ -618,7 +622,7 @@ const resolveConfigPath = (root, customConfig)=>{
618
622
  async function config_loadConfig({ cwd = process.cwd(), path, envMode, configLoader }) {
619
623
  const configFilePath = resolveConfigPath(cwd, path);
620
624
  if (!configFilePath) {
621
- src_logger.debug('no rstest config file found');
625
+ logger_logger.debug('no rstest config file found');
622
626
  return {
623
627
  content: {},
624
628
  filePath: configFilePath
@@ -698,6 +702,7 @@ const createDefaultConfig = ()=>({
698
702
  hideSkippedTests: false,
699
703
  logHeapUsage: false,
700
704
  bail: 0,
705
+ includeTaskLocation: false,
701
706
  coverage: {
702
707
  exclude: [
703
708
  '**/node_modules/**',
@@ -909,8 +914,8 @@ async function runCLI() {
909
914
  try {
910
915
  setupCommands();
911
916
  } catch (err) {
912
- src_logger.error('Failed to start Rstest CLI.');
913
- src_logger.error(err);
917
+ logger_logger.error('Failed to start Rstest CLI.');
918
+ logger_logger.error(err);
914
919
  }
915
920
  }
916
921
  class SnapshotManager {
@@ -1293,94 +1298,6 @@ function G() {
1293
1298
  }
1294
1299
  const P = G();
1295
1300
  P?.name;
1296
- var UNKNOWN_FUNCTION = '<unknown>';
1297
- function stack_trace_parser_esm_parse(stackString) {
1298
- var lines = stackString.split('\n');
1299
- return lines.reduce(function(stack, line) {
1300
- var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
1301
- if (parseResult) stack.push(parseResult);
1302
- return stack;
1303
- }, []);
1304
- }
1305
- var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
1306
- var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
1307
- function parseChrome(line) {
1308
- var parts = chromeRe.exec(line);
1309
- if (!parts) return null;
1310
- var isNative = parts[2] && 0 === parts[2].indexOf('native');
1311
- var isEval = parts[2] && 0 === parts[2].indexOf('eval');
1312
- var submatch = chromeEvalRe.exec(parts[2]);
1313
- if (isEval && null != submatch) {
1314
- parts[2] = submatch[1];
1315
- parts[3] = submatch[2];
1316
- parts[4] = submatch[3];
1317
- }
1318
- return {
1319
- file: isNative ? null : parts[2],
1320
- methodName: parts[1] || UNKNOWN_FUNCTION,
1321
- arguments: isNative ? [
1322
- parts[2]
1323
- ] : [],
1324
- lineNumber: parts[3] ? +parts[3] : null,
1325
- column: parts[4] ? +parts[4] : null
1326
- };
1327
- }
1328
- var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1329
- function parseWinjs(line) {
1330
- var parts = winjsRe.exec(line);
1331
- if (!parts) return null;
1332
- return {
1333
- file: parts[2],
1334
- methodName: parts[1] || UNKNOWN_FUNCTION,
1335
- arguments: [],
1336
- lineNumber: +parts[3],
1337
- column: parts[4] ? +parts[4] : null
1338
- };
1339
- }
1340
- var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
1341
- var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
1342
- function parseGecko(line) {
1343
- var parts = geckoRe.exec(line);
1344
- if (!parts) return null;
1345
- var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
1346
- var submatch = geckoEvalRe.exec(parts[3]);
1347
- if (isEval && null != submatch) {
1348
- parts[3] = submatch[1];
1349
- parts[4] = submatch[2];
1350
- parts[5] = null;
1351
- }
1352
- return {
1353
- file: parts[3],
1354
- methodName: parts[1] || UNKNOWN_FUNCTION,
1355
- arguments: parts[2] ? parts[2].split(',') : [],
1356
- lineNumber: parts[4] ? +parts[4] : null,
1357
- column: parts[5] ? +parts[5] : null
1358
- };
1359
- }
1360
- var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
1361
- function parseJSC(line) {
1362
- var parts = javaScriptCoreRe.exec(line);
1363
- if (!parts) return null;
1364
- return {
1365
- file: parts[3],
1366
- methodName: parts[1] || UNKNOWN_FUNCTION,
1367
- arguments: [],
1368
- lineNumber: +parts[4],
1369
- column: parts[5] ? +parts[5] : null
1370
- };
1371
- }
1372
- var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1373
- function parseNode(line) {
1374
- var parts = nodeRe.exec(line);
1375
- if (!parts) return null;
1376
- return {
1377
- file: parts[2],
1378
- methodName: parts[1] || UNKNOWN_FUNCTION,
1379
- arguments: [],
1380
- lineNumber: +parts[3],
1381
- column: parts[4] ? +parts[4] : null
1382
- };
1383
- }
1384
1301
  const getSummaryStatusString = (tasks, name = 'tests', showTotal = true)=>{
1385
1302
  if (0 === tasks.length) return picocolors_default().dim(`no ${name}`);
1386
1303
  const passed = tasks.filter((result)=>'pass' === result.status);
@@ -1417,19 +1334,19 @@ const printSnapshotSummaryLog = (snapshots, rootDir)=>{
1417
1334
  }
1418
1335
  for (const [index, snapshot] of summary.entries()){
1419
1336
  const title = 0 === index ? 'Snapshots' : '';
1420
- src_logger.log(`${picocolors_default().gray(title.padStart(12))} ${snapshot}`);
1337
+ logger_logger.log(`${picocolors_default().gray(title.padStart(12))} ${snapshot}`);
1421
1338
  }
1422
1339
  };
1423
1340
  const TestFileSummaryLabel = picocolors_default().gray('Test Files'.padStart(11));
1424
1341
  const TestSummaryLabel = picocolors_default().gray('Tests'.padStart(11));
1425
1342
  const DurationLabel = picocolors_default().gray('Duration'.padStart(11));
1426
1343
  const printSummaryLog = ({ results, testResults, snapshotSummary, duration, rootPath })=>{
1427
- src_logger.log('');
1344
+ logger_logger.log('');
1428
1345
  printSnapshotSummaryLog(snapshotSummary, rootPath);
1429
- src_logger.log(`${TestFileSummaryLabel} ${getSummaryStatusString(results)}`);
1430
- src_logger.log(`${TestSummaryLabel} ${getSummaryStatusString(testResults)}`);
1431
- src_logger.log(`${DurationLabel} ${prettyTime(duration.totalTime)} ${picocolors_default().gray(`(build ${prettyTime(duration.buildTime)}, tests ${prettyTime(duration.testTime)})`)}`);
1432
- src_logger.log('');
1346
+ logger_logger.log(`${TestFileSummaryLabel} ${getSummaryStatusString(results)}`);
1347
+ logger_logger.log(`${TestSummaryLabel} ${getSummaryStatusString(testResults)}`);
1348
+ logger_logger.log(`${DurationLabel} ${prettyTime(duration.totalTime)} ${picocolors_default().gray(`(build ${prettyTime(duration.buildTime)}, tests ${prettyTime(duration.testTime)})`)}`);
1349
+ logger_logger.log('');
1433
1350
  };
1434
1351
  const printSummaryErrorLogs = async ({ testResults, results, rootPath, getSourcemap, filterRerunTestPaths })=>{
1435
1352
  const failedTests = [
@@ -1437,13 +1354,13 @@ const printSummaryErrorLogs = async ({ testResults, results, rootPath, getSource
1437
1354
  ...testResults.filter((i)=>'fail' === i.status && (filterRerunTestPaths ? filterRerunTestPaths.includes(i.testPath) : true))
1438
1355
  ];
1439
1356
  if (0 === failedTests.length) return;
1440
- src_logger.log('');
1441
- src_logger.log(picocolors_default().bold('Summary of all failing tests:'));
1442
- src_logger.log('');
1357
+ logger_logger.stderr('');
1358
+ logger_logger.stderr(picocolors_default().bold('Summary of all failing tests:'));
1359
+ logger_logger.stderr('');
1443
1360
  for (const test of failedTests){
1444
1361
  const relativePath = posix.relative(rootPath, test.testPath);
1445
1362
  const nameStr = getTaskNameWithPrefix(test);
1446
- src_logger.log(`${picocolors_default().bgRed(' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${picocolors_default().dim(">")} ${nameStr}` : ''}`);
1363
+ logger_logger.stderr(`${bgColor('bgRed', ' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${picocolors_default().dim(">")} ${nameStr}` : ''}`);
1447
1364
  if (test.errors) {
1448
1365
  const { printError } = await Promise.resolve().then(()=>({
1449
1366
  printError: error_printError
@@ -1575,11 +1492,11 @@ class StatusRenderer {
1575
1492
  renderer;
1576
1493
  startTime = void 0;
1577
1494
  testState;
1578
- constructor(rootPath, state){
1495
+ constructor(rootPath, state, logger){
1579
1496
  this.rootPath = rootPath;
1580
1497
  this.renderer = new WindowRenderer({
1581
1498
  getWindow: ()=>this.getContent(),
1582
- logger: {
1499
+ logger: logger ?? {
1583
1500
  outputStream: process.stdout,
1584
1501
  errorStream: process.stderr,
1585
1502
  getColumns: ()=>'columns' in process.stdout ? process.stdout.columns : 80
@@ -1596,7 +1513,7 @@ class StatusRenderer {
1596
1513
  const shouldDisplayRunningTests = (runningTests)=>runningTests[0]?.startTime && now - runningTests[0].startTime > 2000;
1597
1514
  for (const [module, { runningTests }] of runningModules.entries()){
1598
1515
  const relativePath = pathe_M_eThtNZ_relative(this.rootPath, module);
1599
- summary.push(`${picocolors_default().bgYellow(picocolors_default().bold(' RUNS '))} ${prettyTestPath(relativePath)}`);
1516
+ summary.push(`${bgColor('bgYellow', ' RUNS ')} ${prettyTestPath(relativePath)}`);
1600
1517
  if (runningTests.length && shouldDisplayRunningTests(runningTests)) {
1601
1518
  let caseLog = ` ${picocolors_default().gray("➜")} ${getTaskNameWithPrefix(runningTests[0])} ${picocolors_default().magenta(prettyTime(now - runningTests[0].startTime))}`;
1602
1519
  if (runningTests.length > 1) caseLog += picocolors_default().gray(` and ${runningTests.length - 1} more cases`);
@@ -1646,8 +1563,8 @@ const logCase = (result, options)=>{
1646
1563
  const duration = void 0 !== result.duration ? ` (${prettyTime(result.duration)})` : '';
1647
1564
  const retry = result.retryCount ? picocolors_default().yellow(` (retry x${result.retryCount})`) : '';
1648
1565
  const heap = result.heap ? ` ${picocolors_default().magenta(formatHeapUsed(result.heap))}` : '';
1649
- src_logger.log(` ${icon} ${nameStr}${picocolors_default().gray(duration)}${retry}${heap}`);
1650
- if (result.errors) for (const error of result.errors)console.error(picocolors_default().red(` ${error.message}`));
1566
+ logger_logger.log(` ${icon} ${nameStr}${picocolors_default().gray(duration)}${retry}${heap}`);
1567
+ if (result.errors) for (const error of result.errors)logger_logger.log(picocolors_default().red(` ${error.message}`));
1651
1568
  };
1652
1569
  const formatHeapUsed = (heap)=>`${Math.floor(heap / 1024 / 1024)} MB heap used`;
1653
1570
  const logFileTitle = (test, relativePath, alwaysShowTime = false)=>{
@@ -1656,7 +1573,7 @@ const logFileTitle = (test, relativePath, alwaysShowTime = false)=>{
1656
1573
  title += ` ${picocolors_default().gray(`(${test.results.length})`)}`;
1657
1574
  if (alwaysShowTime) title += ` ${formatDuration(test.duration)}`;
1658
1575
  if (test.heap) title += ` ${picocolors_default().magenta(formatHeapUsed(test.heap))}`;
1659
- src_logger.log(title);
1576
+ logger_logger.log(title);
1660
1577
  };
1661
1578
  class DefaultReporter {
1662
1579
  rootPath;
@@ -1667,7 +1584,7 @@ class DefaultReporter {
1667
1584
  this.rootPath = rootPath;
1668
1585
  this.config = config;
1669
1586
  this.options = options;
1670
- if (isTTY()) this.statusRenderer = new StatusRenderer(rootPath, testState);
1587
+ if (isTTY() || options.logger) this.statusRenderer = new StatusRenderer(rootPath, testState, options.logger);
1671
1588
  }
1672
1589
  onTestFileStart() {
1673
1590
  this.statusRenderer?.onTestFileStart();
@@ -1699,10 +1616,11 @@ class DefaultReporter {
1699
1616
  if (filePath !== testPath) titles.push(testPath);
1700
1617
  titles.push(`${filePath}:${frame.lineNumber}:${frame.column}`);
1701
1618
  } else titles.push(testPath);
1702
- src_logger.log('');
1703
- src_logger.log(`${log.name}${picocolors_default().gray(picocolors_default().dim(` | ${titles.join(picocolors_default().gray(picocolors_default().dim(' | ')))}`))}`);
1704
- src_logger.log(log.content);
1705
- src_logger.log('');
1619
+ const logOutput = 'stdout' === log.type ? logger_logger.log : logger_logger.stderr;
1620
+ logOutput('');
1621
+ logOutput(`${log.name}${picocolors_default().gray(picocolors_default().dim(` | ${titles.join(picocolors_default().gray(picocolors_default().dim(' | ')))}`))}`);
1622
+ logOutput(log.content);
1623
+ logOutput('');
1706
1624
  }
1707
1625
  async onExit() {
1708
1626
  this.statusRenderer?.clear();
@@ -1734,7 +1652,7 @@ class GithubActionsReporter {
1734
1652
  this.rootPath = rootPath;
1735
1653
  }
1736
1654
  log(message) {
1737
- console.log(`${message}\n`);
1655
+ logger_logger.log(`${message}\n`);
1738
1656
  }
1739
1657
  async onTestRunEnd({ results, testResults, getSourcemap }) {
1740
1658
  const failedTests = [
@@ -2115,14 +2033,14 @@ async function error_printError(error, getSourcemap, rootPath) {
2115
2033
  ` - Update your code to use imports from "${picocolors_default().yellow('@rstest/core')}" instead of "${picocolors_default().yellow('vitest')}".`,
2116
2034
  ' - Enable `globals` configuration and use global API.'
2117
2035
  ];
2118
- src_logger.log(`${picocolors_default().red(tips.join('\n'))}\n`);
2036
+ logger_logger.stderr(`${picocolors_default().red(tips.join('\n'))}\n`);
2119
2037
  return;
2120
2038
  }
2121
2039
  if (error.message.includes('is not defined')) error.message = hintNotDefinedError(error.message);
2122
- src_logger.log(`${picocolors_default().red(picocolors_default().bold(errorName))}${picocolors_default().red(`: ${error.message}`)}\n`);
2040
+ logger_logger.stderr(`${picocolors_default().red(picocolors_default().bold(errorName))}${picocolors_default().red(`: ${error.message}`)}\n`);
2123
2041
  if (error.diff) {
2124
- src_logger.log(error.diff);
2125
- src_logger.log();
2042
+ logger_logger.stderr(error.diff);
2043
+ logger_logger.stderr('');
2126
2044
  }
2127
2045
  if (error.stack) {
2128
2046
  const stackFrames = await error_parseErrorStacktrace({
@@ -2130,7 +2048,7 @@ async function error_printError(error, getSourcemap, rootPath) {
2130
2048
  fullStack: error.fullStack,
2131
2049
  getSourcemap
2132
2050
  });
2133
- 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."));
2051
+ if (!stackFrames.length && !(error.fullStack || isDebug()) && !error.stack.endsWith(error.message)) logger_logger.stderr(picocolors_default().gray("No error stack found, set 'DEBUG=rstest' to show fullStack."));
2134
2052
  if (stackFrames[0]) await printCodeFrame(stackFrames[0]);
2135
2053
  printStack(stackFrames, rootPath);
2136
2054
  }
@@ -2150,15 +2068,15 @@ async function printCodeFrame(frame) {
2150
2068
  highlightCode: true,
2151
2069
  linesBelow: 2
2152
2070
  });
2153
- src_logger.log(result);
2154
- src_logger.log('');
2071
+ logger_logger.stderr(result);
2072
+ logger_logger.stderr('');
2155
2073
  }
2156
2074
  function formatStack(frame, rootPath) {
2157
2075
  return '<unknown>' !== frame.methodName ? `at ${frame.methodName} (${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column})` : `at ${formatTestPath(rootPath, frame.file)}:${frame.lineNumber}:${frame.column}`;
2158
2076
  }
2159
2077
  function printStack(stackFrames, rootPath) {
2160
- for (const frame of stackFrames)src_logger.log(picocolors_default().gray(` ${formatStack(frame, rootPath)}`));
2161
- stackFrames.length && src_logger.log();
2078
+ for (const frame of stackFrames)logger_logger.stderr(picocolors_default().gray(` ${formatStack(frame, rootPath)}`));
2079
+ stackFrames.length && logger_logger.stderr('');
2162
2080
  }
2163
2081
  const stackIgnores = [
2164
2082
  /\/@rstest\/core/,
@@ -2175,7 +2093,7 @@ const stackIgnores = [
2175
2093
  ];
2176
2094
  async function error_parseErrorStacktrace({ stack, getSourcemap, fullStack = isDebug() }) {
2177
2095
  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)=>{
2178
- const sourcemap = await getSourcemap(frame.file);
2096
+ const sourcemap = await getSourcemap?.(frame.file);
2179
2097
  if (sourcemap) {
2180
2098
  const traceMap = new TraceMap(sourcemap);
2181
2099
  const { line, column, source, name } = originalPositionFor(traceMap, {
@@ -2305,13 +2223,13 @@ class JUnitReporter {
2305
2223
  const xmlContent = this.generateJUnitXml(report);
2306
2224
  if (this.outputPath) try {
2307
2225
  await writeFile(this.outputPath, xmlContent, 'utf-8');
2308
- console.log(`JUnit XML report written to: ${this.outputPath}`);
2226
+ logger_logger.log(`JUnit XML report written to: ${this.outputPath}`);
2309
2227
  } catch (error) {
2310
- console.error(`Failed to write JUnit XML report to ${this.outputPath}:`, error);
2311
- console.log('JUnit XML Report:');
2312
- console.log(xmlContent);
2228
+ logger_logger.stderr(`Failed to write JUnit XML report to ${this.outputPath}:`, error);
2229
+ logger_logger.log('JUnit XML Report:');
2230
+ logger_logger.log(xmlContent);
2313
2231
  }
2314
- else console.log(xmlContent);
2232
+ else logger_logger.log(xmlContent);
2315
2233
  }
2316
2234
  }
2317
2235
  class VerboseReporter extends DefaultReporter {
@@ -2428,7 +2346,7 @@ class Rstest {
2428
2346
  });
2429
2347
  this.reporters = reporters;
2430
2348
  this.snapshotManager = snapshotManager;
2431
- this.version = "0.7.1";
2349
+ this.version = "0.7.3";
2432
2350
  this.rootPath = rootPath;
2433
2351
  this.originalConfig = userConfig;
2434
2352
  this.normalizedConfig = rstestConfig;
@@ -2523,7 +2441,7 @@ function core_createRstest({ config, projects, configFilePath }, command, fileFi
2523
2441
  const { listTests } = await import("./0~634.js").then((mod)=>({
2524
2442
  listTests: mod.listTests
2525
2443
  }));
2526
- await listTests(context, options);
2444
+ return listTests(context, options);
2527
2445
  };
2528
2446
  return {
2529
2447
  context,
@@ -2571,4 +2489,4 @@ function defineConfig(config) {
2571
2489
  function defineProject(config) {
2572
2490
  return config;
2573
2491
  }
2574
- 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 };
2492
+ export { EventEmitter, afterAll, afterEach, assert, beforeAll, beforeEach, config_loadConfig as loadConfig, core_createRstest as createRstest, core_logger, createRsbuild, defineConfig, defineProject, describe, error_printError, expect, init_initCli as initCli, it, mergeRstestConfig, onTestFailed, onTestFinished, public_rstest as rstest, public_test as test, rs, runCLI, runRest };
package/dist/404.js ADDED
@@ -0,0 +1,210 @@
1
+ import 'module';
2
+ /*#__PURE__*/ import.meta.url;
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import node_v8 from "node:v8";
5
+ const TYPE_REQUEST = "q";
6
+ const TYPE_RESPONSE = "s";
7
+ const DEFAULT_TIMEOUT = 6e4;
8
+ function defaultSerialize(i) {
9
+ return i;
10
+ }
11
+ const defaultDeserialize = defaultSerialize;
12
+ const { clearTimeout: dist_clearTimeout, setTimeout: dist_setTimeout } = globalThis;
13
+ const random = Math.random.bind(Math);
14
+ function createBirpc($functions, options) {
15
+ const { post, on, off = ()=>{}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT } = options;
16
+ let $closed = false;
17
+ const _rpcPromiseMap = /* @__PURE__ */ new Map();
18
+ let _promiseInit;
19
+ let rpc;
20
+ async function _call(method, args, event, optional) {
21
+ if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
22
+ const req = {
23
+ m: method,
24
+ a: args,
25
+ t: TYPE_REQUEST
26
+ };
27
+ if (optional) req.o = true;
28
+ const send = async (_req)=>post(serialize(_req));
29
+ if (event) return void await send(req);
30
+ if (_promiseInit) try {
31
+ await _promiseInit;
32
+ } finally{
33
+ _promiseInit = void 0;
34
+ }
35
+ let { promise, resolve, reject } = createPromiseWithResolvers();
36
+ const id = nanoid();
37
+ req.i = id;
38
+ let timeoutId;
39
+ async function handler(newReq = req) {
40
+ if (timeout >= 0) {
41
+ timeoutId = dist_setTimeout(()=>{
42
+ try {
43
+ const handleResult = options.onTimeoutError?.call(rpc, method, args);
44
+ if (true !== handleResult) throw new Error(`[birpc] timeout on calling "${method}"`);
45
+ } catch (e) {
46
+ reject(e);
47
+ }
48
+ _rpcPromiseMap.delete(id);
49
+ }, timeout);
50
+ if ("object" == typeof timeoutId) timeoutId = timeoutId.unref?.();
51
+ }
52
+ _rpcPromiseMap.set(id, {
53
+ resolve,
54
+ reject,
55
+ timeoutId,
56
+ method
57
+ });
58
+ await send(newReq);
59
+ return promise;
60
+ }
61
+ try {
62
+ if (options.onRequest) await options.onRequest.call(rpc, req, handler, resolve);
63
+ else await handler();
64
+ } catch (e) {
65
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
66
+ return;
67
+ } finally{
68
+ dist_clearTimeout(timeoutId);
69
+ _rpcPromiseMap.delete(id);
70
+ }
71
+ return promise;
72
+ }
73
+ const $call = (method, ...args)=>_call(method, args, false);
74
+ const $callOptional = (method, ...args)=>_call(method, args, false, true);
75
+ const $callEvent = (method, ...args)=>_call(method, args, true);
76
+ const $callRaw = (options2)=>_call(options2.method, options2.args, options2.event, options2.optional);
77
+ const builtinMethods = {
78
+ $call,
79
+ $callOptional,
80
+ $callEvent,
81
+ $callRaw,
82
+ $rejectPendingCalls,
83
+ get $closed () {
84
+ return $closed;
85
+ },
86
+ get $meta () {
87
+ return options.meta;
88
+ },
89
+ $close,
90
+ $functions
91
+ };
92
+ rpc = new Proxy({}, {
93
+ get (_, method) {
94
+ if (Object.prototype.hasOwnProperty.call(builtinMethods, method)) return builtinMethods[method];
95
+ if ("then" === method && !eventNames.includes("then") && !("then" in $functions)) return;
96
+ const sendEvent = (...args)=>_call(method, args, true);
97
+ if (eventNames.includes(method)) {
98
+ sendEvent.asEvent = sendEvent;
99
+ return sendEvent;
100
+ }
101
+ const sendCall = (...args)=>_call(method, args, false);
102
+ sendCall.asEvent = sendEvent;
103
+ return sendCall;
104
+ }
105
+ });
106
+ function $close(customError) {
107
+ $closed = true;
108
+ _rpcPromiseMap.forEach(({ reject, method })=>{
109
+ const error = new Error(`[birpc] rpc is closed, cannot call "${method}"`);
110
+ if (customError) {
111
+ customError.cause ??= error;
112
+ return reject(customError);
113
+ }
114
+ reject(error);
115
+ });
116
+ _rpcPromiseMap.clear();
117
+ off(onMessage);
118
+ }
119
+ function $rejectPendingCalls(handler) {
120
+ const entries = Array.from(_rpcPromiseMap.values());
121
+ const handlerResults = entries.map(({ method, reject })=>{
122
+ if (!handler) return reject(new Error(`[birpc]: rejected pending call "${method}".`));
123
+ return handler({
124
+ method,
125
+ reject
126
+ });
127
+ });
128
+ _rpcPromiseMap.clear();
129
+ return handlerResults;
130
+ }
131
+ async function onMessage(data, ...extra) {
132
+ let msg;
133
+ try {
134
+ msg = deserialize(data);
135
+ } catch (e) {
136
+ if (options.onGeneralError?.call(rpc, e) !== true) throw e;
137
+ return;
138
+ }
139
+ if (msg.t === TYPE_REQUEST) {
140
+ const { m: method, a: args, o: optional } = msg;
141
+ let result, error;
142
+ let fn = await (resolver ? resolver.call(rpc, method, $functions[method]) : $functions[method]);
143
+ if (optional) fn ||= ()=>void 0;
144
+ if (fn) try {
145
+ result = await fn.apply("rpc" === bind ? rpc : $functions, args);
146
+ } catch (e) {
147
+ error = e;
148
+ }
149
+ else error = new Error(`[birpc] function "${method}" not found`);
150
+ if (msg.i) {
151
+ if (error && options.onError) options.onError.call(rpc, error, method, args);
152
+ if (error && options.onFunctionError) {
153
+ if (true === options.onFunctionError.call(rpc, error, method, args)) return;
154
+ }
155
+ if (!error) try {
156
+ await post(serialize({
157
+ t: TYPE_RESPONSE,
158
+ i: msg.i,
159
+ r: result
160
+ }), ...extra);
161
+ return;
162
+ } catch (e) {
163
+ error = e;
164
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
165
+ }
166
+ try {
167
+ await post(serialize({
168
+ t: TYPE_RESPONSE,
169
+ i: msg.i,
170
+ e: error
171
+ }), ...extra);
172
+ } catch (e) {
173
+ if (options.onGeneralError?.call(rpc, e, method, args) !== true) throw e;
174
+ }
175
+ }
176
+ } else {
177
+ const { i: ack, r: result, e: error } = msg;
178
+ const promise = _rpcPromiseMap.get(ack);
179
+ if (promise) {
180
+ dist_clearTimeout(promise.timeoutId);
181
+ if (error) promise.reject(error);
182
+ else promise.resolve(result);
183
+ }
184
+ _rpcPromiseMap.delete(ack);
185
+ }
186
+ }
187
+ _promiseInit = on(onMessage);
188
+ return rpc;
189
+ }
190
+ function createPromiseWithResolvers() {
191
+ let resolve;
192
+ let reject;
193
+ const promise = new Promise((res, rej)=>{
194
+ resolve = res;
195
+ reject = rej;
196
+ });
197
+ return {
198
+ promise,
199
+ resolve,
200
+ reject
201
+ };
202
+ }
203
+ const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
204
+ function nanoid(size = 21) {
205
+ let id = "";
206
+ let i = size;
207
+ while(i--)id += urlAlphabet[64 * random() | 0];
208
+ return id;
209
+ }
210
+ export { createBirpc, fileURLToPath, node_v8, pathToFileURL };