@remotex-labs/xjet 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/shared.d.ts CHANGED
@@ -3,7 +3,8 @@
3
3
  * This file was automatically generated by xBuild.
4
4
  * DO NOT EDIT MANUALLY.
5
5
  */
6
- import type { FunctionLikeType, RejectedValueType, ResolvedValueType } from '@remotex-labs/xjet-expect';
6
+ import type { FunctionType, RejectedValueType, ResolvedValueType } from '@remotex-labs/xjet-expect';
7
+ import type { FunctionLikeType, FunctionType } from '@remotex-labs/xjet-expect';
7
8
  import type { ContextType, FunctionType } from '@remotex-labs/xjet-expect';
8
9
  import { type ContextType, type FunctionLikeType, type FunctionType } from '@remotex-labs/xjet-expect';
9
10
  import type { ContextType } from '@remotex-labs/xjet-expect';
@@ -11,9 +12,6 @@ import type { FunctionLikeType } from '@remotex-labs/xjet-expect';
11
12
  import type { FunctionType } from '@remotex-labs/xjet-expect';
12
13
  import type { Struct } from '@remotex-labs/xstruct';
13
14
  import { Struct } from '@remotex-labs/xstruct';
14
- import type { ConstructorLikeType, FunctionType } from '@remotex-labs/xjet-expect';
15
- import type { ConstructorType } from '@remotex-labs/xjet-expect';
16
- import type { ConstructorLikeType, FunctionLikeType } from '@remotex-labs/xjet-expect';
17
15
 
18
16
  /**
19
17
  * Imports
@@ -24,23 +22,47 @@ export {};
24
22
  * Import will remove at compile time
25
23
  */
26
24
  /**
27
- * A class representing the mock state for tracking and managing the behavior of mocked functions or classes.
25
+ * A powerful mock state manager for simulating functions and classes in tests.
28
26
  *
29
- * @template ReturnType - The type of value returned by the mock function.
30
- * @template Context - The type representing the context (`this` value) used in the mock function.
31
- * @template Args - The types of arguments for the mocked function.
27
+ * @template F - The function signature being mocked, defaults to any function
32
28
  *
33
29
  * @remarks
34
- * This class provides mechanisms to customize and manage the behavior of mocked functions or constructors.
35
- * It tracks invocation details, allows for behavior customization, and enables resetting or restoring the mock to its original state.
30
+ * MockState provides a complete mocking solution. It tracks
31
+ * all invocations, including arguments, return values, and contexts, while also allowing
32
+ * customization of behavior through various methods like `mockImplementation` and
33
+ * `mockReturnValue`.
34
+ *
35
+ * Key features:
36
+ * - Tracks call arguments, return values, and execution contexts
37
+ * - Supports one-time implementations and return values
38
+ * - Manages Promise resolutions and rejections
39
+ * - Provides methods for resetting or restoring mock state
40
+ * - Preserves the interface of the original function
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * // Create a basic mock
45
+ * const mockFn = new MockState();
46
+ *
47
+ * // Configure return values
48
+ * mockFn.mockReturnValue('default');
49
+ * mockFn.mockReturnValueOnce('first call');
50
+ *
51
+ * // Use the mock
52
+ * console.log(mockFn()); // 'first call'
53
+ * console.log(mockFn()); // 'default'
36
54
  *
37
- * @since v1.0.0
55
+ * // Inspect calls
56
+ * console.log(mockFn.mock.calls); // [[], []]
57
+ * ```
58
+ *
59
+ * @since 1.0.0
38
60
  */
39
- declare class MockState<ReturnType = unknown, Args extends Array<unknown> = unknown[], Context = unknown> extends Function {
61
+ declare class MockState<F extends FunctionType = FunctionType> extends Function {
40
62
  /**
41
- * List of all mocks that created
63
+ * List of all mocks that created as WeakRef
42
64
  */
43
- static mocks: Array<MockState>;
65
+ static mocks: Set<WeakRef<MockState>>;
44
66
  /**
45
67
  * The `name` property represents the name of the mock function.
46
68
  */
@@ -50,555 +72,674 @@ declare class MockState<ReturnType = unknown, Args extends Array<unknown> = unkn
50
72
  */
51
73
  readonly xJetMock: boolean;
52
74
  /**
53
- * The `state` property holds the detailed state of the mock invocations.
54
- * It tracks information such as the arguments passed, the results returned, the context (`this` value) used,
55
- * the instances created, and the order of invocations.
56
- * This data is automatically updated after each call to the mock.
75
+ * Holds the current state of the mock, including all invocation records.
57
76
  *
58
- * @template ReturnType - The type of value returned by the mock function.
59
- * @template Context - The type representing the context (`this` value) used in the mock function.
60
- * @template Args - The types of arguments for the mocked function.
77
+ * @remarks
78
+ * This property tracks the complete history of the mock's usage, storing
79
+ * information like call arguments, return values, execution contexts,
80
+ * instances, and the order of invocations.
61
81
  *
62
- * @see MocksStateInterface
82
+ * It's initialized with empty arrays for tracking and gets updated with
83
+ * each invocation. This state is what powers the inspection capabilities
84
+ * accessible via the public `mock` getter.
63
85
  *
64
- * @since v1.0.0
86
+ * @since 1.0.0
65
87
  */
66
88
  private state;
67
89
  /**
68
- * A private function that restores the mock's original implementation.
90
+ * Stores one-time implementations to be used on successive invocations.
69
91
  *
70
92
  * @remarks
71
- * The `restore` function is responsible for resetting the mock to its initial state.
72
- * It works in conjunction with methods like `mockReset` and `mockRestore` to ensure
73
- * proper restoration of the mock's behavior.
74
- *
75
- * Responsibilities:
76
- * - Returning the original implementation when restoring the mock
77
- * - Ensuring consistent reset behavior across mock operations
78
- * - Supporting the {@link mockRestore} method's functionality
79
- * - Maintaining mock state integrity during restoration
93
+ * This queue contains functions that will be consumed in FIFO order
94
+ * (first-in, first-out) when the mock is called. Each implementation
95
+ * is used exactly once and then removed from the queue.
80
96
  *
81
- * @see MockState.mockRestore
82
- * @see MockState.originalImplementation
97
+ * When adding implementations with `mockImplementationOnce()` or similar
98
+ * methods, they are pushed to this queue. On invocation, the mock will
99
+ * check this queue first, using and removing the oldest implementation
100
+ * if available, or falling back to the default implementation.
83
101
  *
84
- * @since 1.2.0
102
+ * @since 1.0.0
85
103
  */
86
- private readonly restore?;
104
+ private queuedImplementations;
87
105
  /**
88
- * A private array that stores the implementations queued to be executed
89
- * for future invocations of the mock.
90
- * Each function in this array is invoked in sequence when the mock function is called,
91
- * with the first queued implementation being used on the first call, the second on the second call, and so on.
106
+ * The current default implementation for this mock.
92
107
  *
93
- * This property is used in conjunction with methods like `mockImplementationOnce`
94
- * to specify different behaviors for consecutive calls to the mock.
108
+ * @remarks
109
+ * This property holds the function that will be executed when the mock is called,
110
+ * unless overridden by a queued one-time implementation. It can be set using
111
+ * the `mockImplementation()` method and retrieved with `getMockImplementation()`.
95
112
  *
96
- * @since v1.0.0
97
- */
98
- private queuedImplementations;
99
- /**
100
- * A private property that holds the current implementation of the mock function.
101
- * This function is executed whenever the mock is invoked and can be changed
102
- * using methods like `mockImplementation` or `mockImplementationOnce`.
113
+ * If not explicitly set, it defaults to `undefined`, meaning the mock will
114
+ * return `undefined` when called (after any queued implementations are used).
103
115
  *
104
- * The `implementation` allows for customizing the behavior of the mock,
105
- * such as returning specific values, throwing errors, or performing actions.
116
+ * This implementation determines the behavior of the mock for all calls that
117
+ * don't have a specific one-time implementation in the queue.
106
118
  *
107
- * @since v1.0.0
119
+ * @since 1.0.0
108
120
  */
109
121
  private implementation;
110
122
  /**
111
- * A private property that holds the original implementation of the mock function.
112
- * This is the initial function passed to the constructor that defines the mock's default behavior
113
- * before any customization.
114
- *
115
- * @template ReturnType - The type of value returned by the original function.
116
- * @template Args - The types of arguments for the original function.
117
- * @template Context - The type representing the context (`this` value) used in the original function.
123
+ * Preserves the original implementation provided when creating the mock.
118
124
  *
119
125
  * @remarks
120
- * This property stores the initial implementation provided when creating the mock.
121
- * If no implementation is provided during construction, it defaults to a function
122
- * that returns `undefined` cast to the appropriate return type.
123
- * Unlike `implementation` which can be modified, this property maintains a reference
124
- * to the original function for scenarios where the original behavior needs to be preserved
125
- * or restored.
126
+ * This property stores the initial function passed to the constructor, allowing
127
+ * the mock to be restored to its original behavior later using `mockRestore()`.
128
+ *
129
+ * If no implementation was provided in the constructor, this will contain a
130
+ * function that returns `undefined` when called.
126
131
  *
127
- * @see FunctionLikeType
128
- * @see MockState.original
132
+ * The original implementation is immutable and serves as a reference point
133
+ * for resetting the mock to its initial state.
129
134
  *
130
135
  * @since 1.0.0
131
136
  */
132
137
  private readonly originalImplementation;
133
138
  /**
134
- * Constructs a mock object that allows custom implementation, restore capability,
135
- * and optional naming functionality. This mock is proxied to handle function invocation
136
- * and class instantiation.
139
+ * Optional cleanup function to be called when the mock is restored.
140
+ *
141
+ * @remarks
142
+ * If provided, this function will be executed when `mockRestore()` is called,
143
+ * allowing for custom cleanup operations. This is particularly useful when
144
+ * creating mocks that replace methods or properties on existing objects.
145
+ *
146
+ * The restore function should handle any necessary teardown, such as
147
+ * restoring original object properties, removing event listeners, or
148
+ * closing connections that were established during mock creation.
137
149
  *
138
- * @template ReturnType - The type of the value returned by the mock function.
139
- * @template Context - The type of the context (`this`) for the mock function.
140
- * @template Args - The type of arguments accepted by the mock function.
150
+ * @since 1.0.0
151
+ */
152
+ private readonly restore?;
153
+ /**
154
+ * Creates a new instance of a mock function.
141
155
  *
142
- * @param implementation - Optional implementation for the mock function.
143
- * @param restore - Optional function to restore the mock to its initial state. Defaults to resetting to the provided implementation.
144
- * @param name - Optional name for the mock instance. Default to a predefined mock name if not provided.
156
+ * @template F - The function type being mocked. This generic type parameter allows
157
+ * the mock to properly type-check parameters and return values to match
158
+ * the function signature being mocked.
145
159
  *
146
- * @returns A proxied mock object capable of behaving as a callable function or a constructible class.
160
+ * @param implementation - The initial function implementation to use. If not provided,
161
+ * the mock will return `undefined` when called.
162
+ * @param restore - Optional cleanup function that will be called when `mockRestore()` is invoked.
163
+ * Useful for restoring original behavior when mocking existing object methods.
164
+ * @param name - Optional name for the mock function, used in error messages and test output.
165
+ * Defaults to "xJet.fn()" if not provided.
147
166
  *
148
167
  * @remarks
149
- * The mock object can work as both a function and a class, using JavaScript's Proxy API. The restore functionality
150
- * allows resetting to the original state or implementation. If no implementation is provided, the mock remains uninitialized
151
- * but still functional.
168
+ * The constructor initializes the mock's state, implementation, and metadata.
169
+ * It returns a Proxy that allows the mock to be both a function and an object with properties.
170
+ *
171
+ * The Proxy intercepts:
172
+ * - Function calls (via `apply`)
173
+ * - Property access (via `get`)
174
+ * - Constructor calls with `new` (via `construct`)
152
175
  *
153
- * @see FunctionLikeType
154
- * @see VoidFunctionType
176
+ * This enables the mock to track calls, return configured values, and provide
177
+ * helper methods for assertions and configuration.
178
+ *
179
+ * @see ReturnType
180
+ * @see ImplementationType
155
181
  *
156
182
  * @since 1.0.0
157
183
  */
158
- constructor(implementation?: FunctionLikeType<ReturnType, Args, Context>, restore?: () => FunctionLikeType<ReturnType, Args, Context> | void, name?: string);
159
- /**
160
- * todo remove it
161
- * only for jest expect will support this mock
162
- */
163
- getMockName(): string;
184
+ constructor(implementation?: F, restore?: () => F | void, name?: string);
164
185
  /**
165
- * Retrieves the current state of the mock function.
186
+ * Gets a readonly snapshot of the current mocks state.
166
187
  *
167
- * @remarks
168
- * The `mock` getter provides read-only access to the complete state tracking information
169
- * for the mock function. This includes all recorded invocations, return values, contexts,
170
- * and other mock-related tracking data.
188
+ * @template F - The function type being mocked.
171
189
  *
172
- * Responsibilities:
173
- * - Providing access to recorded function calls via {@link MocksStateInterface.calls}
174
- * - Tracking invocation results through {@link MocksStateInterface.results}
175
- * - Maintaining context information in {@link MocksStateInterface.contexts}
176
- * - Recording instance creation in {@link MocksStateInterface.instances}
177
- * - Preserving invocation order via {@link MocksStateInterface.invocationCallOrder}
190
+ * @returns A frozen (immutable) copy of the mock state {@link MocksStateInterface}, containing information
191
+ * about calls, return values, and other tracking data.
178
192
  *
179
- * @returns A read-only view of the mock state tracking object.
193
+ * @remarks
194
+ * This property provides safe access to the mock's internal state for assertions and
195
+ * debugging purposes. The returned object is a deep copy with all properties frozen
196
+ * to prevent accidental modification of the mock's internal state.
180
197
  *
181
198
  * @see MocksStateInterface
199
+ *
182
200
  * @since 1.0.0
183
201
  */
184
- get mock(): Readonly<MocksStateInterface<ReturnType, Args, Context>>;
202
+ get mock(): Readonly<MocksStateInterface<F>>;
185
203
  /**
186
- * Returns the original implementation of the function that was instrumented
204
+ * Gets the original function implementation.
205
+ *
206
+ * @template F - The function type being mocked.
187
207
  *
188
- * @returns The original function implementation that was wrapped or modified
208
+ * @returns The original function implementation that was provided when creating the mock
209
+ * or a default implementation that returns undefined if none was provided.
189
210
  *
190
211
  * @remarks
191
- * This getter provides access to the unmodified function that was originally passed
192
- * to the instrumentation system. Useful for debugging, testing, or when you need
193
- * to bypass the instrumented behavior temporarily.
212
+ * This property allows access to the original implementation that was stored
213
+ * when the mock was created. It's useful when you need to temporarily access
214
+ * or call the original behavior within test cases.
194
215
  *
195
216
  * @example
196
217
  * ```ts
197
- * const mockFn = jest.fn(x => x * 2);
198
- * // Later in test
199
- * const originalImplementation = mockFn.original;
200
- * expect(originalImplementation(5)).toBe(10);
201
- * ```
218
+ * // Create a mock with an original implementation
219
+ * const originalFn = (x: number) => x * 2;
220
+ * const mockFn = xJet.fn(originalFn);
202
221
  *
203
- * @see FunctionLikeType
222
+ * // Override the implementation for some tests
223
+ * mockFn.mockImplementation((x: number) => x * 3);
224
+ *
225
+ * // Call the original implementation directly when needed
226
+ * const result = mockFn.original(5); // Returns 10, not 15
227
+ * ```
204
228
  *
205
229
  * @since 1.0.0
206
230
  */
207
- get original(): FunctionLikeType<ReturnType, Args, Context>;
231
+ get original(): F;
208
232
  /**
209
- * Clears the `mock.calls`, `mock.results`, `mock.contexts`, `mock.instances`, and `mock.invocationCallOrder` properties.
233
+ * Clears all information stored in the mock's state {@link MocksStateInterface}.
210
234
  *
211
- * @returns The current instance of the mock, allowing for method chaining.
235
+ * @returns The mock instance for method chaining.
212
236
  *
213
237
  * @remarks
214
- * This method resets the state of the mock function, clearing all invocation data and results,
215
- * ensuring that previous mock states do not affect the following tests.
216
- * Equivalent to calling `.mockClear()` on every mocked function.
238
+ * This method resets all stored information such as tracked calls, return values,
239
+ * and other state information. It doesn't reset any custom implementations that
240
+ * were set using mockImplementation or similar methods.
217
241
  *
218
- * @see MockState.initState
242
+ * @example
243
+ * ```ts
244
+ * const mockFn = xJet.fn();
245
+ * mockFn('first call');
246
+ * mockFn('second call');
247
+ *
248
+ * expect(mockFn.mock.calls.length).toBe(2);
249
+ *
250
+ * mockFn.mockClear();
251
+ *
252
+ * // All calls information has been cleared
253
+ * expect(mockFn.mock.calls.length).toBe(0);
254
+ * ```
219
255
  *
220
- * @since v1.0.0
256
+ * @since 1.0.0
221
257
  */
222
258
  mockClear(): this;
223
259
  /**
224
- * Resets the mock function to its initial state.
260
+ * Resets the mock by clearing all state and removing all queued implementations.
225
261
  *
226
- * @returns The current instance of the mock, allowing for method chaining.
262
+ * @returns The mock instance for method chaining.
227
263
  *
228
264
  * @remarks
229
- * The `mockReset` method clears all invocation data and results by calling `mockClear()` and also resets
230
- * the queued implementations,
231
- * removing any previously queued behavior set by methods like `mockImplementationOnce`.
232
- * This ensures that the mock is in a clean state and ready for new invocations or configurations.
265
+ * This method performs a more complete reset than mockClear() {@link mockClear}.
266
+ * It clears all stored information about calls and additionally removes any queued implementations that were
267
+ * set using mockImplementationOnce(). The default implementation will be restored.
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * const mockFn = xJet.fn(() => 'default');
272
+ * mockFn.mockImplementationOnce(() => 'first call');
273
+ * mockFn.mockImplementationOnce(() => 'second call');
233
274
  *
234
- * @see MockState.mockClear
275
+ * console.log(mockFn()); // 'first call'
235
276
  *
236
- * @since v1.0.0
277
+ * mockFn.mockReset();
278
+ *
279
+ * // All calls have been cleared, and queued implementations removed
280
+ * console.log(mockFn()); // 'default'
281
+ * ```
282
+ *
283
+ * @see mockClear
284
+ * @since 1.0.0
237
285
  */
238
286
  mockReset(): this;
239
287
  /**
240
- * Restores the mock function to its original implementation and resets its state.
288
+ * Restores the original implementation of the mocked function.
241
289
  *
242
- * @returns The current instance of the mock, allowing for method chaining.
290
+ * @returns The mock instance for method chaining.
243
291
  *
244
292
  * @remarks
245
- * The `mockRestore` method does two things:
246
- * 1. It restores the mock to its initial implementation, which was set during the mocks creation or
247
- * via the `mockImplementation` method.
248
- * 2. It clears all tracking data, such as calls, results, contexts, instances, and invocation call order
249
- * by calling `mockReset()`, ensuring the mock is fully reset and ready for new invocations.
293
+ * This method performs the most complete reset operation. It first calls mockReset() {@link mockReset}
294
+ * to clear all state and queued implementations, then restores the original implementation
295
+ * provided when the mock was created. If a custom restore function was provided,
296
+ * it will be used instead to determine the implementation to restore.
297
+ *
298
+ * @example
299
+ * ```ts
300
+ * // Create a mock with an original implementation
301
+ * const originalFn = (x: number) => x * 2;
302
+ * const mockFn = xJet.fn(originalFn);
303
+ *
304
+ * // Override the implementation
305
+ * mockFn.mockImplementation((x: number) => x * 3);
250
306
  *
251
- * This method is useful for ensuring that the mock is completely restored and cleared, making it behave as it did
252
- * when it was first created or last restored.
307
+ * console.log(mockFn(5)); // 15
253
308
  *
254
- * @see MockState.restore
255
- * @see MockState.mockReset
309
+ * // Restore the original implementation
310
+ * mockFn.mockRestore();
311
+ *
312
+ * console.log(mockFn(5)); // 10
313
+ * ```
256
314
  *
257
- * @since v1.0.0
315
+ * @see mockClear
316
+ * @see mockReset
317
+ *
318
+ * @since 1.0.0
258
319
  */
259
320
  mockRestore(): this;
260
321
  /**
261
- * Retrieves the mock implementation for a function, if available.
262
- *
263
- * @template ReturnType The type the return value of the function.
264
- * @template Context The type of the `this` context for the function.
265
- * @template Args The type the argument(s) of the function.
322
+ * Returns the current implementation of the mock function.
266
323
  *
267
- * @return A function matching `FunctionLikeType` that represents the mock implementation,
268
- * or `undefined` if no implementation is set.
324
+ * @returns The current mock implementation, or undefined if no implementation exists.
269
325
  *
270
326
  * @remarks
271
- * This method returns the mock implementation associated with the instance.
272
- * If no mock implementation exists, it returns `undefined`.
327
+ * This method returns the current implementation function used by the mock.
328
+ * This could be the default implementation, a custom implementation set via
329
+ * mockImplementation() {@link mockImplementation}, or the original implementation
330
+ * if mockRestore() {@link mockRestore} was called.
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * const mockFn = xJet.fn(() => 'default');
335
+ *
336
+ * // Get the default implementation
337
+ * const impl = mockFn.getMockImplementation();
338
+ * console.log(impl()); // 'default'
339
+ *
340
+ * // Change the implementation
341
+ * mockFn.mockImplementation(() => 'new implementation');
342
+ *
343
+ * // Get the new implementation
344
+ * const newImpl = mockFn.getMockImplementation();
345
+ * console.log(newImpl()); // 'new implementation'
346
+ * ```
273
347
  *
274
348
  * @since 1.0.0
275
349
  */
276
- getMockImplementation(): FunctionLikeType<ReturnType, Args, Context> | undefined;
350
+ getMockImplementation(): ImplementationType<F> | undefined;
277
351
  /**
278
- * Retrieves the next implementation from the queued implementations or defaults to the current implementation.
352
+ * Returns the next implementation to be used when the mock is called.
279
353
  *
280
- * @template ReturnType The return type of the function-like implementation.
281
- * @template Context The context in which the implementation executes.
282
- * @template Args The argument types expected by the implementation.
283
- *
284
- * @return The next implementation from the queue if available, or the current implementation.
285
- * Returns are `undefined` if no implementation is found.
354
+ * @returns The next implementation from the queue, or the default implementation if the queue is empty.
286
355
  *
287
356
  * @remarks
288
- * This method first checks if there are any queued implementations available.
289
- * If a queued implementation exists, it will be removed from the queue and returned.
290
- * If the queue is empty, the primary current implementation is returned.
291
- * Returns are `undefined` if there is no implementation available.
357
+ * This method retrieves and removes the next implementation from the queue of implementations
358
+ * added via mockImplementationOnce() {@link mockImplementationOnce}. If the queue is empty,
359
+ * it returns the default implementation set via mockImplementation() {@link mockImplementation}
360
+ * or the original function.
361
+ *
362
+ * @example
363
+ * ```ts
364
+ * const mockFn = xJet.fn(() => 'default');
365
+ * mockFn.mockImplementationOnce(() => 'first call');
366
+ * mockFn.mockImplementationOnce(() => 'second call');
367
+ *
368
+ * const firstImpl = mockFn.getNextImplementation();
369
+ * console.log(firstImpl()); // 'first call'
370
+ *
371
+ * const secondImpl = mockFn.getNextImplementation();
372
+ * console.log(secondImpl()); // 'second call'
373
+ *
374
+ * const defaultImpl = mockFn.getNextImplementation();
375
+ * console.log(defaultImpl()); // 'default'
376
+ * ```
292
377
  *
293
378
  * @since 1.0.0
294
379
  */
295
- getNextImplementation(): FunctionLikeType<ReturnType, Args, Context> | undefined;
380
+ getNextImplementation(): ImplementationType<F> | undefined;
296
381
  /**
297
- * Replaces the default implementation of a mock function with the provided function.
382
+ * Sets a new implementation for this mock function.
298
383
  *
299
- * @template ReturnType - The type of the value returned by the implementation function.
300
- * @template Context - The context (`this`) expected by the implementation function.
301
- * @template Args - The types of the arguments expected by the implementation function.
384
+ * @param fn - The function to be used as the mock implementation.
385
+ * @returns The mock instance for method chaining.
302
386
  *
303
- * @param fn - The function to be used as the mock implementation. It defines
304
- * the behavior of the mock when called.
387
+ * @remarks
388
+ * This method sets a persistent implementation that will be used whenever the mock function is called,
389
+ * unless there are queued implementations from mockImplementationOnce() {@link mockImplementationOnce}.
390
+ * The implementation remains until it is replaced by another call to mockImplementation() or restored
391
+ * via mockRestore() {@link mockRestore}.
305
392
  *
306
- * @return Returns the instance of the current object for method chaining.
393
+ * @example
394
+ * ```ts
395
+ * const mockFn = xJet.fn();
307
396
  *
308
- * @remarks
309
- * This method is useful when you need to mock the behavior of a function
310
- * dynamically during tests or in controlled scenarios.
397
+ * mockFn.mockImplementation((x: number) => x * 2);
398
+ *
399
+ * console.log(mockFn(5)); // 10
400
+ * console.log(mockFn(10)); // 20
401
+ *
402
+ * // Change the implementation
403
+ * mockFn.mockImplementation((x: number) => x * 3);
404
+ *
405
+ * console.log(mockFn(5)); // 15
406
+ * ```
407
+ *
408
+ * @see mockRestore
409
+ * @see mockImplementationOnce
311
410
  *
312
411
  * @since 1.0.0
313
412
  */
314
- mockImplementation(fn: FunctionLikeType<ReturnType, Args, Context>): this;
413
+ mockImplementation(fn: ImplementationType<F>): this;
315
414
  /**
316
- * Sets a mock implementation that will be used once for the next call to the mocked function.
317
- *
318
- * @template ReturnType The type of the value that the mock function will return.
319
- * @template Context The type of the `this` context for the mock function.
320
- * @template Args The type of arguments that the mock function will receive.
415
+ * Adds a one-time implementation for this mock function.
321
416
  *
322
- * @param fn - The function to be used as the mock implementation for the next call.
323
- * @returns The current instance, allowing for chaining of mock configurations.
417
+ * @param fn - The function to be used as the mock implementation for a single call.
418
+ * @returns The mock instance for method chaining.
324
419
  *
325
420
  * @remarks
326
- * The provided mock implementation will only be executed once. Further calls will fall back
327
- * to a different implementation, if provided, or the default behavior of the mock function.
421
+ * This method queues an implementation that will be used for a single call to the mock function.
422
+ * After being used once, it will be removed from the queue. Multiple implementations can be queued,
423
+ * and they will be used in the order they were added. Once all queued implementations are used,
424
+ * the mock will revert to using the implementation set by mockImplementation() {@link mockImplementation}.
328
425
  *
329
426
  * @example
330
427
  * ```ts
331
- * const mockFn = new MockState();
428
+ * const mockFn = xJet.fn(() => 'default');
332
429
  *
333
- * // Set default implementation
334
- * mockFn.mockImplementation(() => 'default');
335
- *
336
- * // Set one-time behavior for the next call
337
- * mockFn.mockImplementationOnce(() => 'first call');
430
+ * mockFn.mockImplementationOnce(() => 'first call')
431
+ * .mockImplementationOnce(() => 'second call');
338
432
  *
339
- * console.log(mockFn()); // Output: 'first call' (from mockImplementationOnce)
340
- * console.log(mockFn()); // Output: 'default' (from mockImplementation)
433
+ * console.log(mockFn()); // 'first call'
434
+ * console.log(mockFn()); // 'second call'
435
+ * console.log(mockFn()); // 'default'
341
436
  * ```
342
437
  *
343
- * @see FunctionLikeType
438
+ * @see mockReset
439
+ * @see mockImplementation
344
440
  *
345
441
  * @since 1.0.0
346
442
  */
347
- mockImplementationOnce(fn: FunctionLikeType<ReturnType, Args, Context>): this;
443
+ mockImplementationOnce(fn: ImplementationType<F>): this;
348
444
  /**
349
- * Sets a mock implementation to always return a specified value when invoked.
445
+ * Sets a fixed return value for this mock function.
350
446
  *
351
- * @template ReturnType The type of the value returned by the mock implementation.
352
- *
353
- * @param value - The value to always return when the mock function is called.
354
- * @return The current instance for chaining.
447
+ * @param value - The value to be returned when the mock function is called.
448
+ * @returns The mock instance for method chaining.
355
449
  *
356
450
  * @remarks
357
- * This method overrides any previous mock implementation configured for the function.
451
+ * This method is a convenience wrapper around mockImplementation() {@link mockImplementation}
452
+ * that creates an implementation which always returns the same value. It replaces any existing
453
+ * implementation with a function that simply returns the specified value.
358
454
  *
359
455
  * @example
360
456
  * ```ts
361
- * const mockFn = new MockState();
457
+ * const mockFn = xJet.fn();
458
+ *
459
+ * mockFn.mockReturnValue(42);
362
460
  *
363
- * // Set mock to return 'Hello World' on each call
364
- * mockFn.mockReturnValue('Hello World');
461
+ * console.log(mockFn()); // 42
462
+ * console.log(mockFn('anything')); // 42
463
+ * console.log(mockFn({}, [])); // 42
365
464
  *
366
- * console.log(mockFn()); // Output: 'Hello World'
367
- * console.log(mockFn()); // Output: 'Hello World'
465
+ * // Can be changed
466
+ * mockFn.mockReturnValue('new value');
467
+ * console.log(mockFn()); // 'new value'
368
468
  * ```
369
469
  *
470
+ * @see mockImplementation
471
+ * @see mockReturnValueOnce
472
+ *
370
473
  * @since 1.0.0
371
474
  */
372
- mockReturnValue(value: ReturnType): this;
475
+ mockReturnValue(value: ReturnType<F>): this;
373
476
  /**
374
- * Sets up a mock function to always resolve a promise with the specified value when called.
477
+ * Adds a one-time fixed return value for this mock function.
375
478
  *
376
- * @template ResolvedValueType - The type of the value to be resolved by the promise.
377
- * @template ReturnType - The return type of the function, which should include a Promise of the specified resolved value type.
378
- *
379
- * @param value - The value to be returned as the resolved value of the promise.
380
- * @returns The mock function instance, enabling method chaining.
479
+ * @param value - The value to be returned for a single call to the mock function.
480
+ * @returns The mock instance for method chaining.
381
481
  *
382
482
  * @remarks
383
- * This method is particularly useful for mocking asynchronous functions that return promises.
384
- * It ensures that the mock function resolves with the provided value every time it is called.
483
+ * This method is a convenience wrapper around mockImplementationOnce() {@link mockImplementationOnce}
484
+ * that creates a one-time implementation which returns the specified value. Multiple return values
485
+ * can be queued, and they will be used in the order they were added. After all queued values are
486
+ * consumed, the mock will revert to its default implementation.
385
487
  *
386
488
  * @example
387
489
  * ```ts
388
- * const mockFn = new MockState<Promise<string>>();
490
+ * const mockFn = xJet.fn(() => 'default');
389
491
  *
390
- * // Set mock to return a resolved promise with the value 'Success'
391
- * mockFn.mockResolvedValue('Success');
492
+ * mockFn.mockReturnValueOnce(42)
493
+ * .mockReturnValueOnce('string value')
494
+ * .mockReturnValueOnce({ object: true });
392
495
  *
393
- * mockFn().then((result: string) => {
394
- * console.log(result); // Output: 'Success'
395
- * });
496
+ * console.log(mockFn()); // 42
497
+ * console.log(mockFn()); // 'string value'
498
+ * console.log(mockFn()); // { object: true }
499
+ * console.log(mockFn()); // 'default'
396
500
  * ```
397
501
  *
502
+ * @see mockReturnValue
503
+ * @see mockImplementationOnce
504
+ *
398
505
  * @since 1.0.0
399
506
  */
400
- mockResolvedValue(value: ResolvedValueType<ReturnType>): this;
507
+ mockReturnValueOnce(value: ReturnType<F>): this;
401
508
  /**
402
- * Sets a mock implementation for a single call that resolves to the specified value.
403
- *
404
- * @template ReturnType The type of the resolved value.
405
- * @template ResolvedValueType The type of the input value to be resolved.
509
+ * Sets a resolved Promise return value for this mock function.
406
510
  *
407
- * @param value - The value that the promise should resolve with when the mock is called once.
408
- * @return The current mock object instance, enabling method chaining.
511
+ * @param value - The value that the Promise will resolve to.
512
+ * @returns The mock instance for method chaining.
409
513
  *
410
514
  * @remarks
411
- * This method is useful for defining custom behavior for a specific invocation of a mocked function,
412
- * returning a resolved promise with the provided value.
515
+ * This method is a convenience wrapper that creates an implementation which returns a
516
+ * Promise that resolves to the specified value. It's particularly useful for testing
517
+ * async functions that should return resolved Promises.
413
518
  *
414
519
  * @example
415
520
  * ```ts
416
- * const mockFn = new MockState(async () => {
417
- * return 'end';
418
- * });
521
+ * const mockFn = xJet.fn();
419
522
  *
420
- * // Set mock to return a resolved promise with the value 'Success'
421
- * mockFn.mockResolvedValueOnce('Success');
523
+ * mockFn.mockResolvedValue('resolved value');
422
524
  *
423
- * mockFn().then((result: string) => {
424
- * console.log(result); // Output: 'Success'
525
+ * // The mock now returns a Promise that resolves to 'resolved value'
526
+ * mockFn().then(result => {
527
+ * console.log(result); // 'resolved value'
425
528
  * });
426
529
  *
427
- * mockFn().then((result: string) => {
428
- * console.log(result); // Output: 'end'
429
- * });
530
+ * // Can also be used with async/await
531
+ * const result = await mockFn();
532
+ * console.log(result); // 'resolved value'
430
533
  * ```
431
534
  *
535
+ * @see mockRejectedValue
536
+ * @see mockImplementation
537
+ * @see mockResolvedValueOnce
538
+ *
432
539
  * @since 1.0.0
433
540
  */
434
- mockResolvedValueOnce(value: ResolvedValueType<ReturnType>): this;
541
+ mockResolvedValue(value: ResolvedValueType<ReturnType<F>>): this;
435
542
  /**
436
- * Sets the return value of the mock function for a single call.
543
+ * Adds a one-time resolved Promise return value for this mock function.
437
544
  *
438
- * @template ReturnType The type of the value to be returned.
439
- *
440
- * @param value - The value to be returned by the mock function for the next call.
441
- * @return The mock function instance, allowing for method chaining.
545
+ * @param value - The value that the Promise will resolve to for a single call.
546
+ * @returns The mock instance for method chaining.
442
547
  *
443
548
  * @remarks
444
- * This method only affects the return value for the next call to the mock function.
445
- * All further calls will use the usual mock implementation or other specified behaviors.
549
+ * This method is a convenience wrapper that creates a one-time implementation which returns
550
+ * a Promise that resolves to the specified value. Multiple resolved values can be queued and
551
+ * will be used in the order they were added. After all queued values are consumed, the mock
552
+ * will revert to its default implementation.
446
553
  *
447
554
  * @example
448
555
  * ```ts
449
- * const mockFn = new MockState();
450
- *
451
- * // Set default return value
452
- * mockFn.mockReturnValue('Default Value');
556
+ * const mockFn = xJet.fn(() => Promise.resolve('default'));
453
557
  *
454
- * // Set a one-time return value for the next call
455
- * mockFn.mockReturnValueOnce('First Call');
456
- * mockFn.mockReturnValueOnce('Second Call');
558
+ * mockFn.mockResolvedValueOnce('first call')
559
+ * .mockResolvedValueOnce('second call')
560
+ * .mockResolvedValueOnce('third call');
457
561
  *
458
- * console.log(mockFn()); // Output: 'First Call' (from mockReturnValueOnce)
459
- * console.log(mockFn()); // Output: 'Second Call' (from mockReturnValueOnce)
460
- * console.log(mockFn()); // Output: 'Default Value' (from mockReturnValue)
562
+ * // Each call returns a different Promise
563
+ * await expect(mockFn()).resolves.toEqual('first call');
564
+ * await expect(mockFn()).resolves.toEqual('second call');
565
+ * await expect(mockFn()).resolves.toEqual('third call');
566
+ * await expect(mockFn()).resolves.toEqual('default');
461
567
  * ```
462
568
  *
569
+ * @see mockResolvedValue
570
+ * @see mockRejectedValueOnce
571
+ * @see mockImplementationOnce
572
+ *
463
573
  * @since 1.0.0
464
574
  */
465
- mockReturnValueOnce(value: ReturnType): this;
575
+ mockResolvedValueOnce(value: ResolvedValueType<ReturnType<F>>): this;
466
576
  /**
467
- * Mocks the method to always return a rejected Promise with the specified value.
468
- *
469
- * @template ReturnType - The expected type of the return value for the mocked method.
470
- * @template RejectedValueType - The type of the value used to reject the Promise.
471
- *
472
- * @param value - The value with which the mocked Promise will be rejected.
577
+ * Sets a rejected Promise return value for this mock function.
473
578
  *
474
- * @return The current instance of the mock for chaining purposes.
579
+ * @param value - The error that the Promise will reject with.
580
+ * @returns The mock instance for method chaining.
475
581
  *
476
582
  * @remarks
477
- * This method is useful for testing scenarios where the function being mocked
478
- * is expected to reject with a specific value.
583
+ * This method is a convenience wrapper that creates an implementation which returns a
584
+ * Promise that rejects with the specified value. It's particularly useful for testing
585
+ * error handling in async functions.
479
586
  *
480
587
  * @example
481
588
  * ```ts
482
- * const mockFn = new MockState<Promise<string>>();
589
+ * const mockFn = xJet.fn();
483
590
  *
484
- * // Set mock to return a rejected promise with the value 'Error'
485
- * mockFn.mockRejectedValue('Error');
591
+ * mockFn.mockRejectedValue(new Error('Something went wrong'));
486
592
  *
593
+ * // The mock now returns a Promise that rejects with the error
487
594
  * mockFn().catch(error => {
488
- * console.log(error); // Output: 'Error'
595
+ * console.error(error.message); // 'Something went wrong'
489
596
  * });
597
+ *
598
+ * // Can also be used with async/await and try/catch
599
+ * try {
600
+ * await mockFn();
601
+ * } catch (error) {
602
+ * console.error(error.message); // 'Something went wrong'
603
+ * }
490
604
  * ```
491
605
  *
606
+ * @see mockResolvedValue
607
+ * @see mockImplementation
608
+ * @see mockRejectedValueOnce
609
+ *
492
610
  * @since 1.0.0
493
611
  */
494
- mockRejectedValue(value: RejectedValueType<ReturnType>): this;
612
+ mockRejectedValue(value: RejectedValueType<ReturnType<F>>): this;
495
613
  /**
496
- * Adds a one-time rejection with the provided value to the mock function.
497
- *
498
- * @template ReturnType - The type of the value the mock function would return.
614
+ * Adds a one-time rejected Promise return value for this mock function.
499
615
  *
500
- * @param value - The value to reject the promise with in the mock function.
501
- * @return The current instance of the mock function, allowing for method chaining.
616
+ * @param value - The error that the Promise will reject with for a single call.
617
+ * @returns The mock instance for method chaining.
502
618
  *
503
619
  * @remarks
504
- * This method configures a mock function to return a rejected promise with the
505
- * specified value the next time it is called. After the rejection occurs, the
506
- * mock function's behavior will revert to the next defined mock behavior, or
507
- * to the default behavior if no behaviors are defined.
620
+ * This method is a convenience wrapper that creates a one-time implementation which returns
621
+ * a Promise that rejects with the specified value. Multiple rejected values can be queued and
622
+ * will be used in the order they were added. After all queued values are consumed, the mock
623
+ * will revert to its default implementation.
508
624
  *
509
625
  * @example
510
626
  * ```ts
511
- * const mockFn = new MockState<Promise<string>>();
627
+ * const mockFn = xJet.fn(() => Promise.resolve('success'));
512
628
  *
513
- * // Set default rejected value
514
- * mockFn.mockRejectedValue('Default Error');
629
+ * mockFn.mockRejectedValueOnce(new Error('first error'))
630
+ * .mockRejectedValueOnce(new Error('second error'));
515
631
  *
516
- * // Set a one-time rejected value for the next call
517
- * mockFn.mockRejectedValueOnce('First Call Error');
632
+ * // First call rejects with 'first error'
633
+ * await expect(mockFn()).rejects.toThrow('first error');
518
634
  *
519
- * mockFn().catch(error => {
520
- * console.log(error); // Output: 'First Call Error' (from mockRejectedValueOnce)
521
- * });
635
+ * // Second call rejects with 'second error'
636
+ * await expect(mockFn()).rejects.toThrow('second error');
522
637
  *
523
- * mockFn().catch(error => {
524
- * console.log(error); // Output: 'Default Error' (from mockRejectedValue)
525
- * });
638
+ * // Third call uses the default implementation and resolves
639
+ * await expect(mockFn()).resolves.toEqual('success');
526
640
  * ```
527
641
  *
642
+ * @see mockRejectedValue
643
+ * @see mockResolvedValueOnce
644
+ * @see mockImplementationOnce
645
+ *
528
646
  * @since 1.0.0
529
647
  */
530
- mockRejectedValueOnce(value: RejectedValueType<ReturnType>): this;
648
+ mockRejectedValueOnce(value: RejectedValueType<ReturnType<F>>): this;
531
649
  /**
532
- * Initializes and returns the state object for mock function tracking.
650
+ * Initializes the internal state object for the mock function.
533
651
  *
534
- * @return An object containing the initialized mock function state.
652
+ * @returns A new mock state object with default empty values.
535
653
  *
536
654
  * @remarks
537
- * The state object contains the structure necessary to keep track of
538
- * calls, results, contexts, instances, and invocation orders of the function.
655
+ * This private method creates and returns a fresh state object used to track
656
+ * mock function invocations. The state includes:
657
+ * - calls: Arguments passed to the mock function
658
+ * - results: Return values or errors from each call
659
+ * - lastCall: Arguments from the most recent call
660
+ * - contexts: 'this' context values for each call
661
+ * - instances: Objects created when the mock is used as a constructor
662
+ * - invocationCallOrder: Tracking the sequence of calls across multiple mocks
539
663
  *
540
- * @see MocksStateInterface
664
+ * This method is used internally when creating a new mock or when resetting
665
+ * an existing mocks state.
541
666
  *
542
- * @since v1.0.0
667
+ * @since 1.0.0
543
668
  */
544
669
  private initState;
545
670
  /**
546
- * Invokes the next implementation of a mock function with the provided context and arguments.
671
+ * Invokes the mock function with the provided arguments and context.
547
672
  *
548
- * @template Context The type of `this` context in which the function is invoked.
549
- * @template Args The type of the arguments passed to the function.
550
- * @template ReturnType The type of the return value, of the function being invoked.
551
- *
552
- * @param thisArg - The context (`this`) in which the function is executed.
553
- * @param args - The arguments to be passed to the function.
554
- *
555
- * @returns The result of the function invocation, which is either the return value, the thrown error, or undefined.
673
+ * @param thisArg - The 'this' context for the function call
674
+ * @param args - The arguments to pass to the function
675
+ * @returns The result of the mock implementation or undefined
556
676
  *
557
677
  * @remarks
558
- * This method simulates the function call for a mocked implementation. It tracks all invocations,
559
- * including the call order, the provided arguments, and the context. It handles binding, default
560
- * arguments, and maintains a record of results (either successful returns or thrown errors).
678
+ * This private method handles the actual invocation of the mock function and manages all
679
+ * state trackings.
680
+ *
681
+ * This method is central to the mock's functionality, enabling call tracking,
682
+ * result recording, and the execution of custom implementations.
561
683
  *
562
684
  * @since 1.0.0
563
685
  */
564
686
  private invoke;
565
687
  /**
566
- * Invokes a function within a specific context and with provided arguments.
688
+ * Handles property access for the mock function proxy.
567
689
  *
568
- * @template Context The type of the context in which the function is invoked.
569
- * @template Args The type of the arguments passed to the function.
570
- * @template ReturnType The type of the value that the invoked function returns.
571
- *
572
- * @param target - The instance of the class containing the method to be invoked.
573
- * @param thisArg - The context object that will be bound to the invoked function.
574
- * @param argumentsList - The list of arguments to pass to the invoked function.
575
- * @returns The result of the invoked function or `undefined` if no value is returned.
690
+ * @param target - The mock function instance
691
+ * @param property - The property name or symbol being accessed
692
+ * @returns The property value from either the mock or the original implementation
576
693
  *
577
694
  * @remarks
578
- * This method modifies the state of the `target` instance by adding the `thisArg`
579
- * to the `target.state.instances` array before invoking the function.
695
+ * This private method is used as the 'get' trap for the Proxy surrounding the mock function.
696
+ * It provides property access fallback behavior - first checking if the property exists
697
+ * on the mock itself, and if not, retrieving it from the original implementation.
698
+ *
699
+ * This enables the mock to maintain its own properties while still allowing access to
700
+ * properties from the original function, providing a more transparent mocking experience.
580
701
  *
581
702
  * @since 1.0.0
582
703
  */
583
- private invokeFunction;
704
+ private invokeGet;
584
705
  /**
585
- * Invokes a class method on the provided target with specified arguments and a new target.
586
- *
587
- * @template Args - The type of arguments to be passed to the invoked method.
706
+ * Handles constructor invocation when the mock is used with 'new'.
588
707
  *
589
- * @param target - The object on which the class method is invoked.
590
- * @param argArray - The array of arguments to pass to the invoked method.
591
- * @param newTarget - The new object used as the invocation context.
592
- * @returns The result of the invocation, typically an object. If the result is not an object,
593
- * the `newTarget` is returned instead.
708
+ * @param target - The mock function instance
709
+ * @param argArray - The arguments passed to the constructor
710
+ * @param newTarget - The constructor that was directly invoked
711
+ * @returns The constructed instance
594
712
  *
595
713
  * @remarks
596
- * This method ensures that the result is stored in the `instances` array of the target's state
597
- * if it is detected as a proper class instance. Otherwise, the `newTarget` is registered.
714
+ * This method is used as the 'construct' trap for the Proxy surrounding the mock function.
715
+ * It delegates to the `invoke` method to handle the actual function call, then tracks the
716
+ * resulting instance in the mock's state for later verification.
717
+ *
718
+ * The method handles both cases where the constructor returns an object (which becomes the
719
+ * instance) and where it doesn't (in which case the newTarget becomes the instance).
598
720
  *
599
721
  * @since 1.0.0
600
722
  */
601
723
  private invokeClass;
724
+ /**
725
+ * Handles function invocation when the mock is called.
726
+ *
727
+ * @param target - The mock function instance
728
+ * @param thisArg - The 'this' context for the function call
729
+ * @param argumentsList - The arguments passed to the function
730
+ * @returns The result of the function invocation
731
+ *
732
+ * @remarks
733
+ * This method is used as the 'apply' trap for the Proxy surrounding the mock function.
734
+ * It captures the calling context in the mock's state for later verification, then
735
+ * delegates to the `invoke` method to handle the actual function call logic.
736
+ *
737
+ * This method is called whenever the mock function is invoked as a regular function
738
+ * (not as a constructor).
739
+ *
740
+ * @since 1.0.0
741
+ */
742
+ private invokeFunction;
602
743
  }
603
744
 
604
745
  /**
@@ -621,6 +762,9 @@ interface BoundInterface<Context = unknown | null | undefined, Args = Array<unkn
621
762
  __boundArgs?: Args;
622
763
  }
623
764
 
765
+ /**
766
+ * Import will remove at compile time
767
+ */
624
768
  /**
625
769
  * Represents the possible result types of a mock function invocation.
626
770
  *
@@ -680,35 +824,35 @@ interface MockInvocationResultInterface<T> {
680
824
  *
681
825
  * @since 1.0.0
682
826
  */
683
- interface MocksStateInterface<ReturnType, Args extends Array<unknown> = [], Context = unknown> {
827
+ interface MocksStateInterface<F extends FunctionType> {
684
828
  /**
685
829
  * An array that holds the arguments for each invocation made to the mock.
686
830
  * Each entry corresponds to the arguments passed during a single call to the mock function.
687
831
  *
688
832
  * @since 1.0.0
689
833
  */
690
- calls: Array<Args>;
834
+ calls: Array<Parameters<F>>;
691
835
  /**
692
836
  * The arguments passed to the mock during its most recent invocation.
693
837
  * Returns `undefined` if the mock has not been called yet.
694
838
  *
695
839
  * @since 1.0.0
696
840
  */
697
- lastCall?: Args;
841
+ lastCall?: Parameters<F>;
698
842
  /**
699
843
  * An array of contexts (`this` values) for each invocation made to the mock.
700
844
  * Each entry corresponds to the context in which the mock was called.
701
845
  *
702
846
  * @since 1.0.0
703
847
  */
704
- contexts: Array<Context>;
848
+ contexts: Array<ThisParameterType<F>>;
705
849
  /**
706
850
  * An array of all object instances created by the mock.
707
851
  * Each entry represents an instance was instantiated during the mocks invocations.
708
852
  *
709
853
  * @since 1.0.0
710
854
  */
711
- instances: Array<Context>;
855
+ instances: Array<ThisParameterType<F>>;
712
856
  /**
713
857
  * An array of invocation order indices for the mock.
714
858
  * xJet assigns an index to each call, starting from 1, to track the order in which mocks are invoked within a test file.
@@ -722,8 +866,39 @@ interface MocksStateInterface<ReturnType, Args extends Array<unknown> = [], Cont
722
866
  *
723
867
  * @since 1.0.0
724
868
  */
725
- results: Array<MockInvocationResultInterface<ReturnType>>;
869
+ results: Array<MockInvocationResultInterface<ReturnType<F>>>;
726
870
  }
871
+ /**
872
+ * A utility type that extracts the signature of a function and allows it to be reused in an implementation.
873
+ *
874
+ * @remarks
875
+ * This type creates a representation of a function's signature based on its return type, parameters, and
876
+ * `this` context. It's particularly useful for creating mock implementations, decorators, or wrappers
877
+ * that need to maintain the same signature as the original function.
878
+ *
879
+ * By using this type, you can ensure type safety when implementing functions that need to match
880
+ * an existing function's signature exactly, including its return type, parameter types, and `this` binding.
881
+ *
882
+ * @typeParam F - The original function type to extract the signature from
883
+ *
884
+ * @example
885
+ * ```ts
886
+ * // Original function
887
+ * function greet(name: string): string {
888
+ * return `Hello, ${name}!`;
889
+ * }
890
+ *
891
+ * // Implementation with the same signature
892
+ * const mockGreet: ImplementationType<typeof greet> = function(name) {
893
+ * return `Mocked greeting for ${name}`;
894
+ * };
895
+ *
896
+ * // Both functions now have the exact same type signature
897
+ * ```
898
+ *
899
+ * @since 1.2.2
900
+ */
901
+ type ImplementationType<F extends FunctionType> = FunctionLikeType<ReturnType<F>, Parameters<F>, ThisParameterType<F>>;
727
902
 
728
903
  /**
729
904
  * Import will remove at compile time
@@ -2905,10 +3080,6 @@ declare function getTrimmedStackString(position?: number): string;
2905
3080
  /**
2906
3081
  * Imports
2907
3082
  */
2908
- declare const proxyRegistry: WeakMap<object, {
2909
- proxy: unknown;
2910
- spies: Map<PropertyKey, MockState>;
2911
- }>;
2912
3083
  /**
2913
3084
  * Checks if a property on an object is provided via a proxy mechanism rather than directly defined.
2914
3085
  *
@@ -2950,269 +3121,196 @@ declare const proxyRegistry: WeakMap<object, {
2950
3121
  */
2951
3122
  declare function isProxyProperty<T extends object>(obj: T, key: keyof T): boolean;
2952
3123
  /**
2953
- * Creates a spy on a property accessed via a proxy getter, allowing interception
2954
- * and monitoring of property access operations.
3124
+ * Determines if a value is a mock proxy created by the mocking system.
2955
3125
  *
2956
- * @template T - The type of the target object containing the proxy
2957
- * @template K - The type of property key being spied on
3126
+ * @param value - The value to check
3127
+ * @returns `true` if the value is a mock proxy, `false` otherwise
2958
3128
  *
2959
- * @param target - The object containing the property to spy on
2960
- * @param key - The property key to intercept access to
2961
- * @param method - The method to execute when the property is accessed
2962
- * @returns A {@link MockState} instance that tracks interactions with the property
3129
+ * @remarks
3130
+ * This function checks if an object has the internal `__isMockProxy__` symbol property
3131
+ * which is added to all mock proxy objects created by the mocking framework.
2963
3132
  *
2964
- * @throws Error - If the target is not part of any global object
3133
+ * Mock proxies are specialized proxy objects that intercept property access
3134
+ * and method calls while providing mocking capabilities.
2965
3135
  *
2966
3136
  * @example
2967
3137
  * ```ts
2968
- * // Create an object with dynamic property access
2969
- * const user = new Proxy({}, {
2970
- * get(target, prop) {
2971
- * if (prop === 'name') return 'John';
2972
- * return target[prop];
2973
- * }
2974
- * });
2975
- *
2976
- * // Spy on the 'name' property
2977
- * const nameSpy = spyOnProxyGet(user, 'name', () => 'Jane');
2978
- *
2979
- * // Now accessing user.name returns 'Jane' and the access is tracked
2980
- * console.log(user.name); // 'Jane'
2981
- * expect(nameSpy).toHaveBeenCalled();
3138
+ * const regularObject = { name: 'Test' };
3139
+ * const mockObject = createMock({ name: 'Test' });
2982
3140
  *
2983
- * // Restore original behavior
2984
- * nameSpy.mockRestore();
2985
- * console.log(user.name); // 'John'
3141
+ * isMockProxy(regularObject); // false
3142
+ * isMockProxy(mockObject); // true
2986
3143
  * ```
2987
3144
  *
2988
- * @see MockState
2989
- * @see getParentObject
2990
- *
2991
- * @since 1.2.0
3145
+ * @since 1.2.2
2992
3146
  */
2993
- declare function spyOnProxyGet<T extends object, K extends keyof T>(target: T, key: K, method: unknown): MockState;
3147
+ declare function isMockProxy(value: Record<symbol, unknown>): boolean;
2994
3148
  /**
2995
- * Creates a spy on a specified static method or static property of a target class (not a class instance).
2996
- * Useful for mocking behavior during testing.
3149
+ * Creates a mock proxy that intercepts property access on an object.
2997
3150
  *
2998
- * @template Target - The type of the target class.
2999
- * @template Key - The static method or static property key on the target object to spy on.
3151
+ * @template T - The type of the target object being proxied
3152
+ * @param target - The object to be proxied
3153
+ * @returns A MockProxyInterface that intercepts property access on the target
3000
3154
  *
3001
- * @param target - The object on which to spy.
3002
- * @param key - The key of the method or property of the target to spy on.
3003
- * @returns If the spied-on property is a function, returns a `MockState` object for the function,
3004
- * allowing tracking of calls and modifying the return value or behavior.
3005
- * Otherwise, returns a `MockState` object for the property, enabling tracking and manipulation of its value.
3155
+ * @remarks
3156
+ * This function creates a proxy around an object that allows for interception
3157
+ * and customization of property access. The proxy maintains an internal state
3158
+ * that tracks mocked properties and provides mechanisms for customizing getter behavior.
3006
3159
  *
3007
- * @throws Error Throws an error if the `target` is a primitive value.
3008
- * @throws Error Throws an error if `key` is null or undefined.
3009
- * @throws Error Throws an error if the specified property does not exist on the target object.
3160
+ * The proxy implements special properties:
3161
+ * - `__isMockProxy__`: Used to identify mock proxy objects
3162
+ * - `__MockMap__`: Provides access to the internal state for managing mocks
3010
3163
  *
3011
- * @remarks
3012
- * This function is commonly used in testing environments to replace or monitor functionality without
3013
- * altering the actual logic in the source code. It provides fine-grained control over target behavior.
3164
+ * Property access behavior:
3165
+ * 1. First checks if a custom getter is defined and uses it if available
3166
+ * 2. Then checks if the property has a specific mock implementation
3167
+ * 3. Falls back to the original property on the target object
3014
3168
  *
3015
3169
  * @example
3016
3170
  * ```ts
3017
- * class ClassTest {
3018
- * static name: string = 'ClassTest';
3171
+ * const user = { name: 'John', getAge: () => 30 };
3172
+ * const mockUser = createMockProxy(user);
3019
3173
  *
3020
- * static x(param: string) {
3021
- * console.log(`original static x ${ param }`);
3022
- * }
3023
- * }
3174
+ * // Access original property
3175
+ * console.log(mockUser.name); // "John"
3024
3176
  *
3025
- * const spy1 = xJet.spyOn(ClassTest, 'name');
3026
- * const spy2 = xJet.spyOn(ClassTest, 'x');
3177
+ * // Add a mock for a property
3178
+ * const mockMap = mockUser.__MockMap__;
3179
+ * mockMap.mocks.set('getAge', () => 25);
3027
3180
  *
3028
- * spy1.mockReturnValueOnce('Mock name');
3029
- * spy2.mockImplementationOnce((param: string) => {
3030
- * console.log(`Mock x ${ param }`);
3031
- * });
3032
- *
3033
- * console.log(ClassTest.name); // Mock name
3034
- * console.log(ClassTest.name); // ClassTest
3035
- *
3036
- * ClassTest.x('test1'); // Mock x test1
3037
- * ClassTest.x('test2'); // original static x test2
3181
+ * // Now returns the mock implementation
3182
+ * console.log(mockUser.getAge()); // 25
3038
3183
  * ```
3039
3184
  *
3040
- * @see FunctionType
3041
- * @see KeysExtendingConstructorType
3042
- *
3043
- * @since 1.0.0
3185
+ * @since 1.2.2
3044
3186
  */
3045
- declare function spyOnImplementation<Target, Key extends KeysExtendingConstructorType<Target>>(target: Target, key: Key): Target[Key] extends FunctionType ? MockState<ReturnType<Target[Key]>, Parameters<Target[Key]>, Target> : MockState<Target[Key], [], Target>;
3187
+ declare function createMockProxy<T extends object>(target: T): MockProxyInterface;
3046
3188
  /**
3047
- * Creates a mock spy on the specified method or constructor of the target object.
3189
+ * Creates a spy on a property access for a proxied object.
3048
3190
  *
3049
- * @template Target The type of the target object.
3050
- * @template Key The type of the method or constructor key on the target object.
3191
+ * @template T - The type of the target object
3192
+ * @template K - The key of the property to spy on
3051
3193
  *
3052
- * @param target - The object whose method or constructor needs to be spied on.
3053
- * @param key - The property key of the method or constructor to spy on.
3054
- * @return A mock state representing the spied method or constructor if the key corresponds to a constructor type;
3055
- * otherwise, throws a type error.
3056
- *
3057
- * @throws Error Throws an error if the `target` is a primitive value.
3058
- * @throws Error Throws an error if `key` is null or undefined.
3059
- * @throws Error Throws an error if the specified property does not exist on the target object.
3194
+ * @param target - The proxy object containing the property to spy on
3195
+ * @param prop - The name of the property to spy on
3196
+ * @returns A MockState object wrapping the property access
3060
3197
  *
3061
3198
  * @remarks
3062
- * This method is typically used for testing purposes to observe or manipulate calls to the method or constructor of an object.
3063
- * The returned mock state may allow additional configuration, such as altering its behavior or tracking calls.
3199
+ * This specialized spy function is designed to work with properties accessed through proxy objects.
3200
+ * It handles the complexities of intercepting property access in proxied objects by:
3201
+ *
3202
+ * 1. Locating the proxy object in the global scope if needed
3203
+ * 2. Converting a normal object to a mock proxy if it isn't already one
3204
+ * 3. Setting up a spy on the property get operation
3205
+ *
3206
+ * The function ensures proper cleanup by providing a cleanup function that removes
3207
+ * the spy from the proxy's internal mock map when the spy is restored.
3208
+ *
3209
+ * @throws Error - When the target object cannot be found in the global scope
3064
3210
  *
3065
3211
  * @example
3066
3212
  * ```ts
3067
- * const coolObject = {
3068
- * ClassTest: class {
3069
- * constructor(param: number) {
3070
- * console.log('original Constructor');
3071
- * }
3072
- *
3073
- * justAnFunction() {
3074
- * console.log('original justAnFunction');
3075
- * }
3076
- * }
3077
- * };
3078
- *
3079
- * const spy = xJet.spyOn(coolObject, 'ClassTest');
3080
- * spy.mockImplementationOnce((param: number) => {
3081
- * console.log(`mock Constructor with param: ${ param }`);
3213
+ * // With an existing proxy
3214
+ * const proxyObj = createMockProxy({ getData: () => 'data' });
3215
+ * const spy = spyOnProxyGet(proxyObj, 'getData');
3082
3216
  *
3083
- * return <any> {
3084
- * justAnFunction() {
3085
- * console.log('mock justAnFunction');
3086
- * }
3087
- * };
3088
- * });
3217
+ * proxyObj.getData(); // Spy records this call
3218
+ * spy.verify.called(); // Passes
3089
3219
  *
3090
- * const instance = new coolObject.ClassTest(1); // mock Constructor with param: 1
3091
- * instance.justAnFunction(); // mock justAnFunction
3220
+ * // With a normal object (will be converted to proxy)
3221
+ * const obj = { getValue: () => 42 };
3222
+ * const valueSpy = spyOnProxyGet(obj, 'getValue');
3092
3223
  *
3093
- * const instance2 = new coolObject.ClassTest(2); // original Constructor
3094
- * instance2.justAnFunction(); // original justAnFunction
3224
+ * obj.getValue(); // Spy records this call
3225
+ * valueSpy.verify.called(); // Passes
3095
3226
  * ```
3096
3227
  *
3097
- * @see ConstructorType
3098
- * @see ConstructorKeysType
3099
- *
3100
- * @since 1.0.0
3228
+ * @since 1.2.2
3101
3229
  */
3102
- declare function spyOnImplementation<Target, Key extends ConstructorKeysType<Target>>(target: Target, key: Key): Target[Key] extends ConstructorLikeType ? MockState<InstanceType<Target[Key]>, ConstructorParameters<Target[Key]>, Target> : never;
3230
+ declare function spyOnProxyGet<T extends Record<string | symbol, unknown>, K extends keyof T>(target: T, prop: K): MockState;
3103
3231
  /**
3104
- * Creates a spy on a specific method or property of the given target object.
3232
+ * Creates a spy on a method or property of an object.
3105
3233
  *
3106
- * @template Target - The type of the target object to spy on.
3107
- * @template Key - The key of the property or method to spy on within the target object.
3234
+ * @template T - The type of the target object
3235
+ * @template K - The key of the property or method to spy on
3108
3236
  *
3109
- * @param target - The target object containing the property or method to be spied upon.
3110
- * @param key - The name of the property or method on the target object to spy on.
3111
- * @returns If the spied target is a function, it returns a `MockState` object to observe calls and arguments of the function.
3112
- * Otherwise, it returns a `MockState` object to observe the value or state of the property.
3237
+ * @param target - The object containing the method or property to spy on
3238
+ * @param key - The name of the method or property to spy on
3239
+ * @returns A MockState object wrapping the original method or property
3113
3240
  *
3114
- * @throws Error Throws an error if the `target` is a primitive value.
3115
- * @throws Error Throws an error if `key` is null or undefined.
3116
- * @throws Error Throws an error if the specified property does not exist on the target object.
3241
+ * @remarks
3242
+ * This function creates a spy that wraps around an existing method or property on an object.
3243
+ * The spy tracks all calls to the method or access to the property while still executing the original functionality.
3117
3244
  *
3118
- * @remarks This method is commonly used in test environments to monitor and assert interactions with a specific property
3119
- * or method on an object. The returned `MockState` can be used to retrieve call history or observe mutations.
3245
+ * - For methods: The spy preserves the original `this` context and passes all arguments to the original method
3246
+ * - For properties: The spy intercepts property access and returns the original value
3120
3247
  *
3121
3248
  * @example
3122
3249
  * ```ts
3123
- * const coolObject = {
3124
- * myMethod() {
3125
- * return 'Original myMethod';
3126
- * },
3127
- * coolString: 'Original coolString'
3250
+ * // Spying on a method
3251
+ * const user = {
3252
+ * getName: (prefix: string) => prefix + ' John'
3128
3253
  * };
3254
+ * const spy = xJet.spyOn(user, 'getName');
3129
3255
  *
3130
- * const spy = xJet.spyOn(coolObject, 'coolString');
3131
- * const spy2 = xJet.spyOn(coolObject, 'myMethod');
3132
- *
3133
- * spy.mockImplementationOnce(() => 'mock coolString');
3134
- * spy2.mockImplementationOnce(() => 'mock myMethod string');
3135
- *
3136
- * console.log(coolObject.coolString); // mock coolString
3137
- * console.log(coolObject.coolString); // Original coolString
3138
- * console.log(coolObject.myMethod()); // mock myMethod string
3139
- * console.log(coolObject.myMethod()); // Original myMethod
3256
+ * user.getName('Mr.'); // Returns "Mr. John"
3140
3257
  * ```
3141
3258
  *
3142
- * @see FunctionType
3143
- *
3144
3259
  * @since 1.0.0
3145
3260
  */
3146
- declare function spyOnImplementation<Target, Key extends keyof Target>(target: Target, key: Key): Target[Key] extends FunctionType ? MockState<ReturnType<Target[Key]>, Parameters<Target[Key]>, ThisParameterType<Target[Key]>> : MockState<Target[Key] | void, [Target[Key]], ThisParameterType<Target[Key]>>;
3261
+ declare function spyOnImplementation<T extends object, K extends keyof T>(target: T, key: K): T[K] extends FunctionType ? MockState<(this: ThisParameterType<T[K]>, ...args: Parameters<T[K]>) => ReturnType<T[K]>> : MockState<() => T[K]>;
3147
3262
 
3148
3263
  /**
3149
- * Import will remove at compile time
3150
- */
3151
- /**
3152
- * A utility type that removes all index signatures (string and number keys) from the given type `T`.
3153
- * This results in a new type that retains only explicitly defined properties.
3154
- *
3155
- * @template T - The type from which index signatures are to be removed.
3156
- *
3157
- * @remarks
3158
- * This type is useful for filtering out index signatures from types, especially when working
3159
- * with mapped or dynamic types where indexable properties are not desired.
3160
- * When an object has an index signature (e.g., `[key: string]: any`), TypeScript assumes that all
3161
- * possible string or number keys exist on the object. This utility type filters out such keys,
3162
- * leaving only explicitly defined properties.
3163
- *
3164
- * @see https://stackoverflow.com/a/66252656/4536543
3165
- *
3166
- * @since 1.0.0
3167
- */
3168
- type RemoveIndexType<T> = {
3169
- [P in keyof T as string extends P ? never : number extends P ? never : P]: T[P];
3170
- };
3171
- /**
3172
- * A utility type that maps the keys of a given type `T` whose properties are constructor types.
3173
- *
3174
- * This type iterates over the properties of `RemoveIndexType<T>`,
3175
- * retaining only those keys where the value matches a constructor type.
3176
- *
3177
- * @template T - The target type from which constructor-like properties are to be extracted.
3178
- *
3179
- * @remarks
3180
- * This type is designed to filter out keys of a given type `T` to include only those that are associated with constructor functions.
3181
- * It leverages mapped types along with conditional type checks to achieve this functionality.
3182
- *
3183
- * @since 1.0.0
3184
- */
3185
- type PropertiesWithConstructorsType<T> = {
3186
- [Key in keyof RemoveIndexType<T> as RemoveIndexType<T>[Key] extends ConstructorType ? Key : never]: RemoveIndexType<T>[Key];
3187
- };
3188
- /**
3189
- * A utility type that extracts the keys of the provided type `T` that correspond
3190
- * to properties with constructor types, removing any index signatures.
3191
- *
3192
- * @template T - The object type from which constructor property keys are extracted.
3264
+ * Interface representing the internal state of a mock proxy.
3193
3265
  *
3194
3266
  * @remarks
3195
- * This type is useful for narrowing down a type to only the keys representing
3196
- * properties with constructor functions (e.g., classes) while excluding index signatures.
3267
+ * This interface defines the structure for storing and managing the internal state
3268
+ * of mock proxies, including mock implementations and custom property access behavior.
3197
3269
  *
3198
- * @since 1.0.0
3270
+ * @since 1.2.2
3199
3271
  */
3200
- type ConstructorKeysType<T> = RemoveIndexType<keyof PropertiesWithConstructorsType<T>>;
3272
+ interface MockProxyStateInterface {
3273
+ /**
3274
+ * Map storing mock implementations for specific properties.
3275
+ * Keys are property names, values are the mock implementations.
3276
+ *
3277
+ * @since 1.2.2
3278
+ */
3279
+ mocks: Map<PropertyKey, unknown>;
3280
+ /**
3281
+ * Optional custom getter function that overrides default property access behavior.
3282
+ * When provided, this function is called for all property access on the mock proxy.
3283
+ *
3284
+ * @since 1.2.2
3285
+ */
3286
+ customGetter: ((target: object, prop: PropertyKey, receiver: unknown) => unknown) | null;
3287
+ }
3201
3288
  /**
3202
- * A utility type that extracts the keys of a type `T` if `T` extends a constructor type.
3203
- * If `T` does not extend a constructor type, it resolves to `never`.
3204
- *
3205
- * @template T - The type to check and extract keys from.
3206
- *
3207
- * @param T - The generic type parameter which is evaluated against a constructor type.
3289
+ * Interface representing a mock proxy object.
3208
3290
  *
3209
3291
  * @remarks
3210
- * This type is particularly useful when working with class-like or constructor-based types.
3211
- * It further applies `RemoveIndexType` to exclude index signatures from the resulting keys.
3292
+ * A `MockProxyInterface` defines the structure of objects that have been
3293
+ * wrapped by a mocking proxy system. These proxies intercept property access
3294
+ * and allow for dynamic replacement or monitoring of object properties.
3212
3295
  *
3213
- * @since 1.0.0
3296
+ * @since 1.2.2
3214
3297
  */
3215
- type KeysExtendingConstructorType<T> = T extends ConstructorType ? keyof RemoveIndexType<T> : never;
3298
+ interface MockProxyInterface extends Record<PropertyKey, unknown> {
3299
+ /**
3300
+ * A boolean flag that indicates this object is a mock proxy.
3301
+ * Used for type checking and identification of mock objects.
3302
+ *
3303
+ * @since 1.2.2
3304
+ */
3305
+ readonly __isMockProxy__?: true;
3306
+ /**
3307
+ * Provides access to the internal state of the mock proxy,
3308
+ * including mapped mock implementations and custom getter functions.
3309
+ *
3310
+ * @since 1.2.2
3311
+ */
3312
+ readonly __MockMap__?: MockProxyStateInterface;
3313
+ }
3216
3314
 
3217
3315
  /**
3218
3316
  * Import will remove at compile time
@@ -3220,41 +3318,6 @@ type KeysExtendingConstructorType<T> = T extends ConstructorType ? keyof RemoveI
3220
3318
  /**
3221
3319
  * Imports
3222
3320
  */
3223
- /**
3224
- * Finds the parent object and name of a given function or value in the global scope.
3225
- *
3226
- * @param fn - The function or value to find in the global scope
3227
- * @returns An object containing the name and parent object of the function, or `undefined` if not found
3228
- *
3229
- * @remarks
3230
- * The `getParentObject` function attempts to locate where a function or value is defined
3231
- * within the global context (`globalThis`). It searches for the function's name in the
3232
- * global scope and also within properties of global objects. This is useful for
3233
- * determining the original location of a function or value in the global namespace.
3234
- *
3235
- * Responsibilities:
3236
- * - Finding functions directly attached to `globalThis`
3237
- * - Locating functions within objects in the global scope
3238
- * - Identifying functions by reference equality with global properties
3239
- * - Supporting both named and anonymous functions
3240
- *
3241
- * @example
3242
- * ```ts
3243
- * // Finding a global function
3244
- * const result = getParentObject(setTimeout);
3245
- * // Returns: { name: 'setTimeout', parent: globalThis }
3246
- *
3247
- * // Finding a method on a global object
3248
- * const arrayResult = getParentObject(Array.prototype.map);
3249
- * // Returns: { name: 'map', parent: Array.prototype }
3250
- * ```
3251
- *
3252
- * @since 1.2.0
3253
- */
3254
- declare function getParentObject(fn: unknown): {
3255
- name: string;
3256
- object: Record<string, unknown>;
3257
- } | undefined;
3258
3321
  /**
3259
3322
  * Creates a mock for an object property using property descriptors.
3260
3323
  *
@@ -3292,8 +3355,8 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
3292
3355
  * Creates a mock function interface with the specified implementation and optional restore function.
3293
3356
  *
3294
3357
  * @template ReturnType - The return type of the mocked function.
3295
- * @template Context - The context type that the mocked function binds to.
3296
3358
  * @template Args - The argument type of the mocked function. Defaults to an array of unknown values.
3359
+ * @template Context - The context type that the mocked function binds to.
3297
3360
  *
3298
3361
  * @param implementation - An optional implementation of the mocked function.
3299
3362
  * @param restore - An optional restore function used to reset the mock.
@@ -3306,7 +3369,7 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
3306
3369
  * Responsibilities:
3307
3370
  * - Creating mock functions with custom implementations
3308
3371
  * - Supporting restore functionality for resetting mocks
3309
- * - Providing type-safe mock interfaces via {@link FnMockInterface}
3372
+ * - Providing type-safe mock interfaces via {@link MockableFunctionInterface}
3310
3373
  * - Integrating with the {@link MockState} system
3311
3374
  *
3312
3375
  * @example
@@ -3321,61 +3384,80 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
3321
3384
  * ```
3322
3385
  *
3323
3386
  * @see MockState
3324
- * @see FnMockInterface
3387
+ * @see MockableFunctionInterface
3325
3388
  * @see FunctionLikeType
3326
3389
  *
3327
3390
  * @since 1.2.0
3328
3391
  */
3329
- declare function fnImplementation<ReturnType, Args extends Array<unknown>, Context>(implementation?: FunctionLikeType<ReturnType, Args, Context>, restore?: () => FunctionLikeType<ReturnType, Args, Context> | void): FnMockInterface<ReturnType, Args, Context>;
3392
+ declare function fnImplementation<ReturnType, Args extends Array<unknown>, Context>(implementation?: FunctionLikeType<ReturnType, Args, Context>, restore?: () => FunctionLikeType<ReturnType, Args, Context> | void): MockableFunctionInterface<FunctionLikeType<ReturnType, Args, Context>>;
3330
3393
  /**
3331
- * Creates a mock function with an optional custom implementation.
3394
+ * Creates a mock implementation of the provided class constructor.
3395
+ *
3396
+ * @param method - The class constructor to mock
3397
+ * @param implementation - Optional custom implementation of the mocked constructor
3398
+ * @returns The mock state associated with the mocked constructor
3332
3399
  *
3333
- * @template Method - The return type of the function being mocked
3334
- * @template Args - The argument types for the function, defaulting to unknown array
3335
- * @template Context - The context type (`this`) for the function, defaulting to unknown
3400
+ * @remarks
3401
+ * This overload of the mockImplementation function is specifically designed for mocking class constructors.
3402
+ * It allows for replacing a class implementation during testing while tracking instantiation.
3336
3403
  *
3337
- * @param method - The original function to mock
3338
- * @param implementation - Optional custom implementation to use instead of the original
3339
- * @returns A {@link MockState} instance that wraps the original function
3404
+ * The implementation function can return a partial instance of the class, which will be used
3405
+ * as the constructed object when the mock is called with 'new'.
3406
+ *
3407
+ * @example
3408
+ * ```ts
3409
+ * class User {
3410
+ * name: string;
3411
+ * age: number;
3412
+ * constructor (name: string, age: number) {
3413
+ * this.name = name;
3414
+ * this.age = age;
3415
+ * }
3416
+ * }
3417
+ *
3418
+ * const MockUser = mockImplementation(User, (name, age) => ({ name, age: age + 1 }));
3419
+ * const user = new MockUser('Alice', 30); // user.age === 31
3420
+ * MockUser.verify.called(); // passes
3421
+ * ```
3422
+ *
3423
+ * @since 1.2.2
3424
+ */
3425
+ declare function mockImplementation<F extends abstract new (...args: any) => any>(method: F, implementation?: (...args: ConstructorParameters<F>) => Partial<InstanceType<F>>): MockState<(...args: ConstructorParameters<F>) => Partial<InstanceType<F>>>;
3426
+ /**
3427
+ * Creates a mock implementation of the provided function.
3428
+ *
3429
+ * @param method - The function to mock
3430
+ * @param implementation - Optional custom implementation that returns a partial result
3431
+ * @returns The mock state associated with the mocked function
3340
3432
  *
3341
3433
  * @remarks
3342
- * The `mockImplementation` function creates a new {@link MockState} instance that wraps
3343
- * around a provided function, allowing you to monitor calls to that function and optionally
3344
- * override its implementation. This is particularly useful for testing components that
3345
- * depend on external functions by providing controlled behavior during tests.
3434
+ * This overload of the mockImplementation function allows for providing an implementation
3435
+ * that returns a partial result object. This is particularly useful when mocking functions
3436
+ * that return complex objects where only specific properties are relevant for testing.
3346
3437
  *
3347
- * Responsibilities:
3348
- * - Creating a trackable mock function from any original function
3349
- * - Supporting custom implementation override capability
3350
- * - Preserving the original function's signature and return type
3351
- * - Enabling all mock functionality like call tracking and verification
3352
- * - Maintaining type safety between the original and mocked functions
3438
+ * The implementation preserves the 'this' context from the original function, allowing
3439
+ * for proper method mocking on objects.
3353
3440
  *
3354
3441
  * @example
3355
3442
  * ```ts
3356
- * // Mock a function with default implementation
3357
- * const fetchData = async () => ({ id: 1, name: 'Test' });
3358
- * const mockedFetch = xJet.mock(fetchData);
3443
+ * interface User {
3444
+ * id: number;
3445
+ * name: string;
3446
+ * email: string;
3447
+ * }
3359
3448
  *
3360
- * // Mock with custom implementation
3361
- * const mockedFetchCustom = xJet.mock(fetchData, async () => {
3362
- * return { id: 2, name: 'Custom Test' };
3363
- * });
3449
+ * function getUser(id: number): User {
3450
+ * // real implementation
3451
+ * return { id, name: 'Real User', email: 'user@example.com' };
3452
+ * }
3364
3453
  *
3365
- * test('uses mocked function', async () => {
3366
- * const result = await mockedFetchCustom();
3367
- * expect(result.name).toBe('Custom Test');
3368
- * expect(mockedFetchCustom).toHaveBeenCalled();
3369
- * });
3454
+ * const mockGetUser = mockImplementation(getUser, (id) => ({ id, name: 'Mock User' }));
3455
+ * const user = mockGetUser(123); // { id: 123, name: 'Mock User' }
3370
3456
  * ```
3371
3457
  *
3372
- * @see MockState
3373
- * @see FunctionLikeType
3374
- * @see ConstructorLikeType
3375
- *
3376
- * @since 1.2.0
3458
+ * @since 1.2.2
3377
3459
  */
3378
- declare function mockImplementation<Method, Args extends Array<unknown> = [], Context = unknown>(method: FunctionLikeType<Method, Args, Context> | ConstructorLikeType<Method, Args>, implementation?: FunctionLikeType<Method, Args, Context>): MockState<Method, Args, Context>;
3460
+ declare function mockImplementation<F extends FunctionType>(method: F, implementation?: (...args: Parameters<F>) => Partial<ReturnType<F>>): MockState<(this: ThisParameterType<F>, ...args: Parameters<F>) => Partial<ReturnType<F>>>;
3379
3461
  /**
3380
3462
  * Creates a mock for an element with an optional custom implementation.
3381
3463
  *
@@ -3423,7 +3505,7 @@ declare function mockImplementation<Method, Args extends Array<unknown> = [], Co
3423
3505
  *
3424
3506
  * @since 1.2.0
3425
3507
  */
3426
- declare function mockImplementation<Element = unknown>(item: Element, implementation?: FunctionLikeType<Element>): MockState<Element>;
3508
+ declare function mockImplementation<Element = unknown>(item: Element, implementation?: () => Element): MockState<() => Element>;
3427
3509
 
3428
3510
  /**
3429
3511
  * Import will remove at compile time
@@ -3433,9 +3515,7 @@ declare function mockImplementation<Element = unknown>(item: Element, implementa
3433
3515
  * and argument list. This interface extends `MockState` to facilitate tracking
3434
3516
  * and testing of function behaviors and states.
3435
3517
  *
3436
- * @template ReturnType - Specifies the return type of the function. Defaults to `unknown`.
3437
- * @template Context - Defines the function's "this" context type. Defaults to `unknown`.
3438
- * @template Args - Sets the argument type(s) for the function, represented as an array. Defaults to `unknown[]`.
3518
+ * @template F - The function / class type being mocked
3439
3519
  *
3440
3520
  * @remarks
3441
3521
  * This interface is useful for creating test doubles or mock implementations that simulate
@@ -3446,9 +3526,137 @@ declare function mockImplementation<Element = unknown>(item: Element, implementa
3446
3526
  *
3447
3527
  * @since 1.0.0
3448
3528
  */
3449
- interface FnMockInterface<ReturnType = unknown, Args extends Array<unknown> = any, Context = any> extends MockState<ReturnType, Args, Context> {
3450
- new (...args: Args): ReturnType;
3451
- (this: Context, ...args: Args): ReturnType;
3529
+ interface MockableFunctionInterface<F extends FunctionType> extends MockState<F> {
3530
+ /**
3531
+ * Constructor signature when the mocked item is used with 'new'
3532
+ */
3533
+ new (...args: Parameters<F>): ReturnType<F>;
3534
+ /**
3535
+ * Function call signature preserving 'this' context and parameters
3536
+ */
3537
+ (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F>;
3538
+ }
3539
+
3540
+ /**
3541
+ * Import will remove at compile time
3542
+ */
3543
+ /**
3544
+ * Recursively searches for a specific element within an object or its nested properties.
3545
+ *
3546
+ * @param target - The object to search within.
3547
+ * @param element - The value to find within the target object or its nested properties.
3548
+ * @param key - Optional specific key to search for within the target object.
3549
+ * @param maxDepth - Maximum recursion depth to prevent infinite loops, defaults to 3.
3550
+ * @returns A {@link DeepSearchInterface} object containing parent and key if found, or null if not found.
3551
+ *
3552
+ * @remarks
3553
+ * This utility performs a depth-first search through an object's properties to locate a specific value
3554
+ * or a property with a specific key. It maintains a set of visited objects to prevent circular reference issues.
3555
+ *
3556
+ * The search process:
3557
+ * - Tracks visited objects to avoid circular references
3558
+ * - Searches by exact reference equality for the element
3559
+ * - Handles errors during property access
3560
+ * - Limits search depth to prevent stack overflow
3561
+ * - Can find elements by exact key name (when the `key` parameter is provided)
3562
+ *
3563
+ * @example
3564
+ * ```ts
3565
+ * const obj = {
3566
+ * a: 1,
3567
+ * b: {
3568
+ * c: 'test',
3569
+ * d: [1, 2, { e: 'target' }]
3570
+ * }
3571
+ * };
3572
+ *
3573
+ * // Find by value
3574
+ * const result = deepSearchObject(obj, 'target');
3575
+ * // result: { parent: { e: 'target' }, key: 'e' }
3576
+ *
3577
+ * // Find by key name
3578
+ * const byKey = deepSearchObject(obj, null, 'c');
3579
+ * // byKey: { parent: { c: 'test', d: [...] }, key: 'c' }
3580
+ * ```
3581
+ *
3582
+ * @see DeepSearchInterface
3583
+ * @since 1.0.0
3584
+ */
3585
+ declare function deepSearchObject(target: Record<string | symbol, unknown>, element: unknown, key?: string, maxDepth?: number): DeepSearchInterface | null;
3586
+ /**
3587
+ * Resolves property references that may be affected by ESBuild's `__toESM` transformation.
3588
+ *
3589
+ * @remarks
3590
+ * This function handles a specific issue with ESBuild's module transformation where Node.js
3591
+ * built-in modules (like 'fs', 'http', etc.) are wrapped with getter descriptors that aren't
3592
+ * configurable. This causes problems when trying to mock or modify these modules in testing.
3593
+ *
3594
+ * When ESBuild transforms CommonJS modules to ESM, it creates non-configurable getter properties
3595
+ * on the module object. This function detects such cases and returns a reference to the original
3596
+ * underlying object instead, making the property accessible for mocking or modification.
3597
+ *
3598
+ * @param parent - The object containing the property to resolve
3599
+ * @param key - The property name or symbol to resolve
3600
+ * @returns A {@link DeepSearchInterface} pointing to either the original object or the
3601
+ * underlying object in case of non-configurable ESBuild transformations
3602
+ *
3603
+ * @example
3604
+ * ```ts
3605
+ * // When working with an ESBuild transformed fs module
3606
+ * import * as fs from 'fs';
3607
+ *
3608
+ * // Normal access would use a non-configurable getter
3609
+ * // Making it impossible to mock
3610
+ * const originalRef = { parent: fs, key: 'readFileSync' };
3611
+ *
3612
+ * // This function resolves to the underlying object
3613
+ * const mockableRef = getOwnProperty(fs, 'readFileSync');
3614
+ * // Now we can mock it: mockableRef.parent[mockableRef.key] = mockFn;
3615
+ * ```
3616
+ *
3617
+ * @since 1.2.2
3618
+ */
3619
+ declare function getOwnProperty(parent: Record<string | symbol, unknown>, key: string | symbol): DeepSearchInterface;
3620
+
3621
+ /**
3622
+ * Interface representing the result of a deep object search operation.
3623
+ *
3624
+ * @remarks
3625
+ * This interface provides a structured way to return the results of an object traversal
3626
+ * search, containing both the parent object and the specific key where a target value was found.
3627
+ * It allows callers to not only determine if a value was found, but also access its
3628
+ * containing object and property name.
3629
+ *
3630
+ * The interface is typically used in deep search algorithms that need to return both
3631
+ * the location of a found item and provide access to its context.
3632
+ *
3633
+ * @example
3634
+ * ```ts
3635
+ * // Example result from a search operation
3636
+ * const result: DeepSearchInterface = {
3637
+ * parent: { id: 123, name: 'example' },
3638
+ * key: 'name'
3639
+ * };
3640
+ *
3641
+ * // Accessing the found value through the result
3642
+ * const foundValue = result.parent[result.key]; // 'example'
3643
+ * ```
3644
+ *
3645
+ * @since 1.2.2
3646
+ */
3647
+ interface DeepSearchInterface {
3648
+ /**
3649
+ * The property key (name) where the searched element was found.
3650
+ *
3651
+ * @since 1.2.2
3652
+ */
3653
+ key: string | symbol;
3654
+ /**
3655
+ * The parent object containing the found element.
3656
+ *
3657
+ * @since 1.2.2
3658
+ */
3659
+ parent: Record<string | symbol, unknown>;
3452
3660
  }
3453
3661
 
3454
3662
  /**