@rstest/core 0.9.3 → 0.9.5

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.
Files changed (42) hide show
  1. package/LICENSE.md +0 -228
  2. package/dist/0~8843.js +33 -17
  3. package/dist/0~browserLoader.js +1 -1
  4. package/dist/0~browser~1.js +4 -4
  5. package/dist/0~checkThresholds.js +1 -1
  6. package/dist/0~console.js +1 -1
  7. package/dist/0~fake-timers.js +1483 -0
  8. package/dist/0~generate.js +4 -3
  9. package/dist/0~happyDom.js +1 -1
  10. package/dist/0~jsdom.js +1 -1
  11. package/dist/0~listTests.js +14 -10
  12. package/dist/0~loadEsModule.js +3 -1
  13. package/dist/0~loadModule.js +1 -1
  14. package/dist/0~runTests.js +17 -6
  15. package/dist/0~snapshot.js +2140 -0
  16. package/dist/0~snapshot.js.LICENSE.txt +7 -0
  17. package/dist/0~utils.js +1 -1
  18. package/dist/1949.js +2919 -9808
  19. package/dist/1949.js.LICENSE.txt +1 -49
  20. package/dist/3145.js +363 -63
  21. package/dist/4411.js +232 -47
  22. package/dist/6830.js +61 -9
  23. package/dist/7552.js +22 -4918
  24. package/dist/7704.js +1 -2
  25. package/dist/9743.js +1982 -0
  26. package/dist/9784.js +1343 -0
  27. package/dist/{7552.js.LICENSE.txt → 9784.js.LICENSE.txt} +19 -8
  28. package/dist/browser-runtime/2~fake-timers.js +1653 -0
  29. package/dist/browser-runtime/2~snapshot.js +2138 -0
  30. package/dist/browser-runtime/2~snapshot.js.LICENSE.txt +7 -0
  31. package/dist/browser-runtime/723.js +2055 -10605
  32. package/dist/browser-runtime/723.js.LICENSE.txt +0 -17
  33. package/dist/browser-runtime/index.d.ts +189 -11
  34. package/dist/browser-runtime/rslib-runtime.js +0 -7
  35. package/dist/browser.d.ts +39 -5
  36. package/dist/browser.js +2 -2
  37. package/dist/globalSetupWorker.js +1 -1
  38. package/dist/index.d.ts +39 -5
  39. package/dist/mockRuntimeCode.js +2 -0
  40. package/dist/worker.d.ts +31 -5
  41. package/dist/worker.js +32 -11
  42. package/package.json +21 -22
package/dist/3145.js CHANGED
@@ -7,8 +7,8 @@ import promises from "node:fs/promises";
7
7
  import node_path, { dirname as external_node_path_dirname, resolve as external_node_path_resolve } from "node:path";
8
8
  import { createRequire } from "node:module";
9
9
  import node_process from "node:process";
10
- import { basename, isTTY, dirname as pathe_M_eThtNZ_dirname, resolve as pathe_M_eThtNZ_resolve, relative, getAbsolutePath, join, bgColor, formatRootStr, determineAgent, logger as logger_logger, castArray, dist_m, prettyTime, isDebug, color as logger_color, isAbsolute, getTaskNameWithPrefix, normalize, formatError } from "./6830.js";
11
- import { isDynamicPattern, glob, DEFAULT_CONFIG_NAME, prettyTestPath, globalApis, TEMP_RSTEST_OUTPUT_DIR_GLOB, formatTestPath, filterProjects, DEFAULT_CONFIG_EXTENSIONS, TS_CONFIG_FILE } from "./4411.js";
10
+ import { POINTER, DEFAULT_CONFIG_NAME, globalApis, resolve as pathe_M_eThtNZ_resolve, relative, join, logger as logger_logger, prettyTime, getTempRstestOutputDirGlob, color as logger_color, isAbsolute, getOutputDistPathRoot, TEMP_RSTEST_OUTPUT_DIR, TS_CONFIG_FILE, basename, isTTY, dirname as pathe_M_eThtNZ_dirname, TEST_DELIMITER, getAbsolutePath, bgColor, formatRootStr, determineAgent, castArray, dist_m, getTaskNameWithPrefix, isDebug, formatError, normalize, DEFAULT_CONFIG_EXTENSIONS } from "./6830.js";
11
+ import { isDynamicPattern, glob, filterProjects, prettyTestPath, formatTestPath } from "./4411.js";
12
12
  import { posix } from "./7011.js";
13
13
  import { parse as stack_trace_parser_esm_parse } from "./1672.js";
14
14
  import { decode } from "./4397.js";
@@ -16,11 +16,12 @@ import "./5040.js";
16
16
  var init_namespaceObject = {};
17
17
  __webpack_require__.r(init_namespaceObject);
18
18
  __webpack_require__.d(init_namespaceObject, {
19
- initCli: ()=>init_initCli
19
+ initCli: ()=>init_initCli,
20
+ resolveProjects: ()=>resolveProjects
20
21
  });
21
- var src_core_namespaceObject = {};
22
- __webpack_require__.r(src_core_namespaceObject);
23
- __webpack_require__.d(src_core_namespaceObject, {
22
+ var core_namespaceObject = {};
23
+ __webpack_require__.r(core_namespaceObject);
24
+ __webpack_require__.d(core_namespaceObject, {
24
25
  createRstest: ()=>core_createRstest
25
26
  });
26
27
  var error_namespaceObject = {};
@@ -587,30 +588,281 @@ function prepareCli() {
587
588
  if (!npm_execpath || npm_execpath.includes('npx-cli.js') || npm_execpath.includes('.bun')) logger_logger.log();
588
589
  }
589
590
  function showRstest() {
590
- logger_logger.greet(" Rstest v0.9.3");
591
+ logger_logger.greet(" Rstest v0.9.5");
591
592
  logger_logger.log('');
592
593
  }
593
- const applyCommonOptions = (cli)=>{
594
- 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 (auto | jiti | native)', {
595
- default: 'auto'
596
- }).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('--hideSkippedTestFiles', 'Hide skipped test files 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('--shard <index/count>', 'Split tests into several shards. This is useful for running tests in parallel on multiple machines.').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('--browser', 'Run tests in browser mode').option('--browser.enabled', 'Run tests in browser mode').option('--browser.name <name>', 'Browser to use: chromium, firefox, webkit (default: chromium)').option('--browser.headless', 'Run browser in headless mode (default: true in CI)').option('--browser.port <port>', 'Port for the browser mode dev server').option('--browser.strictPort', 'Exit if the specified port is already in use').option('--unstubGlobals', 'Restores all global variables that were changed with `rstest.stubGlobal` before every test').option('--unstubEnvs', 'Restores all runtime env values that were changed with `rstest.stubEnv` before every test').option('--includeTaskLocation', 'Collect test and suite locations. This might increase the running time.');
597
- cli.option('--pool <type>', 'Shorthand for --pool.type').option('--pool.type <type>', 'Specify the test pool type (e.g. forks)').option('--pool.maxWorkers <value>', 'Maximum number or percentage of workers (e.g. 4 or 50%)').option('--pool.minWorkers <value>', 'Minimum number or percentage of workers (e.g. 1 or 25%)').option('--pool.execArgv <arg>', 'Additional Node.js execArgv passed to worker processes (can be specified multiple times)');
594
+ const runtimeOptionDefinitions = [
595
+ [
596
+ '-c, --config <config>',
597
+ 'Specify the configuration file, can be a relative or absolute path'
598
+ ],
599
+ [
600
+ '--config-loader <loader>',
601
+ 'Specify the loader to load the config file (auto | jiti | native)',
602
+ {
603
+ default: 'auto'
604
+ }
605
+ ],
606
+ [
607
+ '-r, --root <root>',
608
+ 'Specify the project root directory, can be an absolute path or a path relative to cwd'
609
+ ],
610
+ [
611
+ '--globals',
612
+ 'Provide global APIs'
613
+ ],
614
+ [
615
+ '--isolate',
616
+ 'Run tests in an isolated environment'
617
+ ],
618
+ [
619
+ '--include <include>',
620
+ 'Match test files'
621
+ ],
622
+ [
623
+ '--exclude <exclude>',
624
+ 'Exclude files from test'
625
+ ],
626
+ [
627
+ '-u, --update',
628
+ 'Update snapshot files'
629
+ ],
630
+ [
631
+ '--coverage',
632
+ 'Enable code coverage collection'
633
+ ],
634
+ [
635
+ '--project <name>',
636
+ 'Run only projects that match the name, can be a full name or wildcards pattern'
637
+ ],
638
+ [
639
+ '--passWithNoTests',
640
+ 'Allows the test suite to pass when no files are found'
641
+ ],
642
+ [
643
+ '--printConsoleTrace',
644
+ 'Print console traces when calling any console method'
645
+ ],
646
+ [
647
+ '--disableConsoleIntercept',
648
+ 'Disable console intercept'
649
+ ],
650
+ [
651
+ '--logHeapUsage',
652
+ 'Log heap usage after each test'
653
+ ],
654
+ [
655
+ '--slowTestThreshold <value>',
656
+ 'The number of milliseconds after which a test or suite is considered slow'
657
+ ],
658
+ [
659
+ '--reporter <reporter>',
660
+ 'Specify the reporter to use'
661
+ ],
662
+ [
663
+ '-t, --testNamePattern <value>',
664
+ 'Run only tests with a name that matches the regex'
665
+ ],
666
+ [
667
+ '--testEnvironment <name>',
668
+ 'The environment that will be used for testing'
669
+ ],
670
+ [
671
+ '--testTimeout <value>',
672
+ 'Timeout of a test in milliseconds'
673
+ ],
674
+ [
675
+ '--hookTimeout <value>',
676
+ 'Timeout of hook in milliseconds'
677
+ ],
678
+ [
679
+ '--hideSkippedTests',
680
+ 'Hide skipped tests from the output'
681
+ ],
682
+ [
683
+ '--hideSkippedTestFiles',
684
+ 'Hide skipped test files from the output'
685
+ ],
686
+ [
687
+ '--retry <retry>',
688
+ 'Number of times to retry a test if it fails'
689
+ ],
690
+ [
691
+ '--bail [number]',
692
+ 'Stop running tests after n failures. Set to 0 to run all tests regardless of failures'
693
+ ],
694
+ [
695
+ '--shard <index/count>',
696
+ 'Split tests into several shards. This is useful for running tests in parallel on multiple machines.'
697
+ ],
698
+ [
699
+ '--maxConcurrency <value>',
700
+ 'Maximum number of concurrent tests'
701
+ ],
702
+ [
703
+ '--clearMocks',
704
+ 'Automatically clear mock calls, instances, contexts and results before every test'
705
+ ],
706
+ [
707
+ '--resetMocks',
708
+ 'Automatically reset mock state before every test'
709
+ ],
710
+ [
711
+ '--restoreMocks',
712
+ 'Automatically restore mock state and implementation before every test'
713
+ ],
714
+ [
715
+ '--browser',
716
+ 'Run tests in browser mode'
717
+ ],
718
+ [
719
+ '--browser.enabled',
720
+ 'Run tests in browser mode'
721
+ ],
722
+ [
723
+ '--browser.name <name>',
724
+ 'Browser to use: chromium, firefox, webkit (default: chromium)'
725
+ ],
726
+ [
727
+ '--browser.headless',
728
+ 'Run browser in headless mode (default: true in CI)'
729
+ ],
730
+ [
731
+ '--browser.port <port>',
732
+ 'Port for the browser mode dev server'
733
+ ],
734
+ [
735
+ '--browser.strictPort',
736
+ 'Exit if the specified port is already in use'
737
+ ],
738
+ [
739
+ '--unstubGlobals',
740
+ 'Restores all global variables that were changed with `rstest.stubGlobal` before every test'
741
+ ],
742
+ [
743
+ '--unstubEnvs',
744
+ 'Restores all runtime env values that were changed with `rstest.stubEnv` before every test'
745
+ ],
746
+ [
747
+ '--includeTaskLocation',
748
+ 'Collect test and suite locations. This might increase the running time.'
749
+ ]
750
+ ];
751
+ const poolOptionDefinitions = [
752
+ [
753
+ '--pool <type>',
754
+ 'Shorthand for --pool.type'
755
+ ],
756
+ [
757
+ '--pool.type <type>',
758
+ 'Specify the test pool type (e.g. forks)'
759
+ ],
760
+ [
761
+ '--pool.maxWorkers <value>',
762
+ 'Maximum number or percentage of workers (e.g. 4 or 50%)'
763
+ ],
764
+ [
765
+ '--pool.minWorkers <value>',
766
+ 'Minimum number or percentage of workers (e.g. 1 or 25%)'
767
+ ],
768
+ [
769
+ '--pool.execArgv <arg>',
770
+ 'Additional Node.js execArgv passed to worker processes (can be specified multiple times)'
771
+ ]
772
+ ];
773
+ const mergeReportsOptionDefinitions = [
774
+ [
775
+ '-c, --config <config>',
776
+ 'Specify the configuration file, can be a relative or absolute path'
777
+ ],
778
+ [
779
+ '--config-loader <loader>',
780
+ 'Specify the loader to load the config file (auto | jiti | native)',
781
+ {
782
+ default: 'auto'
783
+ }
784
+ ],
785
+ [
786
+ '-r, --root <root>',
787
+ 'Specify the project root directory, can be an absolute path or a path relative to cwd'
788
+ ],
789
+ [
790
+ '--coverage',
791
+ 'Enable code coverage collection'
792
+ ],
793
+ [
794
+ '--reporter <reporter>',
795
+ 'Specify the reporter to use'
796
+ ],
797
+ [
798
+ '--cleanup',
799
+ 'Remove blob reports directory after merging'
800
+ ]
801
+ ];
802
+ const hiddenPassthroughOptionDefinitions = [
803
+ [
804
+ '--isolate',
805
+ 'Run tests in an isolated environment'
806
+ ]
807
+ ];
808
+ const listCommandOptionDefinitions = [
809
+ [
810
+ '--filesOnly',
811
+ 'only list the test files'
812
+ ],
813
+ [
814
+ '--json [boolean/path]',
815
+ 'print tests as JSON or write to a file'
816
+ ],
817
+ [
818
+ '--includeSuites',
819
+ 'include suites in output'
820
+ ],
821
+ [
822
+ '--printLocation',
823
+ 'print test case location'
824
+ ]
825
+ ];
826
+ const applyOptions = (command, definitions)=>{
827
+ for (const [rawName, description, config] of definitions)command.option(rawName, description, config);
828
+ };
829
+ const applyRuntimeCommandOptions = (command)=>{
830
+ applyOptions(command, runtimeOptionDefinitions);
831
+ applyOptions(command, poolOptionDefinitions);
598
832
  };
833
+ const filterHelpOptions = (sections, hiddenOptionPrefixes)=>sections.map((section)=>{
834
+ if ('Options' !== section.title) return section;
835
+ return {
836
+ ...section,
837
+ body: section.body.split('\n').filter((line)=>!hiddenOptionPrefixes.some((prefix)=>line.trimStart().startsWith(prefix))).join('\n')
838
+ };
839
+ });
599
840
  const handleUnexpectedExit = (rstest, err)=>{
600
841
  for (const reporter of rstest?.context.reporters || [])reporter.onExit?.();
601
842
  logger_logger.error('Failed to run Rstest.');
602
843
  logger_logger.error(formatError(err));
603
844
  process.exit(1);
604
845
  };
846
+ const resolveCliRuntime = async (options)=>{
847
+ const [{ initCli }, { createRstest }] = await Promise.all([
848
+ Promise.resolve(init_namespaceObject),
849
+ Promise.resolve(core_namespaceObject)
850
+ ]);
851
+ const { config, configFilePath, projects } = await initCli(options);
852
+ return {
853
+ config,
854
+ configFilePath,
855
+ projects,
856
+ createRstest
857
+ };
858
+ };
605
859
  const runRest = async ({ options, filters, command })=>{
606
860
  let rstest;
607
861
  const unexpectedlyExitHandler = (err)=>{
608
862
  handleUnexpectedExit(rstest, err);
609
863
  };
610
864
  try {
611
- const { initCli } = await Promise.resolve(init_namespaceObject);
612
- const { config, configFilePath, projects } = await initCli(options);
613
- const { createRstest } = await Promise.resolve(src_core_namespaceObject);
865
+ const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
614
866
  rstest = createRstest({
615
867
  config,
616
868
  configFilePath,
@@ -635,12 +887,23 @@ const runRest = async ({ options, filters, command })=>{
635
887
  handleUnexpectedExit(rstest, err);
636
888
  }
637
889
  };
638
- function setupCommands() {
890
+ function createCli() {
639
891
  const cli = cac('rstest');
640
- cli.help();
641
- cli.version("0.9.3");
642
- applyCommonOptions(cli);
643
- cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode').action(async (filters, options)=>{
892
+ cli.help((sections)=>{
893
+ switch(cli.matchedCommand?.name){
894
+ case 'init':
895
+ case 'merge-reports':
896
+ return filterHelpOptions(sections, [
897
+ '--isolate'
898
+ ]);
899
+ default:
900
+ return sections;
901
+ }
902
+ });
903
+ cli.version("0.9.5");
904
+ const defaultCommand = cli.command('[...filters]', 'run tests').option('-w, --watch', 'Run tests in watch mode');
905
+ applyRuntimeCommandOptions(defaultCommand);
906
+ defaultCommand.action(async (filters, options)=>{
644
907
  if (!determineAgent().isAgent) showRstest();
645
908
  if (options.watch) await runRest({
646
909
  options,
@@ -653,7 +916,9 @@ function setupCommands() {
653
916
  command: 'run'
654
917
  });
655
918
  });
656
- cli.command('run [...filters]', 'run tests without watch mode').action(async (filters, options)=>{
919
+ const runCommand = cli.command('run [...filters]', 'run tests without watch mode');
920
+ applyRuntimeCommandOptions(runCommand);
921
+ runCommand.action(async (filters, options)=>{
657
922
  if (!determineAgent().isAgent) showRstest();
658
923
  await runRest({
659
924
  options,
@@ -661,7 +926,9 @@ function setupCommands() {
661
926
  command: 'run'
662
927
  });
663
928
  });
664
- cli.command('watch [...filters]', 'run tests in watch mode').action(async (filters, options)=>{
929
+ const watchCommand = cli.command('watch [...filters]', 'run tests in watch mode');
930
+ applyRuntimeCommandOptions(watchCommand);
931
+ watchCommand.action(async (filters, options)=>{
665
932
  if (!determineAgent().isAgent) showRstest();
666
933
  await runRest({
667
934
  options,
@@ -669,12 +936,13 @@ function setupCommands() {
669
936
  command: 'watch'
670
937
  });
671
938
  });
672
- 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)=>{
939
+ const listCommand = cli.command('list [...filters]', 'lists all test files that Rstest will run');
940
+ applyRuntimeCommandOptions(listCommand);
941
+ applyOptions(listCommand, listCommandOptionDefinitions);
942
+ listCommand.action(async (filters, options)=>{
673
943
  try {
674
- const { initCli } = await Promise.resolve(init_namespaceObject);
675
- const { config, configFilePath, projects } = await initCli(options);
944
+ const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
676
945
  if (options.printLocation) config.includeTaskLocation = true;
677
- const { createRstest } = await Promise.resolve(src_core_namespaceObject);
678
946
  const rstest = createRstest({
679
947
  config,
680
948
  configFilePath,
@@ -692,12 +960,13 @@ function setupCommands() {
692
960
  process.exit(1);
693
961
  }
694
962
  });
695
- cli.command('merge-reports [path]', 'Merge blob reports from multiple shards into a unified report').option('--cleanup', 'Remove blob reports directory after merging').action(async (path, options)=>{
963
+ const mergeReportsCommand = cli.command('merge-reports [path]', 'Merge blob reports from multiple shards into a unified report');
964
+ applyOptions(mergeReportsCommand, mergeReportsOptionDefinitions);
965
+ applyOptions(mergeReportsCommand, hiddenPassthroughOptionDefinitions);
966
+ mergeReportsCommand.action(async (path, options)=>{
696
967
  if (!determineAgent().isAgent) showRstest();
697
968
  try {
698
- const { initCli } = await Promise.resolve(init_namespaceObject);
699
- const { config, configFilePath, projects } = await initCli(options);
700
- const { createRstest } = await Promise.resolve(src_core_namespaceObject);
969
+ const { config, configFilePath, projects, createRstest } = await resolveCliRuntime(options);
701
970
  const rstest = createRstest({
702
971
  config,
703
972
  configFilePath,
@@ -713,7 +982,7 @@ function setupCommands() {
713
982
  process.exit(1);
714
983
  }
715
984
  });
716
- cli.command('init [project]', 'Initialize rstest configuration').option('--yes', 'Use default options (non-interactive)').action(async (project, options)=>{
985
+ cli.command('init [project]', 'Initialize rstest configuration').option('--yes', 'Use default options (non-interactive)').option('--isolate', 'Run tests in an isolated environment').action(async (project, options)=>{
717
986
  try {
718
987
  let selectedProject = project;
719
988
  if (!selectedProject) {
@@ -750,7 +1019,10 @@ function setupCommands() {
750
1019
  process.exit(1);
751
1020
  }
752
1021
  });
753
- cli.parse();
1022
+ return cli;
1023
+ }
1024
+ function setupCommands() {
1025
+ createCli().parse();
754
1026
  }
755
1027
  const findConfig = (basePath)=>DEFAULT_CONFIG_EXTENSIONS.map((ext)=>basePath + ext).find(node_fs.existsSync);
756
1028
  const resolveConfigPath = (root, customConfig)=>{
@@ -852,6 +1124,11 @@ const createDefaultConfig = ()=>({
852
1124
  testEnvironment: {
853
1125
  name: 'node'
854
1126
  },
1127
+ output: {
1128
+ distPath: {
1129
+ root: TEMP_RSTEST_OUTPUT_DIR
1130
+ }
1131
+ },
855
1132
  retry: 0,
856
1133
  reporters: 'true' === process.env.GITHUB_ACTIONS ? [
857
1134
  'default',
@@ -913,7 +1190,11 @@ const withDefaultConfig = (config)=>{
913
1190
  const merged = mergeRstestConfig(createDefaultConfig(), config);
914
1191
  merged.setupFiles = castArray(merged.setupFiles);
915
1192
  merged.globalSetup = castArray(merged.globalSetup);
916
- merged.exclude.patterns.push(TEMP_RSTEST_OUTPUT_DIR_GLOB);
1193
+ const outputDistPathRoot = getOutputDistPathRoot(merged.output?.distPath);
1194
+ merged.output.distPath = {
1195
+ root: formatRootStr(outputDistPathRoot, merged.root)
1196
+ };
1197
+ merged.exclude.patterns.push(getTempRstestOutputDirGlob(merged.output?.distPath?.root));
917
1198
  const reportsDirectory = formatRootStr(merged.coverage.reportsDirectory, merged.root);
918
1199
  merged.coverage.reportsDirectory = isAbsolute(reportsDirectory) ? reportsDirectory : pathe_M_eThtNZ_resolve(merged.root, reportsDirectory);
919
1200
  merged.pool = 'string' == typeof config.pool ? {
@@ -1067,22 +1348,23 @@ async function resolveProjects({ config, root, options }) {
1067
1348
  const getProjects = async (rstestConfig, root)=>{
1068
1349
  const projectPaths = [];
1069
1350
  const projectPatterns = [];
1070
- const projectConfigs = [];
1071
- await Promise.all((rstestConfig.projects || []).map(async (p)=>{
1351
+ const inlineProjectConfigPromises = [];
1352
+ for (const p of rstestConfig.projects || []){
1072
1353
  if ('object' == typeof p) {
1073
1354
  const projectRoot = p.root ? formatRootStr(p.root, root) : root;
1074
- const projectConfig = await resolveExtends({
1355
+ inlineProjectConfigPromises.push(resolveExtends({
1075
1356
  ...p
1076
- });
1077
- projectConfigs.push({
1078
- config: mergeWithCLIOptions({
1079
- root: projectRoot,
1080
- ...projectConfig,
1081
- name: p.name ? p.name : getDefaultProjectName(projectRoot)
1082
- }, options),
1083
- configFilePath: void 0
1084
- });
1085
- return;
1357
+ }).then((projectConfig)=>({
1358
+ config: mergeWithCLIOptions({
1359
+ root: projectRoot,
1360
+ ...projectConfig,
1361
+ name: p.name ? p.name : getDefaultProjectName(projectRoot)
1362
+ }, options),
1363
+ configFilePath: void 0
1364
+ }), (error)=>({
1365
+ error
1366
+ })));
1367
+ continue;
1086
1368
  }
1087
1369
  const projectStr = formatRootStr(p, root);
1088
1370
  if (isDynamicPattern(projectStr)) projectPatterns.push(projectStr);
@@ -1091,8 +1373,16 @@ async function resolveProjects({ config, root, options }) {
1091
1373
  if (!existsSync(absolutePath)) throw `Can't resolve project "${p}", please make sure "${p}" is a existing file or a directory.`;
1092
1374
  projectPaths.push(absolutePath);
1093
1375
  }
1094
- }));
1095
- projectPaths.push(...await globProjects(projectPatterns, root));
1376
+ }
1377
+ const [inlineProjectConfigResults, globbedProjectPaths] = await Promise.all([
1378
+ Promise.all(inlineProjectConfigPromises),
1379
+ globProjects(projectPatterns, root)
1380
+ ]);
1381
+ const projectConfigs = inlineProjectConfigResults.map((result)=>{
1382
+ if ('error' in result) throw result.error;
1383
+ return result;
1384
+ });
1385
+ projectPaths.push(...globbedProjectPaths);
1096
1386
  const projects = [];
1097
1387
  await Promise.all(projectPaths.map(async (project)=>{
1098
1388
  const isDirectory = statSync(project).isDirectory();
@@ -1249,14 +1539,14 @@ const printSnapshotSummaryLog = (snapshots, rootDir)=>{
1249
1539
  else summary.push(logger_color.bold(logger_color.yellow(`${snapshots.filesRemoved} files obsolete `)));
1250
1540
  if (snapshots.filesRemovedList?.length) {
1251
1541
  const [head, ...tail] = snapshots.filesRemovedList;
1252
- summary.push(`${logger_color.gray("➜")} ${formatTestPath(rootDir, head)}`);
1542
+ summary.push(`${logger_color.gray(POINTER)} ${formatTestPath(rootDir, head)}`);
1253
1543
  for (const key of tail)summary.push(` ${formatTestPath(rootDir, key)}`);
1254
1544
  }
1255
1545
  if (snapshots.unchecked) {
1256
1546
  if (snapshots.didUpdate) summary.push(logger_color.bold(logger_color.green(`${snapshots.unchecked} removed`)));
1257
1547
  else summary.push(logger_color.bold(logger_color.yellow(`${snapshots.unchecked} obsolete`)));
1258
1548
  for (const uncheckedFile of snapshots.uncheckedKeysByFile){
1259
- summary.push(`${logger_color.gray("➜")} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
1549
+ summary.push(`${logger_color.gray(POINTER)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
1260
1550
  for (const key of uncheckedFile.keys)summary.push(` ${key}`);
1261
1551
  }
1262
1552
  }
@@ -1293,7 +1583,7 @@ const printSummaryErrorLogs = async ({ testResults, results, rootPath, unhandled
1293
1583
  for (const test of failedTests){
1294
1584
  const relativePath = posix.relative(rootPath, test.testPath);
1295
1585
  const nameStr = getTaskNameWithPrefix(test);
1296
- logger_logger.stderr(`${bgColor('bgRed', ' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${logger_color.dim(">")} ${nameStr}` : ''}`);
1586
+ logger_logger.stderr(`${bgColor('bgRed', ' FAIL ')} ${prettyTestPath(relativePath)} ${nameStr.length ? `${logger_color.dim(TEST_DELIMITER)} ${nameStr}` : ''}`);
1297
1587
  if (test.errors) {
1298
1588
  const { printError } = await Promise.resolve(error_namespaceObject);
1299
1589
  for (const error of test.errors)await printError(error, getSourcemap, rootPath);
@@ -1450,7 +1740,7 @@ class StatusRenderer {
1450
1740
  const relativePath = relative(this.rootPath, module);
1451
1741
  summary.push(`${bgColor('bgYellow', ' RUNS ')} ${prettyTestPath(relativePath)}`);
1452
1742
  if (runningTests.length && shouldDisplayRunningTests(runningTests)) {
1453
- let caseLog = ` ${logger_color.gray("➜")} ${getTaskNameWithPrefix(runningTests[0])} ${logger_color.magenta(prettyTime(now - runningTests[0].startTime))}`;
1743
+ let caseLog = ` ${logger_color.gray(POINTER)} ${getTaskNameWithPrefix(runningTests[0])} ${logger_color.magenta(prettyTime(now - runningTests[0].startTime))}`;
1454
1744
  if (runningTests.length > 1) caseLog += logger_color.gray(` and ${runningTests.length - 1} more cases`);
1455
1745
  summary.push(caseLog);
1456
1746
  }
@@ -1613,7 +1903,7 @@ class BlobReporter {
1613
1903
  const shard = this.config.shard;
1614
1904
  const fileName = shard ? `blob-${shard.index}-${shard.count}.json` : 'blob.json';
1615
1905
  const blobData = {
1616
- version: "0.9.3",
1906
+ version: "0.9.5",
1617
1907
  shard: shard ? {
1618
1908
  index: shard.index,
1619
1909
  count: shard.count
@@ -1657,7 +1947,7 @@ class GithubActionsReporter {
1657
1947
  const { testPath } = test;
1658
1948
  const nameStr = getTaskNameWithPrefix(test);
1659
1949
  const shortPath = relative(this.rootPath, testPath);
1660
- const title = `${shortPath} > ${nameStr}`;
1950
+ const title = `${shortPath} ${TEST_DELIMITER} ${nameStr}`;
1661
1951
  for (const error of test.errors || []){
1662
1952
  let file = testPath;
1663
1953
  let line = 1;
@@ -2004,7 +2294,7 @@ function traceSegmentInternal(segments, memo, line, column, bias) {
2004
2294
  const isRelativePath = (p)=>/^\.\.?\//.test(p);
2005
2295
  const isHttpLikeFile = (file)=>/^https?:\/\//.test(file);
2006
2296
  const hintNotDefinedError = (message)=>{
2007
- const [, varName] = message.match(/(\w+) is not defined/) || [];
2297
+ const [, varName] = /(\w+) is not defined/.exec(message) || [];
2008
2298
  if (varName) {
2009
2299
  if (globalApis.includes(varName)) return message.replace(`${varName} is not defined`, `${varName} is not defined. Did you forget to enable "globals" configuration?`);
2010
2300
  if ([
@@ -2083,10 +2373,15 @@ const stackIgnores = [
2083
2373
  '<anonymous>'
2084
2374
  ];
2085
2375
  async function error_parseErrorStacktrace({ stack, getSourcemap, fullStack = isDebug() }) {
2376
+ const traceMapCache = new Map();
2086
2377
  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)=>{
2087
2378
  const sourcemap = await getSourcemap?.(frame.file);
2088
2379
  if (sourcemap) {
2089
- const traceMap = new TraceMap(sourcemap);
2380
+ let traceMap = traceMapCache.get(frame.file);
2381
+ if (!traceMap) {
2382
+ traceMap = new TraceMap(sourcemap);
2383
+ traceMapCache.set(frame.file, traceMap);
2384
+ }
2090
2385
  const { line, column, source, name } = originalPositionFor(traceMap, {
2091
2386
  line: frame.lineNumber,
2092
2387
  column: frame.column
@@ -2977,7 +3272,7 @@ const formatFailureListValue = (value)=>{
2977
3272
  };
2978
3273
  const getErrorType = (error)=>{
2979
3274
  const rawName = error.name || 'Error';
2980
- if (/AssertionError/.test(rawName)) return 'AssertionError';
3275
+ if (rawName.includes('AssertionError')) return 'AssertionError';
2981
3276
  if (/\bSnapshot\b.*\bmismatched\b/i.test(error.message)) return 'SnapshotMismatchError';
2982
3277
  return rawName;
2983
3278
  };
@@ -3165,6 +3460,7 @@ const excludedRoots = (()=>{
3165
3460
  return resolvedRoots;
3166
3461
  })();
3167
3462
  const md_parseErrorStacktrace = async ({ stack, getSourcemap, fullStack = false })=>{
3463
+ const traceMapCache = new Map();
3168
3464
  const frames = stack_trace_parser_esm_parse(stack).filter((frame)=>{
3169
3465
  if (fullStack) return true;
3170
3466
  if (!frame.file) return false;
@@ -3182,7 +3478,11 @@ const md_parseErrorStacktrace = async ({ stack, getSourcemap, fullStack = false
3182
3478
  ...frame,
3183
3479
  file
3184
3480
  };
3185
- const traceMap = new TraceMap(sourcemap);
3481
+ let traceMap = traceMapCache.get(file);
3482
+ if (!traceMap) {
3483
+ traceMap = new TraceMap(sourcemap);
3484
+ traceMapCache.set(file, traceMap);
3485
+ }
3186
3486
  const { line, column, source, name } = originalPositionFor(traceMap, {
3187
3487
  line: frame.lineNumber || 1,
3188
3488
  column: frame.column || 1
@@ -3271,7 +3571,7 @@ class MdReporter {
3271
3571
  }
3272
3572
  renderFrontMatter(lines) {
3273
3573
  const frontMatter = {
3274
- tool: "@rstest/core@0.9.3",
3574
+ tool: "@rstest/core@0.9.5",
3275
3575
  timestamp: new Date().toISOString()
3276
3576
  };
3277
3577
  if (this.options.header.env) frontMatter.runtime = {
@@ -3415,10 +3715,10 @@ class MdReporter {
3415
3715
  getSourcemap,
3416
3716
  fullStack: false
3417
3717
  }) : [];
3418
- const fullFrames = error.stack ? await md_parseErrorStacktrace({
3718
+ const fullFrames = error.fullStack && error.stack ? await md_parseErrorStacktrace({
3419
3719
  stack: error.stack,
3420
3720
  getSourcemap,
3421
- fullStack: error.fullStack
3721
+ fullStack: true
3422
3722
  }) : candidateFrames;
3423
3723
  const trimmedFrames = resolveStackFrames(fullFrames, this.options);
3424
3724
  const topFrame = fullFrames[0] ?? candidateFrames[0];
@@ -3645,7 +3945,7 @@ class Rstest {
3645
3945
  updateSnapshot: rstestConfig.update ? 'all' : dist_m ? 'none' : 'new'
3646
3946
  });
3647
3947
  this.snapshotManager = snapshotManager;
3648
- this.version = "0.9.3";
3948
+ this.version = "0.9.5";
3649
3949
  this.rootPath = rootPath;
3650
3950
  this.originalConfig = userConfig;
3651
3951
  this.normalizedConfig = rstestConfig;
@@ -3784,4 +4084,4 @@ function defineConfig(config) {
3784
4084
  function defineProject(config) {
3785
4085
  return config;
3786
4086
  }
3787
- export { config_loadConfig as loadConfig, core_createRstest as createRstest, defineConfig, defineProject, detect, error_parseErrorStacktrace as parseErrorStacktrace, error_printError as printError, formatStack, init_initCli as initCli, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };
4087
+ export { config_loadConfig as loadConfig, core_createRstest as createRstest, core_namespaceObject, defineConfig, defineProject, detect, error_parseErrorStacktrace as parseErrorStacktrace, error_printError as printError, formatStack, init_initCli as initCli, init_namespaceObject, mergeProjectConfig, mergeRstestConfig, resolveCommand, runCLI, runRest };