@rstest/core 0.8.0 → 0.8.1

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/index.d.ts CHANGED
@@ -359,6 +359,17 @@ declare type CommonOptions = {
359
359
  config?: string;
360
360
  configLoader?: LoadConfigOptions['loader'];
361
361
  globals?: boolean;
362
+ /**
363
+ * Pool options.
364
+ * - `string`: shorthand for `{ type: string }` (from `--pool` flag)
365
+ * - `object`: detailed pool config (from `--pool.*` options)
366
+ */
367
+ pool?: string | {
368
+ type?: string;
369
+ maxWorkers?: string | number;
370
+ minWorkers?: string | number;
371
+ execArgv?: string[] | string;
372
+ };
362
373
  /**
363
374
  * Browser mode options.
364
375
  * - `boolean`: shorthand for `{ enabled: boolean }` (from `--browser` flag)
@@ -422,6 +433,8 @@ declare interface Constructable {
422
433
  new (...args: any[]): any;
423
434
  }
424
435
 
436
+ declare type Constructor<T = any> = new (...args: any[]) => T;
437
+
425
438
  /**
426
439
  * Base class for writing content
427
440
  */
@@ -1650,12 +1663,22 @@ declare interface MatcherState_2 extends MatcherState {
1650
1663
  snapshotState: SnapshotState;
1651
1664
  }
1652
1665
 
1666
+ declare type MaybeMockedDeep<T> = T extends Constructor ? MockedClass<T> : T extends MockProcedure ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
1667
+
1668
+ declare type MaybePartiallyMocked<T> = T extends Constructor ? MockedClass<T> : T extends MockProcedure ? MockedFunction<T> : T extends object ? MockedObject<T> : T;
1669
+
1670
+ declare type MaybePartiallyMockedDeep<T> = T extends Constructor ? MockedClass<T> : T extends MockProcedure ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T;
1671
+
1653
1672
  declare type MaybePromise<T> = T | Promise<T>;
1654
1673
 
1655
1674
  export declare const mergeProjectConfig: (...configs: ProjectConfig[]) => ProjectConfig;
1656
1675
 
1657
1676
  export declare const mergeRstestConfig: (...configs: RstestConfig[]) => RstestConfig;
1658
1677
 
1678
+ declare type Methods<T> = {
1679
+ [K in keyof T]: T[K] extends MockProcedure ? K : never;
1680
+ }[keyof T];
1681
+
1659
1682
  export declare interface Mock<T extends FunctionLike = FunctionLike> extends MockInstance_2<T> {
1660
1683
  new (...args: Parameters<T>): ReturnType<T>;
1661
1684
  (...args: Parameters<T>): ReturnType<T>;
@@ -1804,6 +1827,31 @@ declare type MockContext_2<T extends FunctionLike = FunctionLike> = {
1804
1827
  settledResults: MockSettledResult_2<Awaited<ReturnType<T>>>[];
1805
1828
  };
1806
1829
 
1830
+ export declare type Mocked<T> = T extends Constructor ? MockedClass<T> : T extends MockProcedure ? MockedFunction<T> : T extends object ? MockedObject<T> : T;
1831
+
1832
+ declare type MockedClass<T extends Constructor> = Mock<(...args: ConstructorParameters<T>) => InstanceType<T>> & {
1833
+ new (...args: ConstructorParameters<T>): InstanceType<T>;
1834
+ prototype: InstanceType<T>;
1835
+ };
1836
+
1837
+ declare type MockedFunction<T extends MockProcedure> = Mock<T> & {
1838
+ [K in keyof T]: T[K];
1839
+ };
1840
+
1841
+ declare type MockedFunctionDeep<T extends MockProcedure> = Mock<T> & MockedObjectDeep<T>;
1842
+
1843
+ declare type MockedObject<T> = {
1844
+ [K in Methods<T>]: T[K] extends MockProcedure ? MockedFunction<T[K]> : T[K];
1845
+ } & {
1846
+ [K in Properties<T>]: T[K];
1847
+ };
1848
+
1849
+ declare type MockedObjectDeep<T> = {
1850
+ [K in Methods<T>]: T[K] extends MockProcedure ? MockedFunctionDeep<T[K]> : T[K];
1851
+ } & {
1852
+ [K in Properties<T>]: MaybeMockedDeep<T[K]>;
1853
+ };
1854
+
1807
1855
  declare type MockFactory<T = unknown> = () => MaybePromise<Partial<T>>;
1808
1856
 
1809
1857
  declare type MockFn = <T extends FunctionLike = FunctionLike>(fn?: T) => Mock<T>;
@@ -2030,6 +2078,37 @@ declare interface MockInstance_2<T extends FunctionLike = FunctionLike> {
2030
2078
  mockRejectedValueOnce(error: unknown): this;
2031
2079
  }
2032
2080
 
2081
+ /**
2082
+ * Options for rs.mock module mocking.
2083
+ * Supports `{ spy: true }` or `{ mock: true }`.
2084
+ */
2085
+ declare type MockModuleOptions = {
2086
+ /**
2087
+ * If `true`, the module will be auto-mocked but the original implementations
2088
+ * will be preserved - all exports will be wrapped in spy functions that track calls.
2089
+ */
2090
+ spy: true;
2091
+ } | {
2092
+ /**
2093
+ * If `true`, the module will be auto-mocked with all exports replaced by mock functions.
2094
+ * Original implementations will NOT be preserved.
2095
+ */
2096
+ mock: true;
2097
+ };
2098
+
2099
+ /**
2100
+ * Options for mockObject
2101
+ */
2102
+ declare interface MockOptions {
2103
+ /**
2104
+ * If `true`, the original implementation will be kept.
2105
+ * All methods will call the original implementation, but you can still track the calls.
2106
+ */
2107
+ spy?: boolean;
2108
+ }
2109
+
2110
+ declare type MockProcedure = (...args: any[]) => any;
2111
+
2033
2112
  declare type MockResult<T> = MockResultReturn<T> | MockResultThrow | MockResultIncomplete;
2034
2113
 
2035
2114
  declare type MockResult_2<T> = MockResultReturn_2<T> | MockResultThrow_2 | MockResultIncomplete_2;
@@ -2273,6 +2352,10 @@ declare type PromisifyAssertion<T> = Promisify<Assertion_2<T>>;
2273
2352
 
2274
2353
  declare type PromisifyAssertion_2<T> = Promisify_2<Assertion<T>>;
2275
2354
 
2355
+ declare type Properties<T> = {
2356
+ [K in keyof T]: T[K] extends MockProcedure ? never : K;
2357
+ }[keyof T];
2358
+
2276
2359
  declare interface Range_2 {
2277
2360
  start: Location_3;
2278
2361
  end: Location_3;
@@ -2712,6 +2795,74 @@ export declare interface RstestUtilities {
2712
2795
  * Determines if the given function is a mocked function.
2713
2796
  */
2714
2797
  isMockFunction: (fn: any) => fn is MockInstance_2;
2798
+ /**
2799
+ * Deeply mocks properties and methods of a given object
2800
+ * in the same way as `rstest.mock()` mocks module exports.
2801
+ *
2802
+ * @example
2803
+ * ```ts
2804
+ * const original = {
2805
+ * simple: () => 'value',
2806
+ * nested: {
2807
+ * method: () => 'real'
2808
+ * },
2809
+ * prop: 'foo',
2810
+ * }
2811
+ *
2812
+ * const mocked = rstest.mockObject(original)
2813
+ * expect(mocked.simple()).toBe(undefined)
2814
+ * expect(mocked.nested.method()).toBe(undefined)
2815
+ * expect(mocked.prop).toBe('foo')
2816
+ *
2817
+ * mocked.simple.mockReturnValue('mocked')
2818
+ * expect(mocked.simple()).toBe('mocked')
2819
+ *
2820
+ * // With spy option to keep original implementations
2821
+ * const spied = rstest.mockObject(original, { spy: true })
2822
+ * expect(spied.simple()).toBe('value')
2823
+ * expect(spied.simple).toHaveBeenCalled()
2824
+ * ```
2825
+ *
2826
+ * @param value - The object to be mocked
2827
+ * @param options - Mock options
2828
+ * @returns A deeply mocked version of the input object
2829
+ */
2830
+ mockObject: <T>(value: T, options?: MockOptions) => MaybeMockedDeep<T>;
2831
+ /**
2832
+ * Type helper for TypeScript. Just returns the object that was passed.
2833
+ *
2834
+ * When `partial` is `true` it will expect a `Partial<T>` as a return value.
2835
+ * By default, this will only make TypeScript believe that the first level values are mocked.
2836
+ * You can pass down `{ deep: true }` as a second argument to tell TypeScript
2837
+ * that the whole object is mocked, if it actually is.
2838
+ *
2839
+ * @example
2840
+ * ```ts
2841
+ * import example from './example.js'
2842
+ *
2843
+ * rstest.mock('./example.js')
2844
+ *
2845
+ * test('1 + 1 equals 10', async () => {
2846
+ * rstest.mocked(example.calc).mockReturnValue(10)
2847
+ * expect(example.calc(1, '+', 1)).toBe(10)
2848
+ * })
2849
+ * ```
2850
+ * @param item - Anything that can be mocked
2851
+ * @returns The same item with mocked type
2852
+ */
2853
+ mocked: (<T>(item: T, deep?: false) => Mocked<T>) & (<T>(item: T, deep: true) => MaybeMockedDeep<T>) & (<T>(item: T, options: {
2854
+ partial?: false;
2855
+ deep?: false;
2856
+ }) => Mocked<T>) & (<T>(item: T, options: {
2857
+ partial?: false;
2858
+ deep: true;
2859
+ }) => MaybeMockedDeep<T>) & (<T>(item: T, options: {
2860
+ partial: true;
2861
+ deep?: false;
2862
+ }) => MaybePartiallyMocked<T>) & (<T>(item: T, options: {
2863
+ partial: true;
2864
+ deep: true;
2865
+ }) => MaybePartiallyMockedDeep<T>);
2715
2866
  /**
2716
2867
  * Calls `.mockClear()` on all spies.
2717
2868
  */
@@ -2725,21 +2876,37 @@ export declare interface RstestUtilities {
2725
2876
  */
2726
2877
  restoreAllMocks: () => RstestUtilities;
2727
2878
  /**
2728
- * Mock a module
2879
+ * Mock a module.
2880
+ *
2881
+ * When called with a factory function, the module will be replaced with the return value of the factory.
2882
+ * When called with `{ spy: true }`, the module will be auto-mocked but the original implementations
2883
+ * will be preserved - all exports will be wrapped in spy functions that track calls.
2884
+ *
2885
+ * @example
2886
+ * ```ts
2887
+ * // Replace module with factory
2888
+ * rs.mock('./module', () => ({ fn: rs.fn() }))
2889
+ *
2890
+ * // Auto-mock with spy mode - keeps original implementations
2891
+ * rs.mock('./module', { spy: true })
2892
+ * ```
2729
2893
  */
2730
- mock<T = unknown>(moduleName: string | Promise<T>, moduleFactory?: MockFactory<T>): void;
2894
+ mock<T = unknown>(moduleName: string | Promise<T>, factoryOrOptions?: MockFactory<T> | MockModuleOptions): void;
2731
2895
  /**
2732
- * Mock a module
2896
+ * Mock a module (CommonJS require)
2733
2897
  */
2734
- mockRequire: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
2898
+ mockRequire: <T = unknown>(moduleName: string, factoryOrOptions?: (() => T) | MockModuleOptions) => void;
2735
2899
  /**
2736
2900
  * Mock a module, not hoisted.
2901
+ *
2902
+ * When called with `{ spy: true }`, the module will be auto-mocked but the original implementations
2903
+ * will be preserved - all exports will be wrapped in spy functions that track calls.
2737
2904
  */
2738
- doMock<T = unknown>(moduleName: string | Promise<T>, moduleFactory?: MockFactory<T>): void;
2905
+ doMock<T = unknown>(moduleName: string | Promise<T>, factoryOrOptions?: MockFactory<T> | MockModuleOptions): void;
2739
2906
  /**
2740
- * Mock a module, not hoisted.
2907
+ * Mock a module, not hoisted (CommonJS require).
2741
2908
  */
2742
- doMockRequire: <T = unknown>(moduleName: string, moduleFactory?: () => T) => void;
2909
+ doMockRequire: <T = unknown>(moduleName: string, factoryOrOptions?: (() => T) | MockModuleOptions) => void;
2743
2910
  /**
2744
2911
  * Hoisted mock function.
2745
2912
  */
@@ -39,6 +39,32 @@ __webpack_require__.rstest_mock = (id, modFactory)=>{
39
39
  __webpack_require__.rstest_original_modules[id] = requiredModule;
40
40
  __webpack_require__.rstest_original_module_factories[id] = __webpack_modules__[id];
41
41
  }
42
+ if (modFactory && 'object' == typeof modFactory) {
43
+ const isSpy = true === modFactory.spy;
44
+ const isMock = true === modFactory.mock;
45
+ if (!isSpy && !isMock) throw new Error('[Rstest] rs.mock() options must be { spy: true } or { mock: true }');
46
+ if (!requiredModule) {
47
+ const optionName = isSpy ? 'spy' : 'mock';
48
+ throw new Error(`[Rstest] rs.mock('${id}', { ${optionName}: true }) failed: cannot load original module`);
49
+ }
50
+ const originalModule = requiredModule;
51
+ const isEsModule = true === originalModule.__esModule;
52
+ const mockedModule = globalThis.RSTEST_API?.rstest?.mockObject(originalModule, {
53
+ spy: isSpy
54
+ }) || originalModule;
55
+ const finalModFactory = function(__unused_webpack_module, __webpack_exports__, __webpack_require__1) {
56
+ __webpack_require__1.r(__webpack_exports__);
57
+ for(const key in mockedModule)__webpack_require__1.d(__webpack_exports__, {
58
+ [key]: ()=>mockedModule[key]
59
+ });
60
+ if (!isEsModule && !('default' in mockedModule)) __webpack_require__1.d(__webpack_exports__, {
61
+ default: ()=>mockedModule
62
+ });
63
+ };
64
+ __webpack_modules__[id] = finalModFactory;
65
+ delete __webpack_module_cache__[id];
66
+ return;
67
+ }
42
68
  if ('string' == typeof modFactory || 'number' == typeof modFactory) __webpack_module_cache__[id] = {
43
69
  exports: __webpack_require__(modFactory)
44
70
  };
@@ -62,6 +88,28 @@ __webpack_require__.rstest_mock_require = (id, modFactory)=>{
62
88
  __webpack_require__.rstest_original_modules[id] = requiredModule;
63
89
  __webpack_require__.rstest_original_module_factories[id] = __webpack_modules__[id];
64
90
  }
91
+ if (modFactory && 'object' == typeof modFactory) {
92
+ const isSpy = true === modFactory.spy;
93
+ const isMock = true === modFactory.mock;
94
+ if (!isSpy && !isMock) throw new Error('[Rstest] rs.mockRequire() options must be { spy: true } or { mock: true }');
95
+ if (!requiredModule) {
96
+ const optionName = isSpy ? 'spy' : 'mock';
97
+ throw new Error(`[Rstest] rs.mockRequire('${id}', { ${optionName}: true }) failed: cannot load original module`);
98
+ }
99
+ const originalModule = requiredModule;
100
+ const isEsModule = true === originalModule.__esModule;
101
+ const mockedModule = globalThis.RSTEST_API?.rstest?.mockObject(originalModule, {
102
+ spy: isSpy
103
+ }) || originalModule;
104
+ if (isEsModule) __webpack_require__.r(mockedModule);
105
+ else if (!('default' in mockedModule)) mockedModule.default = mockedModule;
106
+ __webpack_module_cache__[id] = {
107
+ exports: mockedModule,
108
+ id,
109
+ loaded: true
110
+ };
111
+ return;
112
+ }
65
113
  if ('string' == typeof modFactory || 'number' == typeof modFactory) __webpack_module_cache__[id] = {
66
114
  exports: __webpack_require__(modFactory)
67
115
  };
@@ -83,6 +131,28 @@ __webpack_require__.rstest_do_mock = (id, modFactory)=>{
83
131
  __webpack_require__.rstest_original_modules[id] = requiredModule;
84
132
  __webpack_require__.rstest_original_module_factories[id] = __webpack_modules__[id];
85
133
  }
134
+ if (modFactory && 'object' == typeof modFactory) {
135
+ const isSpy = true === modFactory.spy;
136
+ const isMock = true === modFactory.mock;
137
+ if (!isSpy && !isMock) throw new Error('[Rstest] rs.doMock() options must be { spy: true } or { mock: true }');
138
+ if (!requiredModule) {
139
+ const optionName = isSpy ? 'spy' : 'mock';
140
+ throw new Error(`[Rstest] rs.doMock('${id}', { ${optionName}: true }) failed: cannot load original module`);
141
+ }
142
+ const originalModule = requiredModule;
143
+ const isEsModule = true === originalModule.__esModule;
144
+ const mockedModule = globalThis.RSTEST_API?.rstest?.mockObject(originalModule, {
145
+ spy: isSpy
146
+ }) || originalModule;
147
+ if (isEsModule) __webpack_require__.r(mockedModule);
148
+ else if (!('default' in mockedModule)) mockedModule.default = mockedModule;
149
+ __webpack_module_cache__[id] = {
150
+ exports: mockedModule,
151
+ id,
152
+ loaded: true
153
+ };
154
+ return;
155
+ }
86
156
  if ('string' == typeof modFactory || 'number' == typeof modFactory) __webpack_module_cache__[id] = {
87
157
  exports: __webpack_require__(modFactory)
88
158
  };
@@ -104,6 +174,28 @@ __webpack_require__.rstest_do_mock_require = (id, modFactory)=>{
104
174
  __webpack_require__.rstest_original_modules[id] = requiredModule;
105
175
  __webpack_require__.rstest_original_module_factories[id] = __webpack_modules__[id];
106
176
  }
177
+ if (modFactory && 'object' == typeof modFactory) {
178
+ const isSpy = true === modFactory.spy;
179
+ const isMock = true === modFactory.mock;
180
+ if (!isSpy && !isMock) throw new Error('[Rstest] rs.doMockRequire() options must be { spy: true } or { mock: true }');
181
+ if (!requiredModule) {
182
+ const optionName = isSpy ? 'spy' : 'mock';
183
+ throw new Error(`[Rstest] rs.doMockRequire('${id}', { ${optionName}: true }) failed: cannot load original module`);
184
+ }
185
+ const originalModule = requiredModule;
186
+ const isEsModule = true === originalModule.__esModule;
187
+ const mockedModule = globalThis.RSTEST_API?.rstest?.mockObject(originalModule, {
188
+ spy: isSpy
189
+ }) || originalModule;
190
+ if (isEsModule) __webpack_require__.r(mockedModule);
191
+ else if (!('default' in mockedModule)) mockedModule.default = mockedModule;
192
+ __webpack_module_cache__[id] = {
193
+ exports: mockedModule,
194
+ id,
195
+ loaded: true
196
+ };
197
+ return;
198
+ }
107
199
  if ('string' == typeof modFactory || 'number' == typeof modFactory) __webpack_module_cache__[id] = {
108
200
  exports: __webpack_require__(modFactory)
109
201
  };
@@ -29,33 +29,6 @@ __webpack_require__.m = __webpack_modules__;
29
29
  return getter;
30
30
  };
31
31
  })();
32
- (()=>{
33
- var getProto = Object.getPrototypeOf ? (obj)=>Object.getPrototypeOf(obj) : (obj)=>obj.__proto__;
34
- var leafPrototypes;
35
- __webpack_require__.t = function(value, mode) {
36
- if (1 & mode) value = this(value);
37
- if (8 & mode) return value;
38
- if ('object' == typeof value && value) {
39
- if (4 & mode && value.__esModule) return value;
40
- if (16 & mode && 'function' == typeof value.then) return value;
41
- }
42
- var ns = Object.create(null);
43
- __webpack_require__.r(ns);
44
- var def = {};
45
- leafPrototypes = leafPrototypes || [
46
- null,
47
- getProto({}),
48
- getProto([]),
49
- getProto(getProto)
50
- ];
51
- for(var current = 2 & mode && value; ('object' == typeof current || 'function' == typeof current) && !~leafPrototypes.indexOf(current); current = getProto(current))Object.getOwnPropertyNames(current).forEach((key)=>{
52
- def[key] = ()=>value[key];
53
- });
54
- def['default'] = ()=>value;
55
- __webpack_require__.d(ns, def);
56
- return ns;
57
- };
58
- })();
59
32
  (()=>{
60
33
  __webpack_require__.d = (exports, definition)=>{
61
34
  for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) Object.defineProperty(exports, key, {
package/dist/worker.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import 'module';
2
2
  /*#__PURE__*/ import.meta.url;
3
3
  import { __webpack_require__ } from "./rslib-runtime.js";
4
- import { basename, isAbsolute, undoSerializableConfig, dirname, resolve as pathe_M_eThtNZ_resolve, join } from "./2672.js";
4
+ import { basename, isAbsolute, undoSerializableConfig, dirname, color, resolve as pathe_M_eThtNZ_resolve, join } from "./3160.js";
5
5
  import "./487.js";
6
6
  import { node_v8, createBirpc } from "./3216.js";
7
7
  import { createCoverageProvider } from "./5734.js";
@@ -106,8 +106,6 @@ class RstestSnapshotEnvironment extends NodeSnapshotEnvironment {
106
106
  }
107
107
  }
108
108
  const source_map_support = __webpack_require__("../../node_modules/.pnpm/source-map-support@0.5.21/node_modules/source-map-support/source-map-support.js");
109
- const picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js");
110
- var picocolors_default = /*#__PURE__*/ __webpack_require__.n(picocolors);
111
109
  let sourceMaps = {};
112
110
  (0, source_map_support.install)({
113
111
  environment: 'node',
@@ -185,7 +183,7 @@ const preparePool = async ({ entryInfo: { distPath, testPath }, updateSnapshot,
185
183
  const error = 'string' == typeof e ? new Error(e) : e;
186
184
  error.name = type;
187
185
  if (isTeardown) {
188
- error.stack = `${picocolors_default().yellow('Caught error after test environment was torn down:')}\n\n${error.stack}`;
186
+ error.stack = `${color.yellow('Caught error after test environment was torn down:')}\n\n${error.stack}`;
189
187
  console.error(error);
190
188
  } else {
191
189
  console.error(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rstest/core",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "The Rsbuild-based test tool.",
5
5
  "bugs": {
6
6
  "url": "https://github.com/web-infra-dev/rstest/issues"
@@ -60,6 +60,7 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@babel/code-frame": "^7.27.1",
63
+ "@clack/prompts": "^0.10.1",
63
64
  "@jridgewell/trace-mapping": "0.3.31",
64
65
  "@microsoft/api-extractor": "^7.55.2",
65
66
  "@rsbuild/plugin-node-polyfill": "^1.3.0",
@@ -72,8 +73,6 @@
72
73
  "@types/jsdom": "^21.1.7",
73
74
  "@types/picomatch": "^4.0.2",
74
75
  "@types/sinonjs__fake-timers": "^8.1.5",
75
- "@clack/prompts": "^0.10.1",
76
- "@vercel/detect-agent": "^1.0.0",
77
76
  "@types/source-map-support": "^0.5.10",
78
77
  "@vitest/expect": "^3.2.4",
79
78
  "@vitest/snapshot": "^3.2.4",