@remotex-labs/xjet 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -4,11 +4,9 @@
4
4
  * DO NOT EDIT MANUALLY.
5
5
  */
6
6
  import type { xExpect } from '@remotex-labs/xjet-expect';
7
- import type { ConstructorLikeType, FunctionLikeType } from '@remotex-labs/xjet-expect';
8
- import type { FunctionLikeType, RejectedValueType, ResolvedValueType } from '@remotex-labs/xjet-expect';
9
- import type { ConstructorLikeType, FunctionType } from '@remotex-labs/xjet-expect';
10
- import type { ConstructorType } from '@remotex-labs/xjet-expect';
7
+ import type { FunctionLikeType, FunctionType } from '@remotex-labs/xjet-expect';
11
8
  import type { FunctionType } from '@remotex-labs/xjet-expect';
9
+ import type { FunctionType, RejectedValueType, ResolvedValueType } from '@remotex-labs/xjet-expect';
12
10
  import type { ContextType } from '@remotex-labs/xjet-expect';
13
11
  import type { FunctionLikeType } from '@remotex-labs/xjet-expect';
14
12
  import type { ContextType, FunctionType } from '@remotex-labs/xjet-expect';
@@ -76,41 +74,6 @@ export {};
76
74
  /**
77
75
  * Imports
78
76
  */
79
- /**
80
- * Finds the parent object and name of a given function or value in the global scope.
81
- *
82
- * @param fn - The function or value to find in the global scope
83
- * @returns An object containing the name and parent object of the function, or `undefined` if not found
84
- *
85
- * @remarks
86
- * The `getParentObject` function attempts to locate where a function or value is defined
87
- * within the global context (`globalThis`). It searches for the function's name in the
88
- * global scope and also within properties of global objects. This is useful for
89
- * determining the original location of a function or value in the global namespace.
90
- *
91
- * Responsibilities:
92
- * - Finding functions directly attached to `globalThis`
93
- * - Locating functions within objects in the global scope
94
- * - Identifying functions by reference equality with global properties
95
- * - Supporting both named and anonymous functions
96
- *
97
- * @example
98
- * ```ts
99
- * // Finding a global function
100
- * const result = getParentObject(setTimeout);
101
- * // Returns: { name: 'setTimeout', parent: globalThis }
102
- *
103
- * // Finding a method on a global object
104
- * const arrayResult = getParentObject(Array.prototype.map);
105
- * // Returns: { name: 'map', parent: Array.prototype }
106
- * ```
107
- *
108
- * @since 1.2.0
109
- */
110
- declare function getParentObject(fn: unknown): {
111
- name: string;
112
- object: Record<string, unknown>;
113
- } | undefined;
114
77
  /**
115
78
  * Creates a mock for an object property using property descriptors.
116
79
  *
@@ -148,8 +111,8 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
148
111
  * Creates a mock function interface with the specified implementation and optional restore function.
149
112
  *
150
113
  * @template ReturnType - The return type of the mocked function.
151
- * @template Context - The context type that the mocked function binds to.
152
114
  * @template Args - The argument type of the mocked function. Defaults to an array of unknown values.
115
+ * @template Context - The context type that the mocked function binds to.
153
116
  *
154
117
  * @param implementation - An optional implementation of the mocked function.
155
118
  * @param restore - An optional restore function used to reset the mock.
@@ -162,7 +125,7 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
162
125
  * Responsibilities:
163
126
  * - Creating mock functions with custom implementations
164
127
  * - Supporting restore functionality for resetting mocks
165
- * - Providing type-safe mock interfaces via {@link FnMockInterface}
128
+ * - Providing type-safe mock interfaces via {@link MockableFunctionInterface}
166
129
  * - Integrating with the {@link MockState} system
167
130
  *
168
131
  * @example
@@ -177,61 +140,80 @@ declare function mockDescriptorProperty<T extends object>(target: T, key: string
177
140
  * ```
178
141
  *
179
142
  * @see MockState
180
- * @see FnMockInterface
143
+ * @see MockableFunctionInterface
181
144
  * @see FunctionLikeType
182
145
  *
183
146
  * @since 1.2.0
184
147
  */
185
- declare function fnImplementation<ReturnType, Args extends Array<unknown>, Context>(implementation?: FunctionLikeType<ReturnType, Args, Context>, restore?: () => FunctionLikeType<ReturnType, Args, Context> | void): FnMockInterface<ReturnType, Args, Context>;
148
+ 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>>;
186
149
  /**
187
- * Creates a mock function with an optional custom implementation.
150
+ * Creates a mock implementation of the provided class constructor.
151
+ *
152
+ * @param method - The class constructor to mock
153
+ * @param implementation - Optional custom implementation of the mocked constructor
154
+ * @returns The mock state associated with the mocked constructor
188
155
  *
189
- * @template Method - The return type of the function being mocked
190
- * @template Args - The argument types for the function, defaulting to unknown array
191
- * @template Context - The context type (`this`) for the function, defaulting to unknown
156
+ * @remarks
157
+ * This overload of the mockImplementation function is specifically designed for mocking class constructors.
158
+ * It allows for replacing a class implementation during testing while tracking instantiation.
192
159
  *
193
- * @param method - The original function to mock
194
- * @param implementation - Optional custom implementation to use instead of the original
195
- * @returns A {@link MockState} instance that wraps the original function
160
+ * The implementation function can return a partial instance of the class, which will be used
161
+ * as the constructed object when the mock is called with 'new'.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * class User {
166
+ * name: string;
167
+ * age: number;
168
+ * constructor (name: string, age: number) {
169
+ * this.name = name;
170
+ * this.age = age;
171
+ * }
172
+ * }
173
+ *
174
+ * const MockUser = mockImplementation(User, (name, age) => ({ name, age: age + 1 }));
175
+ * const user = new MockUser('Alice', 30); // user.age === 31
176
+ * MockUser.verify.called(); // passes
177
+ * ```
178
+ *
179
+ * @since 1.2.2
180
+ */
181
+ declare function mockImplementation<F extends abstract new (...args: any) => any>(method: F, implementation?: (...args: ConstructorParameters<F>) => Partial<InstanceType<F>>): MockState<(...args: ConstructorParameters<F>) => Partial<InstanceType<F>>>;
182
+ /**
183
+ * Creates a mock implementation of the provided function.
184
+ *
185
+ * @param method - The function to mock
186
+ * @param implementation - Optional custom implementation that returns a partial result
187
+ * @returns The mock state associated with the mocked function
196
188
  *
197
189
  * @remarks
198
- * The `mockImplementation` function creates a new {@link MockState} instance that wraps
199
- * around a provided function, allowing you to monitor calls to that function and optionally
200
- * override its implementation. This is particularly useful for testing components that
201
- * depend on external functions by providing controlled behavior during tests.
190
+ * This overload of the mockImplementation function allows for providing an implementation
191
+ * that returns a partial result object. This is particularly useful when mocking functions
192
+ * that return complex objects where only specific properties are relevant for testing.
202
193
  *
203
- * Responsibilities:
204
- * - Creating a trackable mock function from any original function
205
- * - Supporting custom implementation override capability
206
- * - Preserving the original function's signature and return type
207
- * - Enabling all mock functionality like call tracking and verification
208
- * - Maintaining type safety between the original and mocked functions
194
+ * The implementation preserves the 'this' context from the original function, allowing
195
+ * for proper method mocking on objects.
209
196
  *
210
197
  * @example
211
198
  * ```ts
212
- * // Mock a function with default implementation
213
- * const fetchData = async () => ({ id: 1, name: 'Test' });
214
- * const mockedFetch = xJet.mock(fetchData);
199
+ * interface User {
200
+ * id: number;
201
+ * name: string;
202
+ * email: string;
203
+ * }
215
204
  *
216
- * // Mock with custom implementation
217
- * const mockedFetchCustom = xJet.mock(fetchData, async () => {
218
- * return { id: 2, name: 'Custom Test' };
219
- * });
205
+ * function getUser(id: number): User {
206
+ * // real implementation
207
+ * return { id, name: 'Real User', email: 'user@example.com' };
208
+ * }
220
209
  *
221
- * test('uses mocked function', async () => {
222
- * const result = await mockedFetchCustom();
223
- * expect(result.name).toBe('Custom Test');
224
- * expect(mockedFetchCustom).toHaveBeenCalled();
225
- * });
210
+ * const mockGetUser = mockImplementation(getUser, (id) => ({ id, name: 'Mock User' }));
211
+ * const user = mockGetUser(123); // { id: 123, name: 'Mock User' }
226
212
  * ```
227
213
  *
228
- * @see MockState
229
- * @see FunctionLikeType
230
- * @see ConstructorLikeType
231
- *
232
- * @since 1.2.0
214
+ * @since 1.2.2
233
215
  */
234
- 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>;
216
+ declare function mockImplementation<F extends FunctionType>(method: F, implementation?: (...args: Parameters<F>) => Partial<ReturnType<F>>): MockState<(this: ThisParameterType<F>, ...args: Parameters<F>) => Partial<ReturnType<F>>>;
235
217
  /**
236
218
  * Creates a mock for an element with an optional custom implementation.
237
219
  *
@@ -279,7 +261,7 @@ declare function mockImplementation<Method, Args extends Array<unknown> = [], Co
279
261
  *
280
262
  * @since 1.2.0
281
263
  */
282
- declare function mockImplementation<Element = unknown>(item: Element, implementation?: FunctionLikeType<Element>): MockState<Element>;
264
+ declare function mockImplementation<Element = unknown>(item: Element, implementation?: () => Element): MockState<() => Element>;
283
265
 
284
266
  /**
285
267
  * Import will remove at compile time
@@ -289,9 +271,7 @@ declare function mockImplementation<Element = unknown>(item: Element, implementa
289
271
  * and argument list. This interface extends `MockState` to facilitate tracking
290
272
  * and testing of function behaviors and states.
291
273
  *
292
- * @template ReturnType - Specifies the return type of the function. Defaults to `unknown`.
293
- * @template Context - Defines the function's "this" context type. Defaults to `unknown`.
294
- * @template Args - Sets the argument type(s) for the function, represented as an array. Defaults to `unknown[]`.
274
+ * @template F - The function / class type being mocked
295
275
  *
296
276
  * @remarks
297
277
  * This interface is useful for creating test doubles or mock implementations that simulate
@@ -302,32 +282,62 @@ declare function mockImplementation<Element = unknown>(item: Element, implementa
302
282
  *
303
283
  * @since 1.0.0
304
284
  */
305
- interface FnMockInterface<ReturnType = unknown, Args extends Array<unknown> = any, Context = any> extends MockState<ReturnType, Args, Context> {
306
- new (...args: Args): ReturnType;
307
- (this: Context, ...args: Args): ReturnType;
285
+ interface MockableFunctionInterface<F extends FunctionType> extends MockState<F> {
286
+ /**
287
+ * Constructor signature when the mocked item is used with 'new'
288
+ */
289
+ new (...args: Parameters<F>): ReturnType<F>;
290
+ /**
291
+ * Function call signature preserving 'this' context and parameters
292
+ */
293
+ (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F>;
308
294
  }
309
295
 
310
296
  /**
311
297
  * Import will remove at compile time
312
298
  */
313
299
  /**
314
- * A class representing the mock state for tracking and managing the behavior of mocked functions or classes.
300
+ * A powerful mock state manager for simulating functions and classes in tests.
315
301
  *
316
- * @template ReturnType - The type of value returned by the mock function.
317
- * @template Context - The type representing the context (`this` value) used in the mock function.
318
- * @template Args - The types of arguments for the mocked function.
302
+ * @template F - The function signature being mocked, defaults to any function
319
303
  *
320
304
  * @remarks
321
- * This class provides mechanisms to customize and manage the behavior of mocked functions or constructors.
322
- * It tracks invocation details, allows for behavior customization, and enables resetting or restoring the mock to its original state.
305
+ * MockState provides a complete mocking solution. It tracks
306
+ * all invocations, including arguments, return values, and contexts, while also allowing
307
+ * customization of behavior through various methods like `mockImplementation` and
308
+ * `mockReturnValue`.
309
+ *
310
+ * Key features:
311
+ * - Tracks call arguments, return values, and execution contexts
312
+ * - Supports one-time implementations and return values
313
+ * - Manages Promise resolutions and rejections
314
+ * - Provides methods for resetting or restoring mock state
315
+ * - Preserves the interface of the original function
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * // Create a basic mock
320
+ * const mockFn = new MockState();
321
+ *
322
+ * // Configure return values
323
+ * mockFn.mockReturnValue('default');
324
+ * mockFn.mockReturnValueOnce('first call');
325
+ *
326
+ * // Use the mock
327
+ * console.log(mockFn()); // 'first call'
328
+ * console.log(mockFn()); // 'default'
329
+ *
330
+ * // Inspect calls
331
+ * console.log(mockFn.mock.calls); // [[], []]
332
+ * ```
323
333
  *
324
- * @since v1.0.0
334
+ * @since 1.0.0
325
335
  */
326
- export declare class MockState<ReturnType = unknown, Args extends Array<unknown> = unknown[], Context = unknown> extends Function {
336
+ export declare class MockState<F extends FunctionType = FunctionType> extends Function {
327
337
  /**
328
- * List of all mocks that created
338
+ * List of all mocks that created as WeakRef
329
339
  */
330
- static mocks: Array<MockState>;
340
+ static mocks: Set<WeakRef<MockState>>;
331
341
  /**
332
342
  * The `name` property represents the name of the mock function.
333
343
  */
@@ -337,555 +347,674 @@ export declare class MockState<ReturnType = unknown, Args extends Array<unknown>
337
347
  */
338
348
  readonly xJetMock: boolean;
339
349
  /**
340
- * The `state` property holds the detailed state of the mock invocations.
341
- * It tracks information such as the arguments passed, the results returned, the context (`this` value) used,
342
- * the instances created, and the order of invocations.
343
- * This data is automatically updated after each call to the mock.
350
+ * Holds the current state of the mock, including all invocation records.
344
351
  *
345
- * @template ReturnType - The type of value returned by the mock function.
346
- * @template Context - The type representing the context (`this` value) used in the mock function.
347
- * @template Args - The types of arguments for the mocked function.
352
+ * @remarks
353
+ * This property tracks the complete history of the mock's usage, storing
354
+ * information like call arguments, return values, execution contexts,
355
+ * instances, and the order of invocations.
348
356
  *
349
- * @see MocksStateInterface
357
+ * It's initialized with empty arrays for tracking and gets updated with
358
+ * each invocation. This state is what powers the inspection capabilities
359
+ * accessible via the public `mock` getter.
350
360
  *
351
- * @since v1.0.0
361
+ * @since 1.0.0
352
362
  */
353
363
  private state;
354
364
  /**
355
- * A private function that restores the mock's original implementation.
365
+ * Stores one-time implementations to be used on successive invocations.
356
366
  *
357
367
  * @remarks
358
- * The `restore` function is responsible for resetting the mock to its initial state.
359
- * It works in conjunction with methods like `mockReset` and `mockRestore` to ensure
360
- * proper restoration of the mock's behavior.
361
- *
362
- * Responsibilities:
363
- * - Returning the original implementation when restoring the mock
364
- * - Ensuring consistent reset behavior across mock operations
365
- * - Supporting the {@link mockRestore} method's functionality
366
- * - Maintaining mock state integrity during restoration
368
+ * This queue contains functions that will be consumed in FIFO order
369
+ * (first-in, first-out) when the mock is called. Each implementation
370
+ * is used exactly once and then removed from the queue.
367
371
  *
368
- * @see MockState.mockRestore
369
- * @see MockState.originalImplementation
372
+ * When adding implementations with `mockImplementationOnce()` or similar
373
+ * methods, they are pushed to this queue. On invocation, the mock will
374
+ * check this queue first, using and removing the oldest implementation
375
+ * if available, or falling back to the default implementation.
370
376
  *
371
- * @since 1.2.0
377
+ * @since 1.0.0
372
378
  */
373
- private readonly restore?;
379
+ private queuedImplementations;
374
380
  /**
375
- * A private array that stores the implementations queued to be executed
376
- * for future invocations of the mock.
377
- * Each function in this array is invoked in sequence when the mock function is called,
378
- * with the first queued implementation being used on the first call, the second on the second call, and so on.
381
+ * The current default implementation for this mock.
379
382
  *
380
- * This property is used in conjunction with methods like `mockImplementationOnce`
381
- * to specify different behaviors for consecutive calls to the mock.
383
+ * @remarks
384
+ * This property holds the function that will be executed when the mock is called,
385
+ * unless overridden by a queued one-time implementation. It can be set using
386
+ * the `mockImplementation()` method and retrieved with `getMockImplementation()`.
382
387
  *
383
- * @since v1.0.0
384
- */
385
- private queuedImplementations;
386
- /**
387
- * A private property that holds the current implementation of the mock function.
388
- * This function is executed whenever the mock is invoked and can be changed
389
- * using methods like `mockImplementation` or `mockImplementationOnce`.
388
+ * If not explicitly set, it defaults to `undefined`, meaning the mock will
389
+ * return `undefined` when called (after any queued implementations are used).
390
390
  *
391
- * The `implementation` allows for customizing the behavior of the mock,
392
- * such as returning specific values, throwing errors, or performing actions.
391
+ * This implementation determines the behavior of the mock for all calls that
392
+ * don't have a specific one-time implementation in the queue.
393
393
  *
394
- * @since v1.0.0
394
+ * @since 1.0.0
395
395
  */
396
396
  private implementation;
397
397
  /**
398
- * A private property that holds the original implementation of the mock function.
399
- * This is the initial function passed to the constructor that defines the mock's default behavior
400
- * before any customization.
401
- *
402
- * @template ReturnType - The type of value returned by the original function.
403
- * @template Args - The types of arguments for the original function.
404
- * @template Context - The type representing the context (`this` value) used in the original function.
398
+ * Preserves the original implementation provided when creating the mock.
405
399
  *
406
400
  * @remarks
407
- * This property stores the initial implementation provided when creating the mock.
408
- * If no implementation is provided during construction, it defaults to a function
409
- * that returns `undefined` cast to the appropriate return type.
410
- * Unlike `implementation` which can be modified, this property maintains a reference
411
- * to the original function for scenarios where the original behavior needs to be preserved
412
- * or restored.
401
+ * This property stores the initial function passed to the constructor, allowing
402
+ * the mock to be restored to its original behavior later using `mockRestore()`.
403
+ *
404
+ * If no implementation was provided in the constructor, this will contain a
405
+ * function that returns `undefined` when called.
413
406
  *
414
- * @see FunctionLikeType
415
- * @see MockState.original
407
+ * The original implementation is immutable and serves as a reference point
408
+ * for resetting the mock to its initial state.
416
409
  *
417
410
  * @since 1.0.0
418
411
  */
419
412
  private readonly originalImplementation;
420
413
  /**
421
- * Constructs a mock object that allows custom implementation, restore capability,
422
- * and optional naming functionality. This mock is proxied to handle function invocation
423
- * and class instantiation.
414
+ * Optional cleanup function to be called when the mock is restored.
424
415
  *
425
- * @template ReturnType - The type of the value returned by the mock function.
426
- * @template Context - The type of the context (`this`) for the mock function.
427
- * @template Args - The type of arguments accepted by the mock function.
416
+ * @remarks
417
+ * If provided, this function will be executed when `mockRestore()` is called,
418
+ * allowing for custom cleanup operations. This is particularly useful when
419
+ * creating mocks that replace methods or properties on existing objects.
420
+ *
421
+ * The restore function should handle any necessary teardown, such as
422
+ * restoring original object properties, removing event listeners, or
423
+ * closing connections that were established during mock creation.
424
+ *
425
+ * @since 1.0.0
426
+ */
427
+ private readonly restore?;
428
+ /**
429
+ * Creates a new instance of a mock function.
428
430
  *
429
- * @param implementation - Optional implementation for the mock function.
430
- * @param restore - Optional function to restore the mock to its initial state. Defaults to resetting to the provided implementation.
431
- * @param name - Optional name for the mock instance. Default to a predefined mock name if not provided.
431
+ * @template F - The function type being mocked. This generic type parameter allows
432
+ * the mock to properly type-check parameters and return values to match
433
+ * the function signature being mocked.
432
434
  *
433
- * @returns A proxied mock object capable of behaving as a callable function or a constructible class.
435
+ * @param implementation - The initial function implementation to use. If not provided,
436
+ * the mock will return `undefined` when called.
437
+ * @param restore - Optional cleanup function that will be called when `mockRestore()` is invoked.
438
+ * Useful for restoring original behavior when mocking existing object methods.
439
+ * @param name - Optional name for the mock function, used in error messages and test output.
440
+ * Defaults to "xJet.fn()" if not provided.
434
441
  *
435
442
  * @remarks
436
- * The mock object can work as both a function and a class, using JavaScript's Proxy API. The restore functionality
437
- * allows resetting to the original state or implementation. If no implementation is provided, the mock remains uninitialized
438
- * but still functional.
443
+ * The constructor initializes the mock's state, implementation, and metadata.
444
+ * It returns a Proxy that allows the mock to be both a function and an object with properties.
445
+ *
446
+ * The Proxy intercepts:
447
+ * - Function calls (via `apply`)
448
+ * - Property access (via `get`)
449
+ * - Constructor calls with `new` (via `construct`)
439
450
  *
440
- * @see FunctionLikeType
441
- * @see VoidFunctionType
451
+ * This enables the mock to track calls, return configured values, and provide
452
+ * helper methods for assertions and configuration.
453
+ *
454
+ * @see ReturnType
455
+ * @see ImplementationType
442
456
  *
443
457
  * @since 1.0.0
444
458
  */
445
- constructor(implementation?: FunctionLikeType<ReturnType, Args, Context>, restore?: () => FunctionLikeType<ReturnType, Args, Context> | void, name?: string);
446
- /**
447
- * todo remove it
448
- * only for jest expect will support this mock
449
- */
450
- getMockName(): string;
459
+ constructor(implementation?: F, restore?: () => F | void, name?: string);
451
460
  /**
452
- * Retrieves the current state of the mock function.
461
+ * Gets a readonly snapshot of the current mocks state.
453
462
  *
454
- * @remarks
455
- * The `mock` getter provides read-only access to the complete state tracking information
456
- * for the mock function. This includes all recorded invocations, return values, contexts,
457
- * and other mock-related tracking data.
463
+ * @template F - The function type being mocked.
458
464
  *
459
- * Responsibilities:
460
- * - Providing access to recorded function calls via {@link MocksStateInterface.calls}
461
- * - Tracking invocation results through {@link MocksStateInterface.results}
462
- * - Maintaining context information in {@link MocksStateInterface.contexts}
463
- * - Recording instance creation in {@link MocksStateInterface.instances}
464
- * - Preserving invocation order via {@link MocksStateInterface.invocationCallOrder}
465
+ * @returns A frozen (immutable) copy of the mock state {@link MocksStateInterface}, containing information
466
+ * about calls, return values, and other tracking data.
465
467
  *
466
- * @returns A read-only view of the mock state tracking object.
468
+ * @remarks
469
+ * This property provides safe access to the mock's internal state for assertions and
470
+ * debugging purposes. The returned object is a deep copy with all properties frozen
471
+ * to prevent accidental modification of the mock's internal state.
467
472
  *
468
473
  * @see MocksStateInterface
474
+ *
469
475
  * @since 1.0.0
470
476
  */
471
- get mock(): Readonly<MocksStateInterface<ReturnType, Args, Context>>;
477
+ get mock(): Readonly<MocksStateInterface<F>>;
472
478
  /**
473
- * Returns the original implementation of the function that was instrumented
479
+ * Gets the original function implementation.
480
+ *
481
+ * @template F - The function type being mocked.
474
482
  *
475
- * @returns The original function implementation that was wrapped or modified
483
+ * @returns The original function implementation that was provided when creating the mock
484
+ * or a default implementation that returns undefined if none was provided.
476
485
  *
477
486
  * @remarks
478
- * This getter provides access to the unmodified function that was originally passed
479
- * to the instrumentation system. Useful for debugging, testing, or when you need
480
- * to bypass the instrumented behavior temporarily.
487
+ * This property allows access to the original implementation that was stored
488
+ * when the mock was created. It's useful when you need to temporarily access
489
+ * or call the original behavior within test cases.
481
490
  *
482
491
  * @example
483
492
  * ```ts
484
- * const mockFn = jest.fn(x => x * 2);
485
- * // Later in test
486
- * const originalImplementation = mockFn.original;
487
- * expect(originalImplementation(5)).toBe(10);
488
- * ```
493
+ * // Create a mock with an original implementation
494
+ * const originalFn = (x: number) => x * 2;
495
+ * const mockFn = xJet.fn(originalFn);
496
+ *
497
+ * // Override the implementation for some tests
498
+ * mockFn.mockImplementation((x: number) => x * 3);
489
499
  *
490
- * @see FunctionLikeType
500
+ * // Call the original implementation directly when needed
501
+ * const result = mockFn.original(5); // Returns 10, not 15
502
+ * ```
491
503
  *
492
504
  * @since 1.0.0
493
505
  */
494
- get original(): FunctionLikeType<ReturnType, Args, Context>;
506
+ get original(): F;
495
507
  /**
496
- * Clears the `mock.calls`, `mock.results`, `mock.contexts`, `mock.instances`, and `mock.invocationCallOrder` properties.
508
+ * Clears all information stored in the mock's state {@link MocksStateInterface}.
497
509
  *
498
- * @returns The current instance of the mock, allowing for method chaining.
510
+ * @returns The mock instance for method chaining.
499
511
  *
500
512
  * @remarks
501
- * This method resets the state of the mock function, clearing all invocation data and results,
502
- * ensuring that previous mock states do not affect the following tests.
503
- * Equivalent to calling `.mockClear()` on every mocked function.
513
+ * This method resets all stored information such as tracked calls, return values,
514
+ * and other state information. It doesn't reset any custom implementations that
515
+ * were set using mockImplementation or similar methods.
516
+ *
517
+ * @example
518
+ * ```ts
519
+ * const mockFn = xJet.fn();
520
+ * mockFn('first call');
521
+ * mockFn('second call');
504
522
  *
505
- * @see MockState.initState
523
+ * expect(mockFn.mock.calls.length).toBe(2);
506
524
  *
507
- * @since v1.0.0
525
+ * mockFn.mockClear();
526
+ *
527
+ * // All calls information has been cleared
528
+ * expect(mockFn.mock.calls.length).toBe(0);
529
+ * ```
530
+ *
531
+ * @since 1.0.0
508
532
  */
509
533
  mockClear(): this;
510
534
  /**
511
- * Resets the mock function to its initial state.
535
+ * Resets the mock by clearing all state and removing all queued implementations.
512
536
  *
513
- * @returns The current instance of the mock, allowing for method chaining.
537
+ * @returns The mock instance for method chaining.
514
538
  *
515
539
  * @remarks
516
- * The `mockReset` method clears all invocation data and results by calling `mockClear()` and also resets
517
- * the queued implementations,
518
- * removing any previously queued behavior set by methods like `mockImplementationOnce`.
519
- * This ensures that the mock is in a clean state and ready for new invocations or configurations.
540
+ * This method performs a more complete reset than mockClear() {@link mockClear}.
541
+ * It clears all stored information about calls and additionally removes any queued implementations that were
542
+ * set using mockImplementationOnce(). The default implementation will be restored.
520
543
  *
521
- * @see MockState.mockClear
544
+ * @example
545
+ * ```ts
546
+ * const mockFn = xJet.fn(() => 'default');
547
+ * mockFn.mockImplementationOnce(() => 'first call');
548
+ * mockFn.mockImplementationOnce(() => 'second call');
549
+ *
550
+ * console.log(mockFn()); // 'first call'
551
+ *
552
+ * mockFn.mockReset();
553
+ *
554
+ * // All calls have been cleared, and queued implementations removed
555
+ * console.log(mockFn()); // 'default'
556
+ * ```
522
557
  *
523
- * @since v1.0.0
558
+ * @see mockClear
559
+ * @since 1.0.0
524
560
  */
525
561
  mockReset(): this;
526
562
  /**
527
- * Restores the mock function to its original implementation and resets its state.
563
+ * Restores the original implementation of the mocked function.
528
564
  *
529
- * @returns The current instance of the mock, allowing for method chaining.
565
+ * @returns The mock instance for method chaining.
530
566
  *
531
567
  * @remarks
532
- * The `mockRestore` method does two things:
533
- * 1. It restores the mock to its initial implementation, which was set during the mocks creation or
534
- * via the `mockImplementation` method.
535
- * 2. It clears all tracking data, such as calls, results, contexts, instances, and invocation call order
536
- * by calling `mockReset()`, ensuring the mock is fully reset and ready for new invocations.
568
+ * This method performs the most complete reset operation. It first calls mockReset() {@link mockReset}
569
+ * to clear all state and queued implementations, then restores the original implementation
570
+ * provided when the mock was created. If a custom restore function was provided,
571
+ * it will be used instead to determine the implementation to restore.
572
+ *
573
+ * @example
574
+ * ```ts
575
+ * // Create a mock with an original implementation
576
+ * const originalFn = (x: number) => x * 2;
577
+ * const mockFn = xJet.fn(originalFn);
537
578
  *
538
- * This method is useful for ensuring that the mock is completely restored and cleared, making it behave as it did
539
- * when it was first created or last restored.
579
+ * // Override the implementation
580
+ * mockFn.mockImplementation((x: number) => x * 3);
540
581
  *
541
- * @see MockState.restore
542
- * @see MockState.mockReset
582
+ * console.log(mockFn(5)); // 15
543
583
  *
544
- * @since v1.0.0
584
+ * // Restore the original implementation
585
+ * mockFn.mockRestore();
586
+ *
587
+ * console.log(mockFn(5)); // 10
588
+ * ```
589
+ *
590
+ * @see mockClear
591
+ * @see mockReset
592
+ *
593
+ * @since 1.0.0
545
594
  */
546
595
  mockRestore(): this;
547
596
  /**
548
- * Retrieves the mock implementation for a function, if available.
597
+ * Returns the current implementation of the mock function.
549
598
  *
550
- * @template ReturnType The type the return value of the function.
551
- * @template Context The type of the `this` context for the function.
552
- * @template Args The type the argument(s) of the function.
553
- *
554
- * @return A function matching `FunctionLikeType` that represents the mock implementation,
555
- * or `undefined` if no implementation is set.
599
+ * @returns The current mock implementation, or undefined if no implementation exists.
556
600
  *
557
601
  * @remarks
558
- * This method returns the mock implementation associated with the instance.
559
- * If no mock implementation exists, it returns `undefined`.
602
+ * This method returns the current implementation function used by the mock.
603
+ * This could be the default implementation, a custom implementation set via
604
+ * mockImplementation() {@link mockImplementation}, or the original implementation
605
+ * if mockRestore() {@link mockRestore} was called.
606
+ *
607
+ * @example
608
+ * ```ts
609
+ * const mockFn = xJet.fn(() => 'default');
610
+ *
611
+ * // Get the default implementation
612
+ * const impl = mockFn.getMockImplementation();
613
+ * console.log(impl()); // 'default'
614
+ *
615
+ * // Change the implementation
616
+ * mockFn.mockImplementation(() => 'new implementation');
617
+ *
618
+ * // Get the new implementation
619
+ * const newImpl = mockFn.getMockImplementation();
620
+ * console.log(newImpl()); // 'new implementation'
621
+ * ```
560
622
  *
561
623
  * @since 1.0.0
562
624
  */
563
- getMockImplementation(): FunctionLikeType<ReturnType, Args, Context> | undefined;
625
+ getMockImplementation(): ImplementationType<F> | undefined;
564
626
  /**
565
- * Retrieves the next implementation from the queued implementations or defaults to the current implementation.
627
+ * Returns the next implementation to be used when the mock is called.
566
628
  *
567
- * @template ReturnType The return type of the function-like implementation.
568
- * @template Context The context in which the implementation executes.
569
- * @template Args The argument types expected by the implementation.
570
- *
571
- * @return The next implementation from the queue if available, or the current implementation.
572
- * Returns are `undefined` if no implementation is found.
629
+ * @returns The next implementation from the queue, or the default implementation if the queue is empty.
573
630
  *
574
631
  * @remarks
575
- * This method first checks if there are any queued implementations available.
576
- * If a queued implementation exists, it will be removed from the queue and returned.
577
- * If the queue is empty, the primary current implementation is returned.
578
- * Returns are `undefined` if there is no implementation available.
632
+ * This method retrieves and removes the next implementation from the queue of implementations
633
+ * added via mockImplementationOnce() {@link mockImplementationOnce}. If the queue is empty,
634
+ * it returns the default implementation set via mockImplementation() {@link mockImplementation}
635
+ * or the original function.
636
+ *
637
+ * @example
638
+ * ```ts
639
+ * const mockFn = xJet.fn(() => 'default');
640
+ * mockFn.mockImplementationOnce(() => 'first call');
641
+ * mockFn.mockImplementationOnce(() => 'second call');
642
+ *
643
+ * const firstImpl = mockFn.getNextImplementation();
644
+ * console.log(firstImpl()); // 'first call'
645
+ *
646
+ * const secondImpl = mockFn.getNextImplementation();
647
+ * console.log(secondImpl()); // 'second call'
648
+ *
649
+ * const defaultImpl = mockFn.getNextImplementation();
650
+ * console.log(defaultImpl()); // 'default'
651
+ * ```
579
652
  *
580
653
  * @since 1.0.0
581
654
  */
582
- getNextImplementation(): FunctionLikeType<ReturnType, Args, Context> | undefined;
655
+ getNextImplementation(): ImplementationType<F> | undefined;
583
656
  /**
584
- * Replaces the default implementation of a mock function with the provided function.
657
+ * Sets a new implementation for this mock function.
585
658
  *
586
- * @template ReturnType - The type of the value returned by the implementation function.
587
- * @template Context - The context (`this`) expected by the implementation function.
588
- * @template Args - The types of the arguments expected by the implementation function.
659
+ * @param fn - The function to be used as the mock implementation.
660
+ * @returns The mock instance for method chaining.
589
661
  *
590
- * @param fn - The function to be used as the mock implementation. It defines
591
- * the behavior of the mock when called.
662
+ * @remarks
663
+ * This method sets a persistent implementation that will be used whenever the mock function is called,
664
+ * unless there are queued implementations from mockImplementationOnce() {@link mockImplementationOnce}.
665
+ * The implementation remains until it is replaced by another call to mockImplementation() or restored
666
+ * via mockRestore() {@link mockRestore}.
592
667
  *
593
- * @return Returns the instance of the current object for method chaining.
668
+ * @example
669
+ * ```ts
670
+ * const mockFn = xJet.fn();
594
671
  *
595
- * @remarks
596
- * This method is useful when you need to mock the behavior of a function
597
- * dynamically during tests or in controlled scenarios.
672
+ * mockFn.mockImplementation((x: number) => x * 2);
673
+ *
674
+ * console.log(mockFn(5)); // 10
675
+ * console.log(mockFn(10)); // 20
676
+ *
677
+ * // Change the implementation
678
+ * mockFn.mockImplementation((x: number) => x * 3);
679
+ *
680
+ * console.log(mockFn(5)); // 15
681
+ * ```
682
+ *
683
+ * @see mockRestore
684
+ * @see mockImplementationOnce
598
685
  *
599
686
  * @since 1.0.0
600
687
  */
601
- mockImplementation(fn: FunctionLikeType<ReturnType, Args, Context>): this;
688
+ mockImplementation(fn: ImplementationType<F>): this;
602
689
  /**
603
- * Sets a mock implementation that will be used once for the next call to the mocked function.
690
+ * Adds a one-time implementation for this mock function.
604
691
  *
605
- * @template ReturnType The type of the value that the mock function will return.
606
- * @template Context The type of the `this` context for the mock function.
607
- * @template Args The type of arguments that the mock function will receive.
608
- *
609
- * @param fn - The function to be used as the mock implementation for the next call.
610
- * @returns The current instance, allowing for chaining of mock configurations.
692
+ * @param fn - The function to be used as the mock implementation for a single call.
693
+ * @returns The mock instance for method chaining.
611
694
  *
612
695
  * @remarks
613
- * The provided mock implementation will only be executed once. Further calls will fall back
614
- * to a different implementation, if provided, or the default behavior of the mock function.
696
+ * This method queues an implementation that will be used for a single call to the mock function.
697
+ * After being used once, it will be removed from the queue. Multiple implementations can be queued,
698
+ * and they will be used in the order they were added. Once all queued implementations are used,
699
+ * the mock will revert to using the implementation set by mockImplementation() {@link mockImplementation}.
615
700
  *
616
701
  * @example
617
702
  * ```ts
618
- * const mockFn = new MockState();
619
- *
620
- * // Set default implementation
621
- * mockFn.mockImplementation(() => 'default');
703
+ * const mockFn = xJet.fn(() => 'default');
622
704
  *
623
- * // Set one-time behavior for the next call
624
- * mockFn.mockImplementationOnce(() => 'first call');
705
+ * mockFn.mockImplementationOnce(() => 'first call')
706
+ * .mockImplementationOnce(() => 'second call');
625
707
  *
626
- * console.log(mockFn()); // Output: 'first call' (from mockImplementationOnce)
627
- * console.log(mockFn()); // Output: 'default' (from mockImplementation)
708
+ * console.log(mockFn()); // 'first call'
709
+ * console.log(mockFn()); // 'second call'
710
+ * console.log(mockFn()); // 'default'
628
711
  * ```
629
712
  *
630
- * @see FunctionLikeType
713
+ * @see mockReset
714
+ * @see mockImplementation
631
715
  *
632
716
  * @since 1.0.0
633
717
  */
634
- mockImplementationOnce(fn: FunctionLikeType<ReturnType, Args, Context>): this;
718
+ mockImplementationOnce(fn: ImplementationType<F>): this;
635
719
  /**
636
- * Sets a mock implementation to always return a specified value when invoked.
720
+ * Sets a fixed return value for this mock function.
637
721
  *
638
- * @template ReturnType The type of the value returned by the mock implementation.
639
- *
640
- * @param value - The value to always return when the mock function is called.
641
- * @return The current instance for chaining.
722
+ * @param value - The value to be returned when the mock function is called.
723
+ * @returns The mock instance for method chaining.
642
724
  *
643
725
  * @remarks
644
- * This method overrides any previous mock implementation configured for the function.
726
+ * This method is a convenience wrapper around mockImplementation() {@link mockImplementation}
727
+ * that creates an implementation which always returns the same value. It replaces any existing
728
+ * implementation with a function that simply returns the specified value.
645
729
  *
646
730
  * @example
647
731
  * ```ts
648
- * const mockFn = new MockState();
732
+ * const mockFn = xJet.fn();
733
+ *
734
+ * mockFn.mockReturnValue(42);
649
735
  *
650
- * // Set mock to return 'Hello World' on each call
651
- * mockFn.mockReturnValue('Hello World');
736
+ * console.log(mockFn()); // 42
737
+ * console.log(mockFn('anything')); // 42
738
+ * console.log(mockFn({}, [])); // 42
652
739
  *
653
- * console.log(mockFn()); // Output: 'Hello World'
654
- * console.log(mockFn()); // Output: 'Hello World'
740
+ * // Can be changed
741
+ * mockFn.mockReturnValue('new value');
742
+ * console.log(mockFn()); // 'new value'
655
743
  * ```
656
744
  *
745
+ * @see mockImplementation
746
+ * @see mockReturnValueOnce
747
+ *
657
748
  * @since 1.0.0
658
749
  */
659
- mockReturnValue(value: ReturnType): this;
750
+ mockReturnValue(value: ReturnType<F>): this;
660
751
  /**
661
- * Sets up a mock function to always resolve a promise with the specified value when called.
662
- *
663
- * @template ResolvedValueType - The type of the value to be resolved by the promise.
664
- * @template ReturnType - The return type of the function, which should include a Promise of the specified resolved value type.
752
+ * Adds a one-time fixed return value for this mock function.
665
753
  *
666
- * @param value - The value to be returned as the resolved value of the promise.
667
- * @returns The mock function instance, enabling method chaining.
754
+ * @param value - The value to be returned for a single call to the mock function.
755
+ * @returns The mock instance for method chaining.
668
756
  *
669
757
  * @remarks
670
- * This method is particularly useful for mocking asynchronous functions that return promises.
671
- * It ensures that the mock function resolves with the provided value every time it is called.
758
+ * This method is a convenience wrapper around mockImplementationOnce() {@link mockImplementationOnce}
759
+ * that creates a one-time implementation which returns the specified value. Multiple return values
760
+ * can be queued, and they will be used in the order they were added. After all queued values are
761
+ * consumed, the mock will revert to its default implementation.
672
762
  *
673
763
  * @example
674
764
  * ```ts
675
- * const mockFn = new MockState<Promise<string>>();
765
+ * const mockFn = xJet.fn(() => 'default');
676
766
  *
677
- * // Set mock to return a resolved promise with the value 'Success'
678
- * mockFn.mockResolvedValue('Success');
767
+ * mockFn.mockReturnValueOnce(42)
768
+ * .mockReturnValueOnce('string value')
769
+ * .mockReturnValueOnce({ object: true });
679
770
  *
680
- * mockFn().then((result: string) => {
681
- * console.log(result); // Output: 'Success'
682
- * });
771
+ * console.log(mockFn()); // 42
772
+ * console.log(mockFn()); // 'string value'
773
+ * console.log(mockFn()); // { object: true }
774
+ * console.log(mockFn()); // 'default'
683
775
  * ```
684
776
  *
777
+ * @see mockReturnValue
778
+ * @see mockImplementationOnce
779
+ *
685
780
  * @since 1.0.0
686
781
  */
687
- mockResolvedValue(value: ResolvedValueType<ReturnType>): this;
782
+ mockReturnValueOnce(value: ReturnType<F>): this;
688
783
  /**
689
- * Sets a mock implementation for a single call that resolves to the specified value.
690
- *
691
- * @template ReturnType The type of the resolved value.
692
- * @template ResolvedValueType The type of the input value to be resolved.
784
+ * Sets a resolved Promise return value for this mock function.
693
785
  *
694
- * @param value - The value that the promise should resolve with when the mock is called once.
695
- * @return The current mock object instance, enabling method chaining.
786
+ * @param value - The value that the Promise will resolve to.
787
+ * @returns The mock instance for method chaining.
696
788
  *
697
789
  * @remarks
698
- * This method is useful for defining custom behavior for a specific invocation of a mocked function,
699
- * returning a resolved promise with the provided value.
790
+ * This method is a convenience wrapper that creates an implementation which returns a
791
+ * Promise that resolves to the specified value. It's particularly useful for testing
792
+ * async functions that should return resolved Promises.
700
793
  *
701
794
  * @example
702
795
  * ```ts
703
- * const mockFn = new MockState(async () => {
704
- * return 'end';
705
- * });
796
+ * const mockFn = xJet.fn();
706
797
  *
707
- * // Set mock to return a resolved promise with the value 'Success'
708
- * mockFn.mockResolvedValueOnce('Success');
798
+ * mockFn.mockResolvedValue('resolved value');
709
799
  *
710
- * mockFn().then((result: string) => {
711
- * console.log(result); // Output: 'Success'
800
+ * // The mock now returns a Promise that resolves to 'resolved value'
801
+ * mockFn().then(result => {
802
+ * console.log(result); // 'resolved value'
712
803
  * });
713
804
  *
714
- * mockFn().then((result: string) => {
715
- * console.log(result); // Output: 'end'
716
- * });
805
+ * // Can also be used with async/await
806
+ * const result = await mockFn();
807
+ * console.log(result); // 'resolved value'
717
808
  * ```
718
809
  *
810
+ * @see mockRejectedValue
811
+ * @see mockImplementation
812
+ * @see mockResolvedValueOnce
813
+ *
719
814
  * @since 1.0.0
720
815
  */
721
- mockResolvedValueOnce(value: ResolvedValueType<ReturnType>): this;
816
+ mockResolvedValue(value: ResolvedValueType<ReturnType<F>>): this;
722
817
  /**
723
- * Sets the return value of the mock function for a single call.
818
+ * Adds a one-time resolved Promise return value for this mock function.
724
819
  *
725
- * @template ReturnType The type of the value to be returned.
726
- *
727
- * @param value - The value to be returned by the mock function for the next call.
728
- * @return The mock function instance, allowing for method chaining.
820
+ * @param value - The value that the Promise will resolve to for a single call.
821
+ * @returns The mock instance for method chaining.
729
822
  *
730
823
  * @remarks
731
- * This method only affects the return value for the next call to the mock function.
732
- * All further calls will use the usual mock implementation or other specified behaviors.
824
+ * This method is a convenience wrapper that creates a one-time implementation which returns
825
+ * a Promise that resolves to the specified value. Multiple resolved values can be queued and
826
+ * will be used in the order they were added. After all queued values are consumed, the mock
827
+ * will revert to its default implementation.
733
828
  *
734
829
  * @example
735
830
  * ```ts
736
- * const mockFn = new MockState();
737
- *
738
- * // Set default return value
739
- * mockFn.mockReturnValue('Default Value');
831
+ * const mockFn = xJet.fn(() => Promise.resolve('default'));
740
832
  *
741
- * // Set a one-time return value for the next call
742
- * mockFn.mockReturnValueOnce('First Call');
743
- * mockFn.mockReturnValueOnce('Second Call');
833
+ * mockFn.mockResolvedValueOnce('first call')
834
+ * .mockResolvedValueOnce('second call')
835
+ * .mockResolvedValueOnce('third call');
744
836
  *
745
- * console.log(mockFn()); // Output: 'First Call' (from mockReturnValueOnce)
746
- * console.log(mockFn()); // Output: 'Second Call' (from mockReturnValueOnce)
747
- * console.log(mockFn()); // Output: 'Default Value' (from mockReturnValue)
837
+ * // Each call returns a different Promise
838
+ * await expect(mockFn()).resolves.toEqual('first call');
839
+ * await expect(mockFn()).resolves.toEqual('second call');
840
+ * await expect(mockFn()).resolves.toEqual('third call');
841
+ * await expect(mockFn()).resolves.toEqual('default');
748
842
  * ```
749
843
  *
844
+ * @see mockResolvedValue
845
+ * @see mockRejectedValueOnce
846
+ * @see mockImplementationOnce
847
+ *
750
848
  * @since 1.0.0
751
849
  */
752
- mockReturnValueOnce(value: ReturnType): this;
850
+ mockResolvedValueOnce(value: ResolvedValueType<ReturnType<F>>): this;
753
851
  /**
754
- * Mocks the method to always return a rejected Promise with the specified value.
755
- *
756
- * @template ReturnType - The expected type of the return value for the mocked method.
757
- * @template RejectedValueType - The type of the value used to reject the Promise.
758
- *
759
- * @param value - The value with which the mocked Promise will be rejected.
852
+ * Sets a rejected Promise return value for this mock function.
760
853
  *
761
- * @return The current instance of the mock for chaining purposes.
854
+ * @param value - The error that the Promise will reject with.
855
+ * @returns The mock instance for method chaining.
762
856
  *
763
857
  * @remarks
764
- * This method is useful for testing scenarios where the function being mocked
765
- * is expected to reject with a specific value.
858
+ * This method is a convenience wrapper that creates an implementation which returns a
859
+ * Promise that rejects with the specified value. It's particularly useful for testing
860
+ * error handling in async functions.
766
861
  *
767
862
  * @example
768
863
  * ```ts
769
- * const mockFn = new MockState<Promise<string>>();
864
+ * const mockFn = xJet.fn();
770
865
  *
771
- * // Set mock to return a rejected promise with the value 'Error'
772
- * mockFn.mockRejectedValue('Error');
866
+ * mockFn.mockRejectedValue(new Error('Something went wrong'));
773
867
  *
868
+ * // The mock now returns a Promise that rejects with the error
774
869
  * mockFn().catch(error => {
775
- * console.log(error); // Output: 'Error'
870
+ * console.error(error.message); // 'Something went wrong'
776
871
  * });
872
+ *
873
+ * // Can also be used with async/await and try/catch
874
+ * try {
875
+ * await mockFn();
876
+ * } catch (error) {
877
+ * console.error(error.message); // 'Something went wrong'
878
+ * }
777
879
  * ```
778
880
  *
881
+ * @see mockResolvedValue
882
+ * @see mockImplementation
883
+ * @see mockRejectedValueOnce
884
+ *
779
885
  * @since 1.0.0
780
886
  */
781
- mockRejectedValue(value: RejectedValueType<ReturnType>): this;
887
+ mockRejectedValue(value: RejectedValueType<ReturnType<F>>): this;
782
888
  /**
783
- * Adds a one-time rejection with the provided value to the mock function.
784
- *
785
- * @template ReturnType - The type of the value the mock function would return.
889
+ * Adds a one-time rejected Promise return value for this mock function.
786
890
  *
787
- * @param value - The value to reject the promise with in the mock function.
788
- * @return The current instance of the mock function, allowing for method chaining.
891
+ * @param value - The error that the Promise will reject with for a single call.
892
+ * @returns The mock instance for method chaining.
789
893
  *
790
894
  * @remarks
791
- * This method configures a mock function to return a rejected promise with the
792
- * specified value the next time it is called. After the rejection occurs, the
793
- * mock function's behavior will revert to the next defined mock behavior, or
794
- * to the default behavior if no behaviors are defined.
895
+ * This method is a convenience wrapper that creates a one-time implementation which returns
896
+ * a Promise that rejects with the specified value. Multiple rejected values can be queued and
897
+ * will be used in the order they were added. After all queued values are consumed, the mock
898
+ * will revert to its default implementation.
795
899
  *
796
900
  * @example
797
901
  * ```ts
798
- * const mockFn = new MockState<Promise<string>>();
902
+ * const mockFn = xJet.fn(() => Promise.resolve('success'));
799
903
  *
800
- * // Set default rejected value
801
- * mockFn.mockRejectedValue('Default Error');
904
+ * mockFn.mockRejectedValueOnce(new Error('first error'))
905
+ * .mockRejectedValueOnce(new Error('second error'));
802
906
  *
803
- * // Set a one-time rejected value for the next call
804
- * mockFn.mockRejectedValueOnce('First Call Error');
907
+ * // First call rejects with 'first error'
908
+ * await expect(mockFn()).rejects.toThrow('first error');
805
909
  *
806
- * mockFn().catch(error => {
807
- * console.log(error); // Output: 'First Call Error' (from mockRejectedValueOnce)
808
- * });
910
+ * // Second call rejects with 'second error'
911
+ * await expect(mockFn()).rejects.toThrow('second error');
809
912
  *
810
- * mockFn().catch(error => {
811
- * console.log(error); // Output: 'Default Error' (from mockRejectedValue)
812
- * });
913
+ * // Third call uses the default implementation and resolves
914
+ * await expect(mockFn()).resolves.toEqual('success');
813
915
  * ```
814
916
  *
917
+ * @see mockRejectedValue
918
+ * @see mockResolvedValueOnce
919
+ * @see mockImplementationOnce
920
+ *
815
921
  * @since 1.0.0
816
922
  */
817
- mockRejectedValueOnce(value: RejectedValueType<ReturnType>): this;
923
+ mockRejectedValueOnce(value: RejectedValueType<ReturnType<F>>): this;
818
924
  /**
819
- * Initializes and returns the state object for mock function tracking.
925
+ * Initializes the internal state object for the mock function.
820
926
  *
821
- * @return An object containing the initialized mock function state.
927
+ * @returns A new mock state object with default empty values.
822
928
  *
823
929
  * @remarks
824
- * The state object contains the structure necessary to keep track of
825
- * calls, results, contexts, instances, and invocation orders of the function.
930
+ * This private method creates and returns a fresh state object used to track
931
+ * mock function invocations. The state includes:
932
+ * - calls: Arguments passed to the mock function
933
+ * - results: Return values or errors from each call
934
+ * - lastCall: Arguments from the most recent call
935
+ * - contexts: 'this' context values for each call
936
+ * - instances: Objects created when the mock is used as a constructor
937
+ * - invocationCallOrder: Tracking the sequence of calls across multiple mocks
826
938
  *
827
- * @see MocksStateInterface
939
+ * This method is used internally when creating a new mock or when resetting
940
+ * an existing mocks state.
828
941
  *
829
- * @since v1.0.0
942
+ * @since 1.0.0
830
943
  */
831
944
  private initState;
832
945
  /**
833
- * Invokes the next implementation of a mock function with the provided context and arguments.
834
- *
835
- * @template Context The type of `this` context in which the function is invoked.
836
- * @template Args The type of the arguments passed to the function.
837
- * @template ReturnType The type of the return value, of the function being invoked.
946
+ * Invokes the mock function with the provided arguments and context.
838
947
  *
839
- * @param thisArg - The context (`this`) in which the function is executed.
840
- * @param args - The arguments to be passed to the function.
841
- *
842
- * @returns The result of the function invocation, which is either the return value, the thrown error, or undefined.
948
+ * @param thisArg - The 'this' context for the function call
949
+ * @param args - The arguments to pass to the function
950
+ * @returns The result of the mock implementation or undefined
843
951
  *
844
952
  * @remarks
845
- * This method simulates the function call for a mocked implementation. It tracks all invocations,
846
- * including the call order, the provided arguments, and the context. It handles binding, default
847
- * arguments, and maintains a record of results (either successful returns or thrown errors).
953
+ * This private method handles the actual invocation of the mock function and manages all
954
+ * state trackings.
955
+ *
956
+ * This method is central to the mock's functionality, enabling call tracking,
957
+ * result recording, and the execution of custom implementations.
848
958
  *
849
959
  * @since 1.0.0
850
960
  */
851
961
  private invoke;
852
962
  /**
853
- * Invokes a function within a specific context and with provided arguments.
854
- *
855
- * @template Context The type of the context in which the function is invoked.
856
- * @template Args The type of the arguments passed to the function.
857
- * @template ReturnType The type of the value that the invoked function returns.
963
+ * Handles property access for the mock function proxy.
858
964
  *
859
- * @param target - The instance of the class containing the method to be invoked.
860
- * @param thisArg - The context object that will be bound to the invoked function.
861
- * @param argumentsList - The list of arguments to pass to the invoked function.
862
- * @returns The result of the invoked function or `undefined` if no value is returned.
965
+ * @param target - The mock function instance
966
+ * @param property - The property name or symbol being accessed
967
+ * @returns The property value from either the mock or the original implementation
863
968
  *
864
969
  * @remarks
865
- * This method modifies the state of the `target` instance by adding the `thisArg`
866
- * to the `target.state.instances` array before invoking the function.
970
+ * This private method is used as the 'get' trap for the Proxy surrounding the mock function.
971
+ * It provides property access fallback behavior - first checking if the property exists
972
+ * on the mock itself, and if not, retrieving it from the original implementation.
973
+ *
974
+ * This enables the mock to maintain its own properties while still allowing access to
975
+ * properties from the original function, providing a more transparent mocking experience.
867
976
  *
868
977
  * @since 1.0.0
869
978
  */
870
- private invokeFunction;
979
+ private invokeGet;
871
980
  /**
872
- * Invokes a class method on the provided target with specified arguments and a new target.
873
- *
874
- * @template Args - The type of arguments to be passed to the invoked method.
981
+ * Handles constructor invocation when the mock is used with 'new'.
875
982
  *
876
- * @param target - The object on which the class method is invoked.
877
- * @param argArray - The array of arguments to pass to the invoked method.
878
- * @param newTarget - The new object used as the invocation context.
879
- * @returns The result of the invocation, typically an object. If the result is not an object,
880
- * the `newTarget` is returned instead.
983
+ * @param target - The mock function instance
984
+ * @param argArray - The arguments passed to the constructor
985
+ * @param newTarget - The constructor that was directly invoked
986
+ * @returns The constructed instance
881
987
  *
882
988
  * @remarks
883
- * This method ensures that the result is stored in the `instances` array of the target's state
884
- * if it is detected as a proper class instance. Otherwise, the `newTarget` is registered.
989
+ * This method is used as the 'construct' trap for the Proxy surrounding the mock function.
990
+ * It delegates to the `invoke` method to handle the actual function call, then tracks the
991
+ * resulting instance in the mock's state for later verification.
992
+ *
993
+ * The method handles both cases where the constructor returns an object (which becomes the
994
+ * instance) and where it doesn't (in which case the newTarget becomes the instance).
885
995
  *
886
996
  * @since 1.0.0
887
997
  */
888
998
  private invokeClass;
999
+ /**
1000
+ * Handles function invocation when the mock is called.
1001
+ *
1002
+ * @param target - The mock function instance
1003
+ * @param thisArg - The 'this' context for the function call
1004
+ * @param argumentsList - The arguments passed to the function
1005
+ * @returns The result of the function invocation
1006
+ *
1007
+ * @remarks
1008
+ * This method is used as the 'apply' trap for the Proxy surrounding the mock function.
1009
+ * It captures the calling context in the mock's state for later verification, then
1010
+ * delegates to the `invoke` method to handle the actual function call logic.
1011
+ *
1012
+ * This method is called whenever the mock function is invoked as a regular function
1013
+ * (not as a constructor).
1014
+ *
1015
+ * @since 1.0.0
1016
+ */
1017
+ private invokeFunction;
889
1018
  }
890
1019
 
891
1020
  /**
@@ -908,6 +1037,9 @@ interface BoundInterface<Context = unknown | null | undefined, Args = Array<unkn
908
1037
  __boundArgs?: Args;
909
1038
  }
910
1039
 
1040
+ /**
1041
+ * Import will remove at compile time
1042
+ */
911
1043
  /**
912
1044
  * Represents the possible result types of a mock function invocation.
913
1045
  *
@@ -967,35 +1099,35 @@ interface MockInvocationResultInterface<T> {
967
1099
  *
968
1100
  * @since 1.0.0
969
1101
  */
970
- interface MocksStateInterface<ReturnType, Args extends Array<unknown> = [], Context = unknown> {
1102
+ interface MocksStateInterface<F extends FunctionType> {
971
1103
  /**
972
1104
  * An array that holds the arguments for each invocation made to the mock.
973
1105
  * Each entry corresponds to the arguments passed during a single call to the mock function.
974
1106
  *
975
1107
  * @since 1.0.0
976
1108
  */
977
- calls: Array<Args>;
1109
+ calls: Array<Parameters<F>>;
978
1110
  /**
979
1111
  * The arguments passed to the mock during its most recent invocation.
980
1112
  * Returns `undefined` if the mock has not been called yet.
981
1113
  *
982
1114
  * @since 1.0.0
983
1115
  */
984
- lastCall?: Args;
1116
+ lastCall?: Parameters<F>;
985
1117
  /**
986
1118
  * An array of contexts (`this` values) for each invocation made to the mock.
987
1119
  * Each entry corresponds to the context in which the mock was called.
988
1120
  *
989
1121
  * @since 1.0.0
990
1122
  */
991
- contexts: Array<Context>;
1123
+ contexts: Array<ThisParameterType<F>>;
992
1124
  /**
993
1125
  * An array of all object instances created by the mock.
994
1126
  * Each entry represents an instance was instantiated during the mocks invocations.
995
1127
  *
996
1128
  * @since 1.0.0
997
1129
  */
998
- instances: Array<Context>;
1130
+ instances: Array<ThisParameterType<F>>;
999
1131
  /**
1000
1132
  * An array of invocation order indices for the mock.
1001
1133
  * xJet assigns an index to each call, starting from 1, to track the order in which mocks are invoked within a test file.
@@ -1009,8 +1141,39 @@ interface MocksStateInterface<ReturnType, Args extends Array<unknown> = [], Cont
1009
1141
  *
1010
1142
  * @since 1.0.0
1011
1143
  */
1012
- results: Array<MockInvocationResultInterface<ReturnType>>;
1144
+ results: Array<MockInvocationResultInterface<ReturnType<F>>>;
1013
1145
  }
1146
+ /**
1147
+ * A utility type that extracts the signature of a function and allows it to be reused in an implementation.
1148
+ *
1149
+ * @remarks
1150
+ * This type creates a representation of a function's signature based on its return type, parameters, and
1151
+ * `this` context. It's particularly useful for creating mock implementations, decorators, or wrappers
1152
+ * that need to maintain the same signature as the original function.
1153
+ *
1154
+ * By using this type, you can ensure type safety when implementing functions that need to match
1155
+ * an existing function's signature exactly, including its return type, parameter types, and `this` binding.
1156
+ *
1157
+ * @typeParam F - The original function type to extract the signature from
1158
+ *
1159
+ * @example
1160
+ * ```ts
1161
+ * // Original function
1162
+ * function greet(name: string): string {
1163
+ * return `Hello, ${name}!`;
1164
+ * }
1165
+ *
1166
+ * // Implementation with the same signature
1167
+ * const mockGreet: ImplementationType<typeof greet> = function(name) {
1168
+ * return `Mocked greeting for ${name}`;
1169
+ * };
1170
+ *
1171
+ * // Both functions now have the exact same type signature
1172
+ * ```
1173
+ *
1174
+ * @since 1.2.2
1175
+ */
1176
+ type ImplementationType<F extends FunctionType> = FunctionLikeType<ReturnType<F>, Parameters<F>, ThisParameterType<F>>;
1014
1177
 
1015
1178
  /**
1016
1179
  * A base error class that extends the standard Error class with enhanced JSON serialization and location tracking
@@ -1091,16 +1254,134 @@ declare class ExecutionError extends Error {
1091
1254
  toJSON(): Record<string, unknown>;
1092
1255
  }
1093
1256
 
1257
+ /**
1258
+ * Import will remove at compile time
1259
+ */
1260
+ /**
1261
+ * Recursively searches for a specific element within an object or its nested properties.
1262
+ *
1263
+ * @param target - The object to search within.
1264
+ * @param element - The value to find within the target object or its nested properties.
1265
+ * @param key - Optional specific key to search for within the target object.
1266
+ * @param maxDepth - Maximum recursion depth to prevent infinite loops, defaults to 3.
1267
+ * @returns A {@link DeepSearchInterface} object containing parent and key if found, or null if not found.
1268
+ *
1269
+ * @remarks
1270
+ * This utility performs a depth-first search through an object's properties to locate a specific value
1271
+ * or a property with a specific key. It maintains a set of visited objects to prevent circular reference issues.
1272
+ *
1273
+ * The search process:
1274
+ * - Tracks visited objects to avoid circular references
1275
+ * - Searches by exact reference equality for the element
1276
+ * - Handles errors during property access
1277
+ * - Limits search depth to prevent stack overflow
1278
+ * - Can find elements by exact key name (when the `key` parameter is provided)
1279
+ *
1280
+ * @example
1281
+ * ```ts
1282
+ * const obj = {
1283
+ * a: 1,
1284
+ * b: {
1285
+ * c: 'test',
1286
+ * d: [1, 2, { e: 'target' }]
1287
+ * }
1288
+ * };
1289
+ *
1290
+ * // Find by value
1291
+ * const result = deepSearchObject(obj, 'target');
1292
+ * // result: { parent: { e: 'target' }, key: 'e' }
1293
+ *
1294
+ * // Find by key name
1295
+ * const byKey = deepSearchObject(obj, null, 'c');
1296
+ * // byKey: { parent: { c: 'test', d: [...] }, key: 'c' }
1297
+ * ```
1298
+ *
1299
+ * @see DeepSearchInterface
1300
+ * @since 1.0.0
1301
+ */
1302
+ declare function deepSearchObject(target: Record<string | symbol, unknown>, element: unknown, key?: string, maxDepth?: number): DeepSearchInterface | null;
1303
+ /**
1304
+ * Resolves property references that may be affected by ESBuild's `__toESM` transformation.
1305
+ *
1306
+ * @remarks
1307
+ * This function handles a specific issue with ESBuild's module transformation where Node.js
1308
+ * built-in modules (like 'fs', 'http', etc.) are wrapped with getter descriptors that aren't
1309
+ * configurable. This causes problems when trying to mock or modify these modules in testing.
1310
+ *
1311
+ * When ESBuild transforms CommonJS modules to ESM, it creates non-configurable getter properties
1312
+ * on the module object. This function detects such cases and returns a reference to the original
1313
+ * underlying object instead, making the property accessible for mocking or modification.
1314
+ *
1315
+ * @param parent - The object containing the property to resolve
1316
+ * @param key - The property name or symbol to resolve
1317
+ * @returns A {@link DeepSearchInterface} pointing to either the original object or the
1318
+ * underlying object in case of non-configurable ESBuild transformations
1319
+ *
1320
+ * @example
1321
+ * ```ts
1322
+ * // When working with an ESBuild transformed fs module
1323
+ * import * as fs from 'fs';
1324
+ *
1325
+ * // Normal access would use a non-configurable getter
1326
+ * // Making it impossible to mock
1327
+ * const originalRef = { parent: fs, key: 'readFileSync' };
1328
+ *
1329
+ * // This function resolves to the underlying object
1330
+ * const mockableRef = getOwnProperty(fs, 'readFileSync');
1331
+ * // Now we can mock it: mockableRef.parent[mockableRef.key] = mockFn;
1332
+ * ```
1333
+ *
1334
+ * @since 1.2.2
1335
+ */
1336
+ declare function getOwnProperty(parent: Record<string | symbol, unknown>, key: string | symbol): DeepSearchInterface;
1337
+
1338
+ /**
1339
+ * Interface representing the result of a deep object search operation.
1340
+ *
1341
+ * @remarks
1342
+ * This interface provides a structured way to return the results of an object traversal
1343
+ * search, containing both the parent object and the specific key where a target value was found.
1344
+ * It allows callers to not only determine if a value was found, but also access its
1345
+ * containing object and property name.
1346
+ *
1347
+ * The interface is typically used in deep search algorithms that need to return both
1348
+ * the location of a found item and provide access to its context.
1349
+ *
1350
+ * @example
1351
+ * ```ts
1352
+ * // Example result from a search operation
1353
+ * const result: DeepSearchInterface = {
1354
+ * parent: { id: 123, name: 'example' },
1355
+ * key: 'name'
1356
+ * };
1357
+ *
1358
+ * // Accessing the found value through the result
1359
+ * const foundValue = result.parent[result.key]; // 'example'
1360
+ * ```
1361
+ *
1362
+ * @since 1.2.2
1363
+ */
1364
+ interface DeepSearchInterface {
1365
+ /**
1366
+ * The property key (name) where the searched element was found.
1367
+ *
1368
+ * @since 1.2.2
1369
+ */
1370
+ key: string | symbol;
1371
+ /**
1372
+ * The parent object containing the found element.
1373
+ *
1374
+ * @since 1.2.2
1375
+ */
1376
+ parent: Record<string | symbol, unknown>;
1377
+ }
1378
+
1094
1379
  /**
1095
1380
  * Import will remove at compile time
1096
1381
  */
1097
1382
  /**
1098
1383
  * Imports
1099
1384
  */
1100
- declare const proxyRegistry: WeakMap<object, {
1101
- proxy: unknown;
1102
- spies: Map<PropertyKey, MockState>;
1103
- }>;
1104
1385
  /**
1105
1386
  * Checks if a property on an object is provided via a proxy mechanism rather than directly defined.
1106
1387
  *
@@ -1142,269 +1423,196 @@ declare const proxyRegistry: WeakMap<object, {
1142
1423
  */
1143
1424
  declare function isProxyProperty<T extends object>(obj: T, key: keyof T): boolean;
1144
1425
  /**
1145
- * Creates a spy on a property accessed via a proxy getter, allowing interception
1146
- * and monitoring of property access operations.
1426
+ * Determines if a value is a mock proxy created by the mocking system.
1147
1427
  *
1148
- * @template T - The type of the target object containing the proxy
1149
- * @template K - The type of property key being spied on
1428
+ * @param value - The value to check
1429
+ * @returns `true` if the value is a mock proxy, `false` otherwise
1150
1430
  *
1151
- * @param target - The object containing the property to spy on
1152
- * @param key - The property key to intercept access to
1153
- * @param method - The method to execute when the property is accessed
1154
- * @returns A {@link MockState} instance that tracks interactions with the property
1431
+ * @remarks
1432
+ * This function checks if an object has the internal `__isMockProxy__` symbol property
1433
+ * which is added to all mock proxy objects created by the mocking framework.
1155
1434
  *
1156
- * @throws Error - If the target is not part of any global object
1435
+ * Mock proxies are specialized proxy objects that intercept property access
1436
+ * and method calls while providing mocking capabilities.
1157
1437
  *
1158
1438
  * @example
1159
1439
  * ```ts
1160
- * // Create an object with dynamic property access
1161
- * const user = new Proxy({}, {
1162
- * get(target, prop) {
1163
- * if (prop === 'name') return 'John';
1164
- * return target[prop];
1165
- * }
1166
- * });
1440
+ * const regularObject = { name: 'Test' };
1441
+ * const mockObject = createMock({ name: 'Test' });
1167
1442
  *
1168
- * // Spy on the 'name' property
1169
- * const nameSpy = spyOnProxyGet(user, 'name', () => 'Jane');
1170
- *
1171
- * // Now accessing user.name returns 'Jane' and the access is tracked
1172
- * console.log(user.name); // 'Jane'
1173
- * expect(nameSpy).toHaveBeenCalled();
1174
- *
1175
- * // Restore original behavior
1176
- * nameSpy.mockRestore();
1177
- * console.log(user.name); // 'John'
1443
+ * isMockProxy(regularObject); // false
1444
+ * isMockProxy(mockObject); // true
1178
1445
  * ```
1179
1446
  *
1180
- * @see MockState
1181
- * @see getParentObject
1182
- *
1183
- * @since 1.2.0
1447
+ * @since 1.2.2
1184
1448
  */
1185
- declare function spyOnProxyGet<T extends object, K extends keyof T>(target: T, key: K, method: unknown): MockState;
1449
+ declare function isMockProxy(value: Record<symbol, unknown>): boolean;
1186
1450
  /**
1187
- * Creates a spy on a specified static method or static property of a target class (not a class instance).
1188
- * Useful for mocking behavior during testing.
1451
+ * Creates a mock proxy that intercepts property access on an object.
1189
1452
  *
1190
- * @template Target - The type of the target class.
1191
- * @template Key - The static method or static property key on the target object to spy on.
1453
+ * @template T - The type of the target object being proxied
1454
+ * @param target - The object to be proxied
1455
+ * @returns A MockProxyInterface that intercepts property access on the target
1192
1456
  *
1193
- * @param target - The object on which to spy.
1194
- * @param key - The key of the method or property of the target to spy on.
1195
- * @returns If the spied-on property is a function, returns a `MockState` object for the function,
1196
- * allowing tracking of calls and modifying the return value or behavior.
1197
- * Otherwise, returns a `MockState` object for the property, enabling tracking and manipulation of its value.
1457
+ * @remarks
1458
+ * This function creates a proxy around an object that allows for interception
1459
+ * and customization of property access. The proxy maintains an internal state
1460
+ * that tracks mocked properties and provides mechanisms for customizing getter behavior.
1198
1461
  *
1199
- * @throws Error Throws an error if the `target` is a primitive value.
1200
- * @throws Error Throws an error if `key` is null or undefined.
1201
- * @throws Error Throws an error if the specified property does not exist on the target object.
1462
+ * The proxy implements special properties:
1463
+ * - `__isMockProxy__`: Used to identify mock proxy objects
1464
+ * - `__MockMap__`: Provides access to the internal state for managing mocks
1202
1465
  *
1203
- * @remarks
1204
- * This function is commonly used in testing environments to replace or monitor functionality without
1205
- * altering the actual logic in the source code. It provides fine-grained control over target behavior.
1466
+ * Property access behavior:
1467
+ * 1. First checks if a custom getter is defined and uses it if available
1468
+ * 2. Then checks if the property has a specific mock implementation
1469
+ * 3. Falls back to the original property on the target object
1206
1470
  *
1207
1471
  * @example
1208
1472
  * ```ts
1209
- * class ClassTest {
1210
- * static name: string = 'ClassTest';
1473
+ * const user = { name: 'John', getAge: () => 30 };
1474
+ * const mockUser = createMockProxy(user);
1211
1475
  *
1212
- * static x(param: string) {
1213
- * console.log(`original static x ${ param }`);
1214
- * }
1215
- * }
1476
+ * // Access original property
1477
+ * console.log(mockUser.name); // "John"
1216
1478
  *
1217
- * const spy1 = xJet.spyOn(ClassTest, 'name');
1218
- * const spy2 = xJet.spyOn(ClassTest, 'x');
1479
+ * // Add a mock for a property
1480
+ * const mockMap = mockUser.__MockMap__;
1481
+ * mockMap.mocks.set('getAge', () => 25);
1219
1482
  *
1220
- * spy1.mockReturnValueOnce('Mock name');
1221
- * spy2.mockImplementationOnce((param: string) => {
1222
- * console.log(`Mock x ${ param }`);
1223
- * });
1224
- *
1225
- * console.log(ClassTest.name); // Mock name
1226
- * console.log(ClassTest.name); // ClassTest
1227
- *
1228
- * ClassTest.x('test1'); // Mock x test1
1229
- * ClassTest.x('test2'); // original static x test2
1483
+ * // Now returns the mock implementation
1484
+ * console.log(mockUser.getAge()); // 25
1230
1485
  * ```
1231
1486
  *
1232
- * @see FunctionType
1233
- * @see KeysExtendingConstructorType
1234
- *
1235
- * @since 1.0.0
1487
+ * @since 1.2.2
1236
1488
  */
1237
- 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>;
1489
+ declare function createMockProxy<T extends object>(target: T): MockProxyInterface;
1238
1490
  /**
1239
- * Creates a mock spy on the specified method or constructor of the target object.
1491
+ * Creates a spy on a property access for a proxied object.
1240
1492
  *
1241
- * @template Target The type of the target object.
1242
- * @template Key The type of the method or constructor key on the target object.
1493
+ * @template T - The type of the target object
1494
+ * @template K - The key of the property to spy on
1243
1495
  *
1244
- * @param target - The object whose method or constructor needs to be spied on.
1245
- * @param key - The property key of the method or constructor to spy on.
1246
- * @return A mock state representing the spied method or constructor if the key corresponds to a constructor type;
1247
- * otherwise, throws a type error.
1248
- *
1249
- * @throws Error Throws an error if the `target` is a primitive value.
1250
- * @throws Error Throws an error if `key` is null or undefined.
1251
- * @throws Error Throws an error if the specified property does not exist on the target object.
1496
+ * @param target - The proxy object containing the property to spy on
1497
+ * @param prop - The name of the property to spy on
1498
+ * @returns A MockState object wrapping the property access
1252
1499
  *
1253
1500
  * @remarks
1254
- * This method is typically used for testing purposes to observe or manipulate calls to the method or constructor of an object.
1255
- * The returned mock state may allow additional configuration, such as altering its behavior or tracking calls.
1501
+ * This specialized spy function is designed to work with properties accessed through proxy objects.
1502
+ * It handles the complexities of intercepting property access in proxied objects by:
1503
+ *
1504
+ * 1. Locating the proxy object in the global scope if needed
1505
+ * 2. Converting a normal object to a mock proxy if it isn't already one
1506
+ * 3. Setting up a spy on the property get operation
1507
+ *
1508
+ * The function ensures proper cleanup by providing a cleanup function that removes
1509
+ * the spy from the proxy's internal mock map when the spy is restored.
1510
+ *
1511
+ * @throws Error - When the target object cannot be found in the global scope
1256
1512
  *
1257
1513
  * @example
1258
1514
  * ```ts
1259
- * const coolObject = {
1260
- * ClassTest: class {
1261
- * constructor(param: number) {
1262
- * console.log('original Constructor');
1263
- * }
1264
- *
1265
- * justAnFunction() {
1266
- * console.log('original justAnFunction');
1267
- * }
1268
- * }
1269
- * };
1270
- *
1271
- * const spy = xJet.spyOn(coolObject, 'ClassTest');
1272
- * spy.mockImplementationOnce((param: number) => {
1273
- * console.log(`mock Constructor with param: ${ param }`);
1515
+ * // With an existing proxy
1516
+ * const proxyObj = createMockProxy({ getData: () => 'data' });
1517
+ * const spy = spyOnProxyGet(proxyObj, 'getData');
1274
1518
  *
1275
- * return <any> {
1276
- * justAnFunction() {
1277
- * console.log('mock justAnFunction');
1278
- * }
1279
- * };
1280
- * });
1519
+ * proxyObj.getData(); // Spy records this call
1520
+ * spy.verify.called(); // Passes
1281
1521
  *
1282
- * const instance = new coolObject.ClassTest(1); // mock Constructor with param: 1
1283
- * instance.justAnFunction(); // mock justAnFunction
1522
+ * // With a normal object (will be converted to proxy)
1523
+ * const obj = { getValue: () => 42 };
1524
+ * const valueSpy = spyOnProxyGet(obj, 'getValue');
1284
1525
  *
1285
- * const instance2 = new coolObject.ClassTest(2); // original Constructor
1286
- * instance2.justAnFunction(); // original justAnFunction
1526
+ * obj.getValue(); // Spy records this call
1527
+ * valueSpy.verify.called(); // Passes
1287
1528
  * ```
1288
1529
  *
1289
- * @see ConstructorType
1290
- * @see ConstructorKeysType
1291
- *
1292
- * @since 1.0.0
1530
+ * @since 1.2.2
1293
1531
  */
1294
- 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;
1532
+ declare function spyOnProxyGet<T extends Record<string | symbol, unknown>, K extends keyof T>(target: T, prop: K): MockState;
1295
1533
  /**
1296
- * Creates a spy on a specific method or property of the given target object.
1534
+ * Creates a spy on a method or property of an object.
1297
1535
  *
1298
- * @template Target - The type of the target object to spy on.
1299
- * @template Key - The key of the property or method to spy on within the target object.
1536
+ * @template T - The type of the target object
1537
+ * @template K - The key of the property or method to spy on
1300
1538
  *
1301
- * @param target - The target object containing the property or method to be spied upon.
1302
- * @param key - The name of the property or method on the target object to spy on.
1303
- * @returns If the spied target is a function, it returns a `MockState` object to observe calls and arguments of the function.
1304
- * Otherwise, it returns a `MockState` object to observe the value or state of the property.
1539
+ * @param target - The object containing the method or property to spy on
1540
+ * @param key - The name of the method or property to spy on
1541
+ * @returns A MockState object wrapping the original method or property
1305
1542
  *
1306
- * @throws Error Throws an error if the `target` is a primitive value.
1307
- * @throws Error Throws an error if `key` is null or undefined.
1308
- * @throws Error Throws an error if the specified property does not exist on the target object.
1543
+ * @remarks
1544
+ * This function creates a spy that wraps around an existing method or property on an object.
1545
+ * The spy tracks all calls to the method or access to the property while still executing the original functionality.
1309
1546
  *
1310
- * @remarks This method is commonly used in test environments to monitor and assert interactions with a specific property
1311
- * or method on an object. The returned `MockState` can be used to retrieve call history or observe mutations.
1547
+ * - For methods: The spy preserves the original `this` context and passes all arguments to the original method
1548
+ * - For properties: The spy intercepts property access and returns the original value
1312
1549
  *
1313
1550
  * @example
1314
1551
  * ```ts
1315
- * const coolObject = {
1316
- * myMethod() {
1317
- * return 'Original myMethod';
1318
- * },
1319
- * coolString: 'Original coolString'
1552
+ * // Spying on a method
1553
+ * const user = {
1554
+ * getName: (prefix: string) => prefix + ' John'
1320
1555
  * };
1556
+ * const spy = xJet.spyOn(user, 'getName');
1321
1557
  *
1322
- * const spy = xJet.spyOn(coolObject, 'coolString');
1323
- * const spy2 = xJet.spyOn(coolObject, 'myMethod');
1324
- *
1325
- * spy.mockImplementationOnce(() => 'mock coolString');
1326
- * spy2.mockImplementationOnce(() => 'mock myMethod string');
1327
- *
1328
- * console.log(coolObject.coolString); // mock coolString
1329
- * console.log(coolObject.coolString); // Original coolString
1330
- * console.log(coolObject.myMethod()); // mock myMethod string
1331
- * console.log(coolObject.myMethod()); // Original myMethod
1558
+ * user.getName('Mr.'); // Returns "Mr. John"
1332
1559
  * ```
1333
1560
  *
1334
- * @see FunctionType
1335
- *
1336
1561
  * @since 1.0.0
1337
1562
  */
1338
- 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]>>;
1563
+ declare function spyOnImplementation<T extends object, K extends keyof T>(target: T, key: K): T[K] extends FunctionType ? MockState<(this: ThisParameterType<T[K]>, ...args: Parameters<T[K]>) => ReturnType<T[K]>> : MockState<() => T[K]>;
1339
1564
 
1340
1565
  /**
1341
- * Import will remove at compile time
1342
- */
1343
- /**
1344
- * A utility type that removes all index signatures (string and number keys) from the given type `T`.
1345
- * This results in a new type that retains only explicitly defined properties.
1346
- *
1347
- * @template T - The type from which index signatures are to be removed.
1348
- *
1349
- * @remarks
1350
- * This type is useful for filtering out index signatures from types, especially when working
1351
- * with mapped or dynamic types where indexable properties are not desired.
1352
- * When an object has an index signature (e.g., `[key: string]: any`), TypeScript assumes that all
1353
- * possible string or number keys exist on the object. This utility type filters out such keys,
1354
- * leaving only explicitly defined properties.
1355
- *
1356
- * @see https://stackoverflow.com/a/66252656/4536543
1357
- *
1358
- * @since 1.0.0
1359
- */
1360
- type RemoveIndexType<T> = {
1361
- [P in keyof T as string extends P ? never : number extends P ? never : P]: T[P];
1362
- };
1363
- /**
1364
- * A utility type that maps the keys of a given type `T` whose properties are constructor types.
1365
- *
1366
- * This type iterates over the properties of `RemoveIndexType<T>`,
1367
- * retaining only those keys where the value matches a constructor type.
1368
- *
1369
- * @template T - The target type from which constructor-like properties are to be extracted.
1370
- *
1371
- * @remarks
1372
- * This type is designed to filter out keys of a given type `T` to include only those that are associated with constructor functions.
1373
- * It leverages mapped types along with conditional type checks to achieve this functionality.
1374
- *
1375
- * @since 1.0.0
1376
- */
1377
- type PropertiesWithConstructorsType<T> = {
1378
- [Key in keyof RemoveIndexType<T> as RemoveIndexType<T>[Key] extends ConstructorType ? Key : never]: RemoveIndexType<T>[Key];
1379
- };
1380
- /**
1381
- * A utility type that extracts the keys of the provided type `T` that correspond
1382
- * to properties with constructor types, removing any index signatures.
1383
- *
1384
- * @template T - The object type from which constructor property keys are extracted.
1566
+ * Interface representing the internal state of a mock proxy.
1385
1567
  *
1386
1568
  * @remarks
1387
- * This type is useful for narrowing down a type to only the keys representing
1388
- * properties with constructor functions (e.g., classes) while excluding index signatures.
1569
+ * This interface defines the structure for storing and managing the internal state
1570
+ * of mock proxies, including mock implementations and custom property access behavior.
1389
1571
  *
1390
- * @since 1.0.0
1572
+ * @since 1.2.2
1391
1573
  */
1392
- type ConstructorKeysType<T> = RemoveIndexType<keyof PropertiesWithConstructorsType<T>>;
1574
+ interface MockProxyStateInterface {
1575
+ /**
1576
+ * Map storing mock implementations for specific properties.
1577
+ * Keys are property names, values are the mock implementations.
1578
+ *
1579
+ * @since 1.2.2
1580
+ */
1581
+ mocks: Map<PropertyKey, unknown>;
1582
+ /**
1583
+ * Optional custom getter function that overrides default property access behavior.
1584
+ * When provided, this function is called for all property access on the mock proxy.
1585
+ *
1586
+ * @since 1.2.2
1587
+ */
1588
+ customGetter: ((target: object, prop: PropertyKey, receiver: unknown) => unknown) | null;
1589
+ }
1393
1590
  /**
1394
- * A utility type that extracts the keys of a type `T` if `T` extends a constructor type.
1395
- * If `T` does not extend a constructor type, it resolves to `never`.
1396
- *
1397
- * @template T - The type to check and extract keys from.
1398
- *
1399
- * @param T - The generic type parameter which is evaluated against a constructor type.
1591
+ * Interface representing a mock proxy object.
1400
1592
  *
1401
1593
  * @remarks
1402
- * This type is particularly useful when working with class-like or constructor-based types.
1403
- * It further applies `RemoveIndexType` to exclude index signatures from the resulting keys.
1594
+ * A `MockProxyInterface` defines the structure of objects that have been
1595
+ * wrapped by a mocking proxy system. These proxies intercept property access
1596
+ * and allow for dynamic replacement or monitoring of object properties.
1404
1597
  *
1405
- * @since 1.0.0
1598
+ * @since 1.2.2
1406
1599
  */
1407
- type KeysExtendingConstructorType<T> = T extends ConstructorType ? keyof RemoveIndexType<T> : never;
1600
+ interface MockProxyInterface extends Record<PropertyKey, unknown> {
1601
+ /**
1602
+ * A boolean flag that indicates this object is a mock proxy.
1603
+ * Used for type checking and identification of mock objects.
1604
+ *
1605
+ * @since 1.2.2
1606
+ */
1607
+ readonly __isMockProxy__?: true;
1608
+ /**
1609
+ * Provides access to the internal state of the mock proxy,
1610
+ * including mapped mock implementations and custom getter functions.
1611
+ *
1612
+ * @since 1.2.2
1613
+ */
1614
+ readonly __MockMap__?: MockProxyStateInterface;
1615
+ }
1408
1616
 
1409
1617
  /**
1410
1618
  * Import will remove at compile time