@remotex-labs/xjet 1.2.1 → 1.2.3

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