@rstest/core 0.3.3 → 0.4.0

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/worker.js CHANGED
@@ -1,22 +1,18 @@
1
1
  /*! For license information please see worker.js.LICENSE.txt */
2
2
  import __rslib_shim_module__ from 'module';
3
3
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(import.meta.url);
4
- import node_process from "node:process";
5
- import * as __WEBPACK_EXTERNAL_MODULE_chai__ from "chai";
6
- import * as __WEBPACK_EXTERNAL_MODULE_node_assert_3e74d44e__ from "node:assert";
7
- import * as __WEBPACK_EXTERNAL_MODULE_node_console_8631dfae__ from "node:console";
8
4
  import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
9
- import * as __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__ from "node:fs/promises";
10
5
  import * as __WEBPACK_EXTERNAL_MODULE_node_module_ab9f2194__ from "node:module";
11
6
  import * as __WEBPACK_EXTERNAL_MODULE_node_os_74b4b876__ from "node:os";
12
7
  import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
13
8
  import * as __WEBPACK_EXTERNAL_MODULE_node_tty_c64aab7e__ from "node:tty";
14
9
  import * as __WEBPACK_EXTERNAL_MODULE_node_util_1b29d436__ from "node:util";
15
10
  import * as __WEBPACK_EXTERNAL_MODULE_pathe__ from "pathe";
16
- import { pathToFileURL } from "node:url";
17
- import node_vm from "node:vm";
18
- import node_v8 from "node:v8";
19
- import { createBirpc } from "birpc";
11
+ import * as __WEBPACK_EXTERNAL_MODULE_node_process_786449bf__ from "node:process";
12
+ import * as __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__ from "node:url";
13
+ import * as __WEBPACK_EXTERNAL_MODULE_node_vm_bd3d9cea__ from "node:vm";
14
+ import * as __WEBPACK_EXTERNAL_MODULE_node_v8_d0df5498__ from "node:v8";
15
+ import * as __WEBPACK_EXTERNAL_MODULE_birpc__ from "birpc";
20
16
  var __webpack_modules__ = {
21
17
  "../../node_modules/.pnpm/@jest+diff-sequences@30.0.1/node_modules/@jest/diff-sequences/build/index.js": function(module) {
22
18
  /*!
@@ -335,7 +331,7 @@ var __webpack_modules__ = {
335
331
  module.exports = __nested_webpack_exports__;
336
332
  })();
337
333
  },
338
- "../../node_modules/.pnpm/@jest+get-type@30.0.1/node_modules/@jest/get-type/build/index.js": function(module) {
334
+ "../../node_modules/.pnpm/@jest+get-type@30.1.0/node_modules/@jest/get-type/build/index.js": function(module) {
339
335
  /*!
340
336
  * /**
341
337
  * * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -2880,7 +2876,7 @@ var __webpack_modules__ = {
2880
2876
  return -1 !== position && (-1 === terminatorPosition || position < terminatorPosition);
2881
2877
  };
2882
2878
  },
2883
- "../../node_modules/.pnpm/jest-diff@30.0.5/node_modules/jest-diff/build/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
2879
+ "../../node_modules/.pnpm/jest-diff@30.1.2/node_modules/jest-diff/build/index.js": function(module, __unused_webpack_exports, __webpack_require__) {
2884
2880
  /*!
2885
2881
  * /**
2886
2882
  * * Copyright (c) Meta Platforms, Inc. and affiliates.
@@ -3744,7 +3740,7 @@ var __webpack_modules__ = {
3744
3740
  }
3745
3741
  });
3746
3742
  var _chalk = _interopRequireDefault(__webpack_require__("../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js"));
3747
- var _getType = __webpack_require__("../../node_modules/.pnpm/@jest+get-type@30.0.1/node_modules/@jest/get-type/build/index.js");
3743
+ var _getType = __webpack_require__("../../node_modules/.pnpm/@jest+get-type@30.1.0/node_modules/@jest/get-type/build/index.js");
3748
3744
  var _prettyFormat = __webpack_require__("../../node_modules/.pnpm/pretty-format@30.0.5/node_modules/pretty-format/build/index.js");
3749
3745
  var _cleanupSemantic = __nested_webpack_require_48295__("./src/cleanupSemantic.ts");
3750
3746
  var _constants = __nested_webpack_require_48295__("./src/constants.ts");
@@ -4976,7 +4972,7 @@ var __webpack_modules__ = {
4976
4972
  });
4977
4973
  var external_node_module_ = __webpack_require__("node:module");
4978
4974
  var external_node_util_ = __webpack_require__("node:util");
4979
- var build = __webpack_require__("../../node_modules/.pnpm/jest-diff@30.0.5/node_modules/jest-diff/build/index.js");
4975
+ var build = __webpack_require__("../../node_modules/.pnpm/jest-diff@30.1.2/node_modules/jest-diff/build/index.js");
4980
4976
  build.DIFF_DELETE;
4981
4977
  build.DIFF_EQUAL;
4982
4978
  build.DIFF_INSERT;
@@ -5066,10 +5062,8 @@ var __webpack_modules__ = {
5066
5062
  "./src/utils/constants.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5067
5063
  __webpack_require__.d(__webpack_exports__, {
5068
5064
  TE: ()=>globalApis,
5069
- q_: ()=>ROOT_SUITE_NAME,
5070
- vO: ()=>TEST_DELIMITER
5065
+ q_: ()=>ROOT_SUITE_NAME
5071
5066
  });
5072
- const TEST_DELIMITER = '>';
5073
5067
  const ROOT_SUITE_NAME = 'Rstest:_internal_root_suite';
5074
5068
  const globalApis = [
5075
5069
  'test',
@@ -5099,7 +5093,7 @@ var __webpack_modules__ = {
5099
5093
  __webpack_require__("pathe");
5100
5094
  var picocolors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
5101
5095
  var picocolors__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/ __webpack_require__.n(picocolors__WEBPACK_IMPORTED_MODULE_2__);
5102
- var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/utils/constants.ts");
5096
+ __webpack_require__("./src/utils/constants.ts");
5103
5097
  const isObject = (obj)=>'[object Object]' === Object.prototype.toString.call(obj);
5104
5098
  const castArray = (arr)=>{
5105
5099
  if (void 0 === arr) return [];
@@ -5126,7 +5120,7 @@ var __webpack_modules__ = {
5126
5120
  return time;
5127
5121
  };
5128
5122
  const getTaskNames = (test)=>(test.parentNames || []).concat(test.name).filter(Boolean);
5129
- const getTaskNameWithPrefix = (test, delimiter = _constants__WEBPACK_IMPORTED_MODULE_1__.vO)=>getTaskNames(test).join(` ${delimiter} `);
5123
+ const getTaskNameWithPrefix = (test, delimiter = ">")=>getTaskNames(test).join(` ${delimiter} `);
5130
5124
  const REGEXP_FLAG_PREFIX = 'RSTEST_REGEXP:';
5131
5125
  const unwrapRegex = (value)=>{
5132
5126
  if (value.startsWith(REGEXP_FLAG_PREFIX)) {
@@ -5153,13 +5147,13 @@ var __webpack_modules__ = {
5153
5147
  });
5154
5148
  var external_node_os_ = __webpack_require__("node:os");
5155
5149
  var external_node_tty_ = __webpack_require__("node:tty");
5156
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : node_process.argv) {
5150
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : __WEBPACK_EXTERNAL_MODULE_node_process_786449bf__["default"].argv) {
5157
5151
  const prefix = flag.startsWith('-') ? '' : 1 === flag.length ? '-' : '--';
5158
5152
  const position = argv.indexOf(prefix + flag);
5159
5153
  const terminatorPosition = argv.indexOf('--');
5160
5154
  return -1 !== position && (-1 === terminatorPosition || position < terminatorPosition);
5161
5155
  }
5162
- const { env } = node_process;
5156
+ const { env } = __WEBPACK_EXTERNAL_MODULE_node_process_786449bf__["default"];
5163
5157
  let flagForceColor;
5164
5158
  if (hasFlag('no-color') || hasFlag('no-colors') || hasFlag('color=false') || hasFlag('color=never')) flagForceColor = 0;
5165
5159
  else if (hasFlag('color') || hasFlag('colors') || hasFlag('color=true') || hasFlag('color=always')) flagForceColor = 1;
@@ -5199,7 +5193,7 @@ var __webpack_modules__ = {
5199
5193
  if (haveStream && !streamIsTTY && void 0 === forceColor) return 0;
5200
5194
  const min = forceColor || 0;
5201
5195
  if ('dumb' === env.TERM) return min;
5202
- if ('win32' === node_process.platform) {
5196
+ if ('win32' === __WEBPACK_EXTERNAL_MODULE_node_process_786449bf__["default"].platform) {
5203
5197
  const osRelease = external_node_os_["default"].release().split('.');
5204
5198
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
5205
5199
  return 1;
@@ -5431,21 +5425,9 @@ var __webpack_modules__ = {
5431
5425
  "timers/promises": function(module) {
5432
5426
  module.exports = require("timers/promises");
5433
5427
  },
5434
- chai: function(module) {
5435
- module.exports = __WEBPACK_EXTERNAL_MODULE_chai__;
5436
- },
5437
- "node:assert": function(module) {
5438
- module.exports = __WEBPACK_EXTERNAL_MODULE_node_assert_3e74d44e__;
5439
- },
5440
- "node:console": function(module) {
5441
- module.exports = __WEBPACK_EXTERNAL_MODULE_node_console_8631dfae__;
5442
- },
5443
5428
  "node:fs": function(module) {
5444
5429
  module.exports = __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__;
5445
5430
  },
5446
- "node:fs/promises": function(module) {
5447
- module.exports = __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__;
5448
- },
5449
5431
  "node:module": function(module) {
5450
5432
  module.exports = __WEBPACK_EXTERNAL_MODULE_node_module_ab9f2194__;
5451
5433
  },
@@ -5531,7 +5513,7 @@ __webpack_require__.m = __webpack_modules__;
5531
5513
  }, []));
5532
5514
  })();
5533
5515
  (()=>{
5534
- __webpack_require__.u = (chunkId)=>"" + chunkId + ".js";
5516
+ __webpack_require__.u = (chunkId)=>"0~" + chunkId + ".js";
5535
5517
  })();
5536
5518
  (()=>{
5537
5519
  __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
@@ -5591,10 +5573,41 @@ __webpack_require__.m = __webpack_modules__;
5591
5573
  };
5592
5574
  })();
5593
5575
  __webpack_require__("./src/runtime/worker/setup.ts");
5576
+ var external_node_module_ = __webpack_require__("node:module");
5577
+ const CoverageProviderMap = {
5578
+ istanbul: '@rstest/coverage-istanbul'
5579
+ };
5580
+ const loadCoverageProvider = async (options, root)=>{
5581
+ const rootPath = (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.pathToFileURL)(root).toString();
5582
+ const moduleName = CoverageProviderMap[options.provider || 'istanbul'];
5583
+ if (!moduleName) throw new Error(`Unknown coverage provider: ${options.provider}`);
5584
+ try {
5585
+ const require = (0, external_node_module_.createRequire)(rootPath);
5586
+ const modulePath = require.resolve(moduleName, {
5587
+ paths: [
5588
+ rootPath
5589
+ ]
5590
+ });
5591
+ const { pluginCoverage, CoverageProvider } = await import((0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.pathToFileURL)(modulePath).toString());
5592
+ return {
5593
+ pluginCoverage,
5594
+ CoverageProvider
5595
+ };
5596
+ } catch (error) {
5597
+ throw new Error(`Failed to load coverage provider module: ${moduleName} in ${root}. Make sure it is installed.\nOriginal error: ${error.message}`);
5598
+ }
5599
+ };
5600
+ async function createCoverageProvider(options, root) {
5601
+ if (!options.enabled) return null;
5602
+ if (!options.provider || CoverageProviderMap[options.provider]) {
5603
+ const { CoverageProvider } = await loadCoverageProvider(options, root);
5604
+ return new CoverageProvider(options);
5605
+ }
5606
+ throw new Error(`Unknown coverage provider: ${options.provider}`);
5607
+ }
5594
5608
  var constants = __webpack_require__("./src/utils/constants.ts");
5595
5609
  var helper = __webpack_require__("./src/utils/helper.ts");
5596
5610
  var util = __webpack_require__("./src/runtime/util.ts");
5597
- var external_node_module_ = __webpack_require__("node:module");
5598
5611
  var external_node_path_ = __webpack_require__("node:path");
5599
5612
  var external_pathe_ = __webpack_require__("pathe");
5600
5613
  var logger = __webpack_require__("./src/utils/logger.ts");
@@ -5673,7 +5686,7 @@ const createRequire = (filename, distPath, rstestContext, assetFiles, interopDef
5673
5686
  return require;
5674
5687
  };
5675
5688
  const defineRstestDynamicImport = ({ testPath, interopDefault, returnModule = false })=>async (specifier, importAttributes)=>{
5676
- const resolvedPath = (0, external_node_path_.isAbsolute)(specifier) ? pathToFileURL(specifier) : import.meta.resolve(specifier, pathToFileURL(testPath));
5689
+ const resolvedPath = (0, external_node_path_.isAbsolute)(specifier) ? (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.pathToFileURL)(specifier) : import.meta.resolve(specifier, (0, __WEBPACK_EXTERNAL_MODULE_node_url_e96de089__.pathToFileURL)(testPath));
5677
5690
  const modulePath = 'string' == typeof resolvedPath ? resolvedPath : resolvedPath.pathname;
5678
5691
  if (importAttributes?.with?.rstest) delete importAttributes.with.rstest;
5679
5692
  const importedModule = await import(modulePath, importAttributes);
@@ -5731,7 +5744,7 @@ const loadModule = ({ codeContent, distPath, testPath, rstestContext, assetFiles
5731
5744
  };
5732
5745
  const codeDefinition = `'use strict';(${Object.keys(context).join(',')})=>{`;
5733
5746
  const code = `${codeDefinition}${codeContent}\n}`;
5734
- const fn = node_vm.runInThisContext(code, {
5747
+ const fn = __WEBPACK_EXTERNAL_MODULE_node_vm_bd3d9cea__["default"].runInThisContext(code, {
5735
5748
  filename: distPath,
5736
5749
  lineOffset: 0,
5737
5750
  columnOffset: -codeDefinition.length,
@@ -5762,7 +5775,7 @@ const processSend = process.send.bind(process);
5762
5775
  const processOn = process.on.bind(process);
5763
5776
  const processOff = process.off.bind(process);
5764
5777
  const dispose = [];
5765
- function createForksRpcOptions(nodeV8 = node_v8) {
5778
+ function createForksRpcOptions(nodeV8 = __WEBPACK_EXTERNAL_MODULE_node_v8_d0df5498__["default"]) {
5766
5779
  return {
5767
5780
  serialize: nodeV8.serialize,
5768
5781
  deserialize: (v)=>nodeV8.deserialize(Buffer.from(v)),
@@ -5780,7 +5793,7 @@ function createForksRpcOptions(nodeV8 = node_v8) {
5780
5793
  };
5781
5794
  }
5782
5795
  function createRuntimeRpc(options) {
5783
- const rpc = createBirpc({}, options);
5796
+ const rpc = (0, __WEBPACK_EXTERNAL_MODULE_birpc__.createBirpc)({}, options);
5784
5797
  return {
5785
5798
  rpc
5786
5799
  };
@@ -5826,8 +5839,8 @@ class RstestSnapshotEnvironment extends NodeSnapshotEnvironment {
5826
5839
  return `// Rstest Snapshot v${this.getVersion()}`;
5827
5840
  }
5828
5841
  }
5829
- const getGlobalApi = (api)=>constants.TE.reduce((apis, key)=>{
5830
- apis[key] = api[key];
5842
+ const registerGlobalApi = (api)=>constants.TE.reduce((apis, key)=>{
5843
+ globalThis[key] = api[key];
5831
5844
  return apis;
5832
5845
  }, {});
5833
5846
  const listeners = [];
@@ -5839,7 +5852,7 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, upda
5839
5852
  const { rpc } = createRuntimeRpc(createForksRpcOptions());
5840
5853
  const { runtimeConfig: { globals, printConsoleTrace, disableConsoleIntercept, testEnvironment } } = context;
5841
5854
  if (!disableConsoleIntercept) {
5842
- const { createCustomConsole } = await __webpack_require__.e("607").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/console.ts"));
5855
+ const { createCustomConsole } = await __webpack_require__.e("493").then(__webpack_require__.bind(__webpack_require__, "./src/runtime/worker/console.ts"));
5843
5856
  global.console = createCustomConsole({
5844
5857
  rpc,
5845
5858
  testPath,
@@ -5916,11 +5929,11 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, sourceMaps, upda
5916
5929
  default:
5917
5930
  throw new Error(`Unknown test environment: ${testEnvironment}`);
5918
5931
  }
5932
+ if (globals) registerGlobalApi(api);
5919
5933
  const rstestContext = {
5920
5934
  global,
5921
5935
  console: global.console,
5922
- Error,
5923
- ...globals ? getGlobalApi(api) : {}
5936
+ Error
5924
5937
  };
5925
5938
  rstestContext.global['@rstest/core'] = api;
5926
5939
  return {
@@ -6018,6 +6031,8 @@ const runInPool = async (options)=>{
6018
6031
  }
6019
6032
  try {
6020
6033
  const { rstestContext, runner, rpc, api, cleanup, unhandledErrors, interopDefault } = await preparePool(options);
6034
+ const coverageProvider = await createCoverageProvider(options.context.runtimeConfig.coverage || {}, options.context.rootPath);
6035
+ if (coverageProvider) coverageProvider.init();
6021
6036
  cleanups.push(cleanup);
6022
6037
  await loadFiles({
6023
6038
  rstestContext,
@@ -6033,6 +6048,10 @@ const runInPool = async (options)=>{
6033
6048
  await rpc.onTestFileStart(test);
6034
6049
  },
6035
6050
  onTestFileResult: async (test)=>{
6051
+ if (coverageProvider) {
6052
+ const coverageMap = coverageProvider.collect();
6053
+ if (coverageMap) test.coverage = coverageMap.toJSON();
6054
+ }
6036
6055
  await rpc.onTestFileResult(test);
6037
6056
  },
6038
6057
  onTestCaseResult: async (result)=>{
@@ -1,5 +1,8 @@
1
1
  import type { assert as assert_2 } from 'chai';
2
+ import type { CoverageMap } from 'istanbul-lib-coverage';
3
+ import type { ReportOptions } from 'istanbul-reports';
2
4
  import type { RsbuildConfig } from '@rsbuild/core';
5
+ import { RsbuildPlugin } from '@rsbuild/core';
3
6
 
4
7
  /**
5
8
  * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
@@ -328,6 +331,80 @@ declare class CounterMap<K> extends DefaultMap<K, number> {
328
331
  total(): number;
329
332
  }
330
333
 
334
+ export declare type CoverageOptions = {
335
+ /**
336
+ * Enable coverage collection.
337
+ * @default false
338
+ */
339
+ enabled?: boolean;
340
+ /**
341
+ * A list of glob patterns that should be excluded from coverage collection.
342
+ *
343
+ * This option accepts an array of wax(https://crates.io/crates/wax)-compatible glob patterns
344
+ *
345
+ * @default ['**\/node_modules/**',
346
+ * '**\/dist/**',
347
+ * '**\/test/**',
348
+ * '**\/__tests__/**',
349
+ * '**\/*.{test,spec}.?(c|m)[jt]s?(x)',
350
+ * '**\/__mocks__/**'
351
+ * ]
352
+ */
353
+ exclude?: string[];
354
+ /**
355
+ * The provider to use for coverage collection.
356
+ * @default 'istanbul'
357
+ */
358
+ provider?: 'istanbul';
359
+ /**
360
+ * The reporters to use for coverage collection.
361
+ * @default ['text', 'html', 'clover', 'json']
362
+ */
363
+ reporters?: (keyof ReportOptions | ReportWithOptions)[];
364
+ /**
365
+ * The directory to store coverage reports.
366
+ * @default './coverage'
367
+ */
368
+ reportsDirectory?: string;
369
+ /**
370
+ * Whether to clean the coverage directory before running tests.
371
+ * @default true
372
+ */
373
+ clean?: boolean;
374
+ /**
375
+ * Coverage thresholds
376
+ *
377
+ * @default undefined
378
+ */
379
+ thresholds?: CoverageThresholds;
380
+ };
381
+
382
+ export declare class CoverageProvider {
383
+ constructor(options: CoverageOptions);
384
+ /**
385
+ * Initialize coverage collection
386
+ */
387
+ init(): void;
388
+ /**
389
+ * Collect coverage data from global coverage object
390
+ */
391
+ collect(): CoverageMap | null;
392
+ /**
393
+ * Create a new coverage map
394
+ */
395
+ createCoverageMap(): CoverageMap;
396
+ /**
397
+ * Generate coverage reports
398
+ */
399
+ generateReports(coverageMap: CoverageMap, options: CoverageOptions): Promise<void>;
400
+ /**
401
+ * Clean up coverage data
402
+ */
403
+ cleanup(): void;
404
+ }
405
+
406
+ declare type CoverageThresholds = Thresholds;
407
+
331
408
  declare interface CustomMatcher {
332
409
  /**
333
410
  * Checks that a value satisfies a custom matcher function.
@@ -1589,18 +1666,23 @@ declare interface NewPlugin {
1589
1666
  test: Test;
1590
1667
  }
1591
1668
 
1592
- declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool' | 'projects'>> & {
1669
+ declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool' | 'projects' | 'coverage'>> & {
1593
1670
  [key in OptionalKeys]?: RstestConfig[key];
1594
1671
  } & {
1595
1672
  pool: RstestPoolOptions;
1673
+ coverage: NormalizedCoverageOptions;
1674
+ };
1675
+
1676
+ export declare type NormalizedCoverageOptions = Required<Omit<CoverageOptions, 'thresholds'>> & {
1677
+ thresholds?: CoverageThresholds;
1596
1678
  };
1597
1679
 
1598
1680
  declare type NormalizedProcedure<T extends Procedure> = (...args: Parameters<T>) => ReturnType<T>;
1599
1681
 
1600
1682
  declare type NormalizedProcedure_2<T extends Procedure_2> = (...args: Parameters<T>) => ReturnType<T>;
1601
1683
 
1602
- declare type NormalizedProjectConfig = Required<Omit<RstestConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1603
- [key in OptionalKeys]?: RstestConfig[key];
1684
+ declare type NormalizedProjectConfig = Required<Omit<NormalizedConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1685
+ [key in OptionalKeys]?: NormalizedConfig[key];
1604
1686
  };
1605
1687
 
1606
1688
  declare interface OldPlugin {
@@ -1676,11 +1758,12 @@ declare type Procedure = (...args: any[]) => any;
1676
1758
 
1677
1759
  declare type Procedure_2 = (...args: any[]) => any;
1678
1760
 
1679
- export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate'>;
1761
+ export declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage'>;
1680
1762
 
1681
1763
  declare type ProjectContext = {
1682
1764
  name: string;
1683
1765
  environmentName: string;
1766
+ /** The root path of current project. */
1684
1767
  rootPath: string;
1685
1768
  configFilePath?: string;
1686
1769
  normalizedConfig: NormalizedProjectConfig;
@@ -1754,6 +1837,8 @@ declare const reportersMap: {
1754
1837
 
1755
1838
  declare type ReporterWithOptions<Name extends BuiltInReporterNames = BuiltInReporterNames> = Name extends keyof BuiltinReporterOptions ? [Name, Partial<BuiltinReporterOptions[Name]>] : [Name, Record<string, unknown>];
1756
1839
 
1840
+ declare type ReportWithOptions<Name extends keyof ReportOptions = keyof ReportOptions> = Name extends keyof ReportOptions ? [Name, Partial<ReportOptions[Name]>] : [Name, Record<string, unknown>];
1841
+
1757
1842
  declare type Ro<T> = T extends Array<infer V> ? V[] | Readonly<V[]> | RoArray<V> | Readonly<RoArray<V>> : T extends object ? T | Readonly<T> | RoObject<T> | Readonly<RoObject<T>> : T;
1758
1843
 
1759
1844
  declare type RoArray<T> = Ro<T>[];
@@ -1764,6 +1849,8 @@ declare type RoObject<T> = {
1764
1849
 
1765
1850
  export declare const rs: RstestUtilities;
1766
1851
 
1852
+ export { RsbuildPlugin }
1853
+
1767
1854
  declare type Rstest = RunnerAPI & {
1768
1855
  expect: RstestExpect;
1769
1856
  assert: typeof assert_2;
@@ -1923,6 +2010,10 @@ export declare interface RstestConfig {
1923
2010
  * Custom handler for console log in tests
1924
2011
  */
1925
2012
  onConsoleLog?: (content: string) => boolean | void;
2013
+ /**
2014
+ * Coverage options
2015
+ */
2016
+ coverage?: CoverageOptions;
1926
2017
  plugins?: RsbuildConfig['plugins'];
1927
2018
  source?: Pick<NonNullable<RsbuildConfig['source']>, 'define' | 'tsconfigPath' | 'decorators' | 'include' | 'exclude'>;
1928
2019
  performance?: Pick<NonNullable<RsbuildConfig['performance']>, 'bundleAnalyze'>;
@@ -1941,7 +2032,7 @@ export declare type RstestConfigSyncFn = () => RstestConfig;
1941
2032
  declare type RstestContext = {
1942
2033
  /** The Rstest core version. */
1943
2034
  version: string;
1944
- /** The root path of current project. */
2035
+ /** The root path of rstest. */
1945
2036
  rootPath: string;
1946
2037
  /** The original Rstest config passed from the createRstest method. */
1947
2038
  originalConfig: Readonly<RstestConfig>;
@@ -1958,8 +2049,9 @@ declare type RstestContext = {
1958
2049
  /**
1959
2050
  * The command type.
1960
2051
  *
1961
- * - dev: `rstest dev`
1962
- * - run: `rstest run`
2052
+ * - run: `rstest`
2053
+ * - dev: `rstest dev` or watch mode
2054
+ * - list: `rstest list`
1963
2055
  */
1964
2056
  command: RstestCommand;
1965
2057
  reporters: Reporter[];
@@ -2119,7 +2211,7 @@ declare type RunnerAPI = {
2119
2211
  onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
2120
2212
  };
2121
2213
 
2122
- declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout'>;
2214
+ declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage'>;
2123
2215
 
2124
2216
  declare type RuntimeOptions = Partial<Pick<RuntimeConfig, 'testTimeout' | 'hookTimeout' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'maxConcurrency' | 'retry'>>;
2125
2217
 
@@ -2397,6 +2489,17 @@ export declare type TestResult = {
2397
2489
 
2398
2490
  declare type TestResultStatus = 'skip' | 'pass' | 'fail' | 'todo';
2399
2491
 
2492
+ declare type Thresholds = {
2493
+ /** Thresholds for statements */
2494
+ statements?: number;
2495
+ /** Thresholds for functions */
2496
+ functions?: number;
2497
+ /** Thresholds for branches */
2498
+ branches?: number;
2499
+ /** Thresholds for lines */
2500
+ lines?: number;
2501
+ };
2502
+
2400
2503
  declare class TraceMap implements SourceMap {
2401
2504
  version: SourceMapV3['version'];
2402
2505
  file: SourceMapV3['file'];
@@ -1,3 +1,4 @@
1
+ import type { ReportOptions } from 'istanbul-reports';
1
2
  import type { RsbuildConfig } from '@rsbuild/core';
2
3
 
3
4
  /**
@@ -317,6 +318,56 @@ declare class CounterMap<K> extends DefaultMap<K, number> {
317
318
  total(): number;
318
319
  }
319
320
 
321
+ declare type CoverageOptions = {
322
+ /**
323
+ * Enable coverage collection.
324
+ * @default false
325
+ */
326
+ enabled?: boolean;
327
+ /**
328
+ * A list of glob patterns that should be excluded from coverage collection.
329
+ *
330
+ * This option accepts an array of wax(https://crates.io/crates/wax)-compatible glob patterns
331
+ *
332
+ * @default ['**\/node_modules/**',
333
+ * '**\/dist/**',
334
+ * '**\/test/**',
335
+ * '**\/__tests__/**',
336
+ * '**\/*.{test,spec}.?(c|m)[jt]s?(x)',
337
+ * '**\/__mocks__/**'
338
+ * ]
339
+ */
340
+ exclude?: string[];
341
+ /**
342
+ * The provider to use for coverage collection.
343
+ * @default 'istanbul'
344
+ */
345
+ provider?: 'istanbul';
346
+ /**
347
+ * The reporters to use for coverage collection.
348
+ * @default ['text', 'html', 'clover', 'json']
349
+ */
350
+ reporters?: (keyof ReportOptions | ReportWithOptions)[];
351
+ /**
352
+ * The directory to store coverage reports.
353
+ * @default './coverage'
354
+ */
355
+ reportsDirectory?: string;
356
+ /**
357
+ * Whether to clean the coverage directory before running tests.
358
+ * @default true
359
+ */
360
+ clean?: boolean;
361
+ /**
362
+ * Coverage thresholds
363
+ *
364
+ * @default undefined
365
+ */
366
+ thresholds?: CoverageThresholds;
367
+ };
368
+
369
+ declare type CoverageThresholds = Thresholds;
370
+
320
371
  declare interface CustomMatcher {
321
372
  /**
322
373
  * Checks that a value satisfies a custom matcher function.
@@ -1363,10 +1414,15 @@ declare interface NewPlugin {
1363
1414
  test: Test;
1364
1415
  }
1365
1416
 
1366
- declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool' | 'projects'>> & {
1417
+ declare type NormalizedConfig = Required<Omit<RstestConfig, OptionalKeys | 'pool' | 'projects' | 'coverage'>> & {
1367
1418
  [key in OptionalKeys]?: RstestConfig[key];
1368
1419
  } & {
1369
1420
  pool: RstestPoolOptions;
1421
+ coverage: NormalizedCoverageOptions;
1422
+ };
1423
+
1424
+ declare type NormalizedCoverageOptions = Required<Omit<CoverageOptions, 'thresholds'>> & {
1425
+ thresholds?: CoverageThresholds;
1370
1426
  };
1371
1427
 
1372
1428
  declare type NormalizedFixture = {
@@ -1380,8 +1436,8 @@ declare type NormalizedFixtures = Record<string, NormalizedFixture>;
1380
1436
 
1381
1437
  declare type NormalizedProcedure<T extends Procedure> = (...args: Parameters<T>) => ReturnType<T>;
1382
1438
 
1383
- declare type NormalizedProjectConfig = Required<Omit<RstestConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1384
- [key in OptionalKeys]?: RstestConfig[key];
1439
+ declare type NormalizedProjectConfig = Required<Omit<NormalizedConfig, OptionalKeys | 'projects' | 'reporters' | 'pool'>> & {
1440
+ [key in OptionalKeys]?: NormalizedConfig[key];
1385
1441
  };
1386
1442
 
1387
1443
  declare interface OldPlugin {
@@ -1451,11 +1507,12 @@ declare function printWithType<T>(name: string, value: T, print: (value: T) => s
1451
1507
 
1452
1508
  declare type Procedure = (...args: any[]) => any;
1453
1509
 
1454
- declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate'>;
1510
+ declare type ProjectConfig = Omit<RstestConfig, 'projects' | 'reporters' | 'pool' | 'isolate' | 'coverage'>;
1455
1511
 
1456
1512
  declare type ProjectContext = {
1457
1513
  name: string;
1458
1514
  environmentName: string;
1515
+ /** The root path of current project. */
1459
1516
  rootPath: string;
1460
1517
  configFilePath?: string;
1461
1518
  normalizedConfig: NormalizedProjectConfig;
@@ -1529,6 +1586,8 @@ declare const reportersMap: {
1529
1586
 
1530
1587
  declare type ReporterWithOptions<Name extends BuiltInReporterNames = BuiltInReporterNames> = Name extends keyof BuiltinReporterOptions ? [Name, Partial<BuiltinReporterOptions[Name]>] : [Name, Record<string, unknown>];
1531
1588
 
1589
+ declare type ReportWithOptions<Name extends keyof ReportOptions = keyof ReportOptions> = Name extends keyof ReportOptions ? [Name, Partial<ReportOptions[Name]>] : [Name, Record<string, unknown>];
1590
+
1532
1591
  declare type Ro<T> = T extends Array<infer V> ? V[] | Readonly<V[]> | RoArray<V> | Readonly<RoArray<V>> : T extends object ? T | Readonly<T> | RoObject<T> | Readonly<RoObject<T>> : T;
1533
1592
 
1534
1593
  declare type RoArray<T> = Ro<T>[];
@@ -1687,6 +1746,10 @@ declare interface RstestConfig {
1687
1746
  * Custom handler for console log in tests
1688
1747
  */
1689
1748
  onConsoleLog?: (content: string) => boolean | void;
1749
+ /**
1750
+ * Coverage options
1751
+ */
1752
+ coverage?: CoverageOptions;
1690
1753
  plugins?: RsbuildConfig['plugins'];
1691
1754
  source?: Pick<NonNullable<RsbuildConfig['source']>, 'define' | 'tsconfigPath' | 'decorators' | 'include' | 'exclude'>;
1692
1755
  performance?: Pick<NonNullable<RsbuildConfig['performance']>, 'bundleAnalyze'>;
@@ -1699,7 +1762,7 @@ declare interface RstestConfig {
1699
1762
  declare type RstestContext = {
1700
1763
  /** The Rstest core version. */
1701
1764
  version: string;
1702
- /** The root path of current project. */
1765
+ /** The root path of rstest. */
1703
1766
  rootPath: string;
1704
1767
  /** The original Rstest config passed from the createRstest method. */
1705
1768
  originalConfig: Readonly<RstestConfig>;
@@ -1716,8 +1779,9 @@ declare type RstestContext = {
1716
1779
  /**
1717
1780
  * The command type.
1718
1781
  *
1719
- * - dev: `rstest dev`
1720
- * - run: `rstest run`
1782
+ * - run: `rstest`
1783
+ * - dev: `rstest dev` or watch mode
1784
+ * - list: `rstest list`
1721
1785
  */
1722
1786
  command: RstestCommand;
1723
1787
  reporters: Reporter[];
@@ -1757,7 +1821,7 @@ declare type RunnerAPI = {
1757
1821
  onTestFailed: (fn: OnTestFailedHandler, timeout?: number) => void;
1758
1822
  };
1759
1823
 
1760
- declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout'>;
1824
+ declare type RuntimeConfig = Pick<RstestContext['normalizedConfig'], 'testTimeout' | 'testNamePattern' | 'globals' | 'passWithNoTests' | 'retry' | 'clearMocks' | 'resetMocks' | 'restoreMocks' | 'unstubEnvs' | 'unstubGlobals' | 'maxConcurrency' | 'printConsoleTrace' | 'disableConsoleIntercept' | 'testEnvironment' | 'isolate' | 'hookTimeout' | 'coverage'>;
1761
1825
 
1762
1826
  /** Runtime to Server */
1763
1827
  declare type RuntimeRPC = {
@@ -2122,6 +2186,17 @@ declare type TestSuite = {
2122
2186
  beforeEachListeners?: BeforeEachListener[];
2123
2187
  };
2124
2188
 
2189
+ declare type Thresholds = {
2190
+ /** Thresholds for statements */
2191
+ statements?: number;
2192
+ /** Thresholds for functions */
2193
+ functions?: number;
2194
+ /** Thresholds for branches */
2195
+ branches?: number;
2196
+ /** Thresholds for lines */
2197
+ lines?: number;
2198
+ };
2199
+
2125
2200
  declare class TraceMap implements SourceMap {
2126
2201
  version: SourceMapV3['version'];
2127
2202
  file: SourceMapV3['file'];
@@ -2167,6 +2242,7 @@ declare type WithAsymmetricMatcher<T> = T | AsymmetricMatcher<unknown>;
2167
2242
 
2168
2243
  declare type WorkerContext = {
2169
2244
  rootPath: RstestContext['rootPath'];
2245
+ projectRoot: ProjectContext['rootPath'];
2170
2246
  project: string;
2171
2247
  runtimeConfig: RuntimeConfig;
2172
2248
  };