@plyaz/types 1.5.2 → 1.5.4
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.js.map +1 -1
- package/dist/testing/common/mocks/types.d.ts +69 -48
- package/dist/testing/common/utils/types.d.ts +2675 -236
- package/package.json +4 -3
|
@@ -68,11 +68,8 @@ import type { UnknownRecord } from 'type-fest';
|
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
70
|
export interface SubscriptionInfo<T = unknown> {
|
|
71
|
-
/** Unique identifier for the subscription */
|
|
72
71
|
id: string;
|
|
73
|
-
/** Mocked callback function that receives subscription data */
|
|
74
72
|
callback: Vitest.MockedFunction<(data: T) => void>;
|
|
75
|
-
/** Function to unsubscribe from the event */
|
|
76
73
|
unsubscribe: () => void;
|
|
77
74
|
}
|
|
78
75
|
/**
|
|
@@ -99,25 +96,15 @@ export interface SubscriptionInfo<T = unknown> {
|
|
|
99
96
|
* ```
|
|
100
97
|
*/
|
|
101
98
|
export interface SubscriptionTracker<T = unknown> {
|
|
102
|
-
/** Track a new subscription with optional ID */
|
|
103
99
|
track: (subscribeFn: (callback: (data: T) => void) => () => void, id?: string) => SubscriptionInfo<T>;
|
|
104
|
-
/** Unsubscribe a specific subscription by ID */
|
|
105
100
|
unsubscribe: (id: string) => void;
|
|
106
|
-
/** Unsubscribe all tracked subscriptions */
|
|
107
101
|
unsubscribeAll: () => void;
|
|
108
|
-
/** Get the number of times a subscription callback was called */
|
|
109
102
|
getCallCount: (id: string) => number;
|
|
110
|
-
/** Get the data from the last callback invocation */
|
|
111
103
|
getLastCall: (id: string) => T | null;
|
|
112
|
-
/** Get all data from all callback invocations */
|
|
113
104
|
getAllCalls: (id: string) => T[];
|
|
114
|
-
/** Reset all subscriptions and their call history */
|
|
115
105
|
reset: () => void;
|
|
116
|
-
/** Reset only the callback history, keeping subscriptions active */
|
|
117
106
|
resetCallbacks: () => void;
|
|
118
|
-
/** Get list of active subscription IDs */
|
|
119
107
|
getActiveSubscriptions: () => string[];
|
|
120
|
-
/** Check if a subscription is currently active */
|
|
121
108
|
hasSubscription: (id: string) => boolean;
|
|
122
109
|
}
|
|
123
110
|
/**
|
|
@@ -142,13 +129,9 @@ export interface SubscriptionTracker<T = unknown> {
|
|
|
142
129
|
* ```
|
|
143
130
|
*/
|
|
144
131
|
export interface CreateTrackedEventEmitterReturn<T> {
|
|
145
|
-
/** Subscribe to an event with a callback, returns unsubscribe function */
|
|
146
132
|
on: (event: string, callback: (data: T) => void) => () => void;
|
|
147
|
-
/** Emit an event with data to all listeners */
|
|
148
133
|
emit: (event: string, data: T) => void;
|
|
149
|
-
/** Remove all listeners for a specific event or all events */
|
|
150
134
|
removeAllListeners: (event?: string) => void;
|
|
151
|
-
/** Subscription tracker for monitoring event activity */
|
|
152
135
|
tracker: SubscriptionTracker<T>;
|
|
153
136
|
}
|
|
154
137
|
/**
|
|
@@ -175,17 +158,11 @@ export interface CreateTrackedEventEmitterReturn<T> {
|
|
|
175
158
|
* ```
|
|
176
159
|
*/
|
|
177
160
|
export interface DeferredPromise<T = void> {
|
|
178
|
-
/** The promise that can be awaited */
|
|
179
161
|
promise: Promise<T>;
|
|
180
|
-
/** Function to resolve the promise with a value */
|
|
181
162
|
resolve: (value: T) => void;
|
|
182
|
-
/** Function to reject the promise with an error */
|
|
183
163
|
reject: (error: unknown) => void;
|
|
184
|
-
/** Whether the promise has been resolved */
|
|
185
164
|
isResolved: boolean;
|
|
186
|
-
/** Whether the promise has been rejected */
|
|
187
165
|
isRejected: boolean;
|
|
188
|
-
/** Whether the promise is still pending */
|
|
189
166
|
isPending: boolean;
|
|
190
167
|
}
|
|
191
168
|
/**
|
|
@@ -203,11 +180,8 @@ export interface DeferredPromise<T = void> {
|
|
|
203
180
|
* ```
|
|
204
181
|
*/
|
|
205
182
|
export interface WaitOptions {
|
|
206
|
-
/** Maximum time to wait in milliseconds (default: 5000) */
|
|
207
183
|
timeout?: number;
|
|
208
|
-
/** Polling interval in milliseconds (default: 50) */
|
|
209
184
|
interval?: number;
|
|
210
|
-
/** Custom error message if timeout is reached */
|
|
211
185
|
message?: string;
|
|
212
186
|
}
|
|
213
187
|
/**
|
|
@@ -233,17 +207,11 @@ export interface WaitOptions {
|
|
|
233
207
|
* ```
|
|
234
208
|
*/
|
|
235
209
|
export interface RetryOptions {
|
|
236
|
-
/** Maximum number of retry attempts (default: 3) */
|
|
237
210
|
attempts?: number;
|
|
238
|
-
/** Initial delay between retries in ms (default: 100) */
|
|
239
211
|
delay?: number;
|
|
240
|
-
/** Backoff multiplier for exponential delay (default: 2) */
|
|
241
212
|
backoff?: number;
|
|
242
|
-
/** Maximum delay between retries in ms (default: 10000) */
|
|
243
213
|
maxDelay?: number;
|
|
244
|
-
/** Function to determine if retry should occur based on error */
|
|
245
214
|
shouldRetry?: (error: Error, attempt: number) => boolean;
|
|
246
|
-
/** Callback invoked before each retry attempt */
|
|
247
215
|
onRetry?: (error: Error, attempt: number) => void;
|
|
248
216
|
}
|
|
249
217
|
/**
|
|
@@ -270,15 +238,10 @@ export interface RetryOptions {
|
|
|
270
238
|
* ```
|
|
271
239
|
*/
|
|
272
240
|
export interface MockAsync<T = void> {
|
|
273
|
-
/** The mock function that returns promises */
|
|
274
241
|
mock: Vitest.Mock;
|
|
275
|
-
/** Resolve the next pending promise with a value */
|
|
276
242
|
resolve: (value: T) => void;
|
|
277
|
-
/** Reject the next pending promise with an error */
|
|
278
243
|
reject: (error: unknown) => void;
|
|
279
|
-
/** Reset the mock and clear all pending promises */
|
|
280
244
|
reset: () => void;
|
|
281
|
-
/** Array of currently pending promises */
|
|
282
245
|
pending: DeferredPromise<T>[];
|
|
283
246
|
}
|
|
284
247
|
/**
|
|
@@ -300,15 +263,10 @@ export interface MockAsync<T = void> {
|
|
|
300
263
|
* ```
|
|
301
264
|
*/
|
|
302
265
|
export interface ControllableTimer {
|
|
303
|
-
/** Start the timer */
|
|
304
266
|
start: () => void;
|
|
305
|
-
/** Stop the timer */
|
|
306
267
|
stop: () => void;
|
|
307
|
-
/** Manually advance the timer by specified milliseconds */
|
|
308
268
|
tick: (ms: number) => void;
|
|
309
|
-
/** Reset the timer to zero */
|
|
310
269
|
reset: () => void;
|
|
311
|
-
/** Get elapsed time in milliseconds */
|
|
312
270
|
elapsed: number;
|
|
313
271
|
}
|
|
314
272
|
/**
|
|
@@ -336,19 +294,12 @@ export interface ControllableTimer {
|
|
|
336
294
|
* ```
|
|
337
295
|
*/
|
|
338
296
|
export interface TestEventEmitter<T = unknown> {
|
|
339
|
-
/** Add event listener, returns unsubscribe function */
|
|
340
297
|
on: (handler: (data: T) => void) => () => void;
|
|
341
|
-
/** Add one-time event listener, returns unsubscribe function */
|
|
342
298
|
once: (handler: (data: T) => void) => () => void;
|
|
343
|
-
/** Emit event synchronously to all listeners */
|
|
344
299
|
emit: (data: T) => void;
|
|
345
|
-
/** Emit event and wait for all async handlers to complete */
|
|
346
300
|
emitAsync: (data: T) => Promise<void>;
|
|
347
|
-
/** Remove all event listeners */
|
|
348
301
|
removeAllListeners: () => void;
|
|
349
|
-
/** Get current number of listeners */
|
|
350
302
|
listenerCount: () => number;
|
|
351
|
-
/** Wait for the next event with optional timeout */
|
|
352
303
|
waitForEvent: (timeout?: number) => Promise<T>;
|
|
353
304
|
}
|
|
354
305
|
/**
|
|
@@ -378,15 +329,10 @@ export interface TestEventEmitter<T = unknown> {
|
|
|
378
329
|
* ```
|
|
379
330
|
*/
|
|
380
331
|
export interface AsyncTestStep<T = unknown> {
|
|
381
|
-
/** Descriptive name for the step */
|
|
382
332
|
name: string;
|
|
383
|
-
/** Function to execute for this step */
|
|
384
333
|
action: () => Promise<T> | T;
|
|
385
|
-
/** Optional delay before executing this step (ms) */
|
|
386
334
|
delay?: number;
|
|
387
|
-
/** Optional assertion to run after step completes */
|
|
388
335
|
assertion?: (result: T) => void | Promise<void>;
|
|
389
|
-
/** Optional error handler for this step */
|
|
390
336
|
onError?: (error: Error) => void;
|
|
391
337
|
}
|
|
392
338
|
/**
|
|
@@ -409,13 +355,9 @@ export interface AsyncTestStep<T = unknown> {
|
|
|
409
355
|
* ```
|
|
410
356
|
*/
|
|
411
357
|
export interface ConcurrentTestOptions {
|
|
412
|
-
/** Array of async operations to execute */
|
|
413
358
|
operations: Array<() => Promise<unknown>>;
|
|
414
|
-
/** Maximum number of operations to run simultaneously */
|
|
415
359
|
maxConcurrency?: number;
|
|
416
|
-
/** Timeout for all operations in milliseconds */
|
|
417
360
|
timeout?: number;
|
|
418
|
-
/** Whether to expect some operations to fail */
|
|
419
361
|
expectErrors?: boolean;
|
|
420
362
|
}
|
|
421
363
|
/**
|
|
@@ -435,13 +377,9 @@ export interface ConcurrentTestOptions {
|
|
|
435
377
|
* ```
|
|
436
378
|
*/
|
|
437
379
|
export interface RateLimitTestOptions {
|
|
438
|
-
/** The operation to test for rate limiting */
|
|
439
380
|
operation: () => Promise<unknown>;
|
|
440
|
-
/** Target requests per second */
|
|
441
381
|
requestsPerSecond: number;
|
|
442
|
-
/** How long to run the test in milliseconds */
|
|
443
382
|
duration: number;
|
|
444
|
-
/** Whether to expect throttling to occur */
|
|
445
383
|
expectThrottle?: boolean;
|
|
446
384
|
}
|
|
447
385
|
/**
|
|
@@ -467,13 +405,9 @@ export interface RateLimitTestOptions {
|
|
|
467
405
|
* ```
|
|
468
406
|
*/
|
|
469
407
|
export interface StateTransition<T> {
|
|
470
|
-
/** Expected state before transition */
|
|
471
408
|
from: T;
|
|
472
|
-
/** Expected state after transition */
|
|
473
409
|
to: T;
|
|
474
|
-
/** Action that triggers the transition */
|
|
475
410
|
action: () => Promise<void> | void;
|
|
476
|
-
/** Optional delay after action before checking state */
|
|
477
411
|
delay?: number;
|
|
478
412
|
}
|
|
479
413
|
/**
|
|
@@ -490,9 +424,7 @@ export interface StateTransition<T> {
|
|
|
490
424
|
* ```
|
|
491
425
|
*/
|
|
492
426
|
export interface EventSequence {
|
|
493
|
-
/** Expected event names in order */
|
|
494
427
|
events: string[];
|
|
495
|
-
/** Whether events must occur in exact order (default: true) */
|
|
496
428
|
strict?: boolean;
|
|
497
429
|
}
|
|
498
430
|
/**
|
|
@@ -518,11 +450,8 @@ export interface EventSequence {
|
|
|
518
450
|
* ```
|
|
519
451
|
*/
|
|
520
452
|
export interface AsyncCleanupItem {
|
|
521
|
-
/** Descriptive name for the cleanup operation */
|
|
522
453
|
name: string;
|
|
523
|
-
/** Cleanup function to execute */
|
|
524
454
|
cleanup: () => Promise<void> | void;
|
|
525
|
-
/** Optional timeout for cleanup operation */
|
|
526
455
|
timeout?: number;
|
|
527
456
|
}
|
|
528
457
|
/**
|
|
@@ -544,15 +473,10 @@ export interface AsyncCleanupItem {
|
|
|
544
473
|
* ```
|
|
545
474
|
*/
|
|
546
475
|
export interface PollingTestOptions {
|
|
547
|
-
/** Function to call on each poll */
|
|
548
476
|
pollFn: () => Promise<unknown> | unknown;
|
|
549
|
-
/** Condition to check if polling should stop */
|
|
550
477
|
condition: (result: unknown) => boolean;
|
|
551
|
-
/** Maximum number of polling attempts */
|
|
552
478
|
maxAttempts?: number;
|
|
553
|
-
/** Interval between polls in milliseconds */
|
|
554
479
|
interval?: number;
|
|
555
|
-
/** Callback invoked after each poll */
|
|
556
480
|
onPoll?: (attempt: number, result: unknown) => void;
|
|
557
481
|
}
|
|
558
482
|
/**
|
|
@@ -699,6 +623,24 @@ export interface TestBedConfig {
|
|
|
699
623
|
imports?: unknown[];
|
|
700
624
|
exports?: unknown[];
|
|
701
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Options for testing NestJS controllers.
|
|
628
|
+
* Configures controller dependencies and mocking.
|
|
629
|
+
*
|
|
630
|
+
* @template T - Type of controller being tested
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```typescript
|
|
634
|
+
* const options: ControllerTestHarnessOptions<UserController> = {
|
|
635
|
+
* Controller: UserController,
|
|
636
|
+
* dependencies: [
|
|
637
|
+
* { token: UserService, value: mockUserService },
|
|
638
|
+
* { token: AuthGuard, value: mockAuthGuard }
|
|
639
|
+
* ],
|
|
640
|
+
* mockLogger: true
|
|
641
|
+
* };
|
|
642
|
+
* ```
|
|
643
|
+
*/
|
|
702
644
|
export interface ControllerTestHarnessOptions<T> {
|
|
703
645
|
Controller: Type<T>;
|
|
704
646
|
dependencies?: Array<{
|
|
@@ -707,6 +649,19 @@ export interface ControllerTestHarnessOptions<T> {
|
|
|
707
649
|
}>;
|
|
708
650
|
mockLogger?: boolean;
|
|
709
651
|
}
|
|
652
|
+
/**
|
|
653
|
+
* Expected response from middleware validation.
|
|
654
|
+
* Used to assert middleware behavior in tests.
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```typescript
|
|
658
|
+
* const expected: ValidateMiddlwareResponseExpected = {
|
|
659
|
+
* type: 'redirect',
|
|
660
|
+
* url: '/login',
|
|
661
|
+
* status: 302
|
|
662
|
+
* };
|
|
663
|
+
* ```
|
|
664
|
+
*/
|
|
710
665
|
export interface ValidateMiddlwareResponseExpected {
|
|
711
666
|
type: 'next' | 'redirect' | 'rewrite' | 'response';
|
|
712
667
|
url?: string;
|
|
@@ -739,6 +694,21 @@ export interface ServiceTestHarnessOptions<T> {
|
|
|
739
694
|
mockLogger?: boolean;
|
|
740
695
|
}
|
|
741
696
|
export type NestModule = Type<unknown>;
|
|
697
|
+
/**
|
|
698
|
+
* Options for testing NestJS modules.
|
|
699
|
+
* Configures module dependencies and overrides.
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const options: ModuleTestHarnessOptions = {
|
|
704
|
+
* Module: UserModule,
|
|
705
|
+
* overrideProviders: [
|
|
706
|
+
* { token: DatabaseService, useValue: mockDb },
|
|
707
|
+
* { token: CacheService, useFactory: () => mockCache }
|
|
708
|
+
* ]
|
|
709
|
+
* };
|
|
710
|
+
* ```
|
|
711
|
+
*/
|
|
742
712
|
export interface ModuleTestHarnessOptions {
|
|
743
713
|
Module: NestModule;
|
|
744
714
|
overrideProviders?: Array<{
|
|
@@ -747,6 +717,18 @@ export interface ModuleTestHarnessOptions {
|
|
|
747
717
|
useFactory?: (...args: unknown[]) => unknown;
|
|
748
718
|
}>;
|
|
749
719
|
}
|
|
720
|
+
/**
|
|
721
|
+
* Options for testing Next.js pages.
|
|
722
|
+
* Extends React Testing Library render options with Next.js specific mocks.
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
* ```typescript
|
|
726
|
+
* const options: NextPageTestOptions = {
|
|
727
|
+
* router: { pathname: '/dashboard', query: { id: '123' } },
|
|
728
|
+
* mockModules: ['router', 'image']
|
|
729
|
+
* };
|
|
730
|
+
* ```
|
|
731
|
+
*/
|
|
750
732
|
export interface NextPageTestOptions extends RenderOptions {
|
|
751
733
|
router?: Partial<MockNextRouter>;
|
|
752
734
|
mockModules?: Array<'router' | 'image' | 'link' | 'head'>;
|
|
@@ -805,12 +787,43 @@ export interface MiddlewareTestContext {
|
|
|
805
787
|
expectHeader: (name: string, value: string) => void;
|
|
806
788
|
expectNext: () => void;
|
|
807
789
|
}
|
|
790
|
+
/**
|
|
791
|
+
* Options for testing Next.js App Router hooks.
|
|
792
|
+
* Provides App Router specific context for hook testing.
|
|
793
|
+
*
|
|
794
|
+
* @template TProps - Type of hook props
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```typescript
|
|
798
|
+
* const options: AppRouterHookTestOptions<UseUserProps> = {
|
|
799
|
+
* pathname: '/user/profile',
|
|
800
|
+
* searchParams: { tab: 'settings' },
|
|
801
|
+
* params: { userId: '123' }
|
|
802
|
+
* };
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
808
805
|
export interface AppRouterHookTestOptions<TProps> extends RenderHookOptions<TProps> {
|
|
809
806
|
pathname?: string;
|
|
810
807
|
searchParams?: Record<string, string | string[]>;
|
|
811
808
|
params?: Record<string, string | string[]>;
|
|
812
809
|
}
|
|
813
810
|
export type UserEvent = UserEventLib;
|
|
811
|
+
/**
|
|
812
|
+
* Configuration for user event simulation.
|
|
813
|
+
* Controls timing and behavior of simulated user interactions.
|
|
814
|
+
*
|
|
815
|
+
* @example
|
|
816
|
+
* ```typescript
|
|
817
|
+
* const config: UserEventConfig = {
|
|
818
|
+
* delay: 10, // 10ms between keystrokes
|
|
819
|
+
* advanceTimers: vi.advanceTimersByTime,
|
|
820
|
+
* applyAccept: true,
|
|
821
|
+
* autoModify: true,
|
|
822
|
+
* skipAutoClose: false,
|
|
823
|
+
* writeToClipboard: true
|
|
824
|
+
* };
|
|
825
|
+
* ```
|
|
826
|
+
*/
|
|
814
827
|
export interface UserEventConfig {
|
|
815
828
|
delay?: number;
|
|
816
829
|
advanceTimers?: (ms: number) => void | Promise<void>;
|
|
@@ -859,6 +872,19 @@ export interface InteractionSequence {
|
|
|
859
872
|
distance?: number;
|
|
860
873
|
};
|
|
861
874
|
}
|
|
875
|
+
/**
|
|
876
|
+
* Mock child process instance for testing.
|
|
877
|
+
* Simulates Node.js child process behavior.
|
|
878
|
+
*
|
|
879
|
+
* @example
|
|
880
|
+
* ```typescript
|
|
881
|
+
* const mockProcess: MockChildProcessInstance = {
|
|
882
|
+
* stdout: { on: { mock: { calls: [] } } },
|
|
883
|
+
* stderr: { on: { mock: { calls: [] } } },
|
|
884
|
+
* on: { mock: { calls: [] } }
|
|
885
|
+
* };
|
|
886
|
+
* ```
|
|
887
|
+
*/
|
|
862
888
|
export interface MockChildProcessInstance {
|
|
863
889
|
stdout: {
|
|
864
890
|
on: {
|
|
@@ -881,6 +907,21 @@ export interface MockChildProcessInstance {
|
|
|
881
907
|
};
|
|
882
908
|
[key: string]: unknown;
|
|
883
909
|
}
|
|
910
|
+
/**
|
|
911
|
+
* Utilities for testing process-level operations.
|
|
912
|
+
* Provides helpers for simulating process events and signals.
|
|
913
|
+
*
|
|
914
|
+
* @example
|
|
915
|
+
* ```typescript
|
|
916
|
+
* const utils: ProcessTestUtils = {
|
|
917
|
+
* simulateSignal: (signal) => process.emit(signal),
|
|
918
|
+
* expectExit: (code) => expect(process.exit).toHaveBeenCalledWith(code),
|
|
919
|
+
* captureOutput: () => ({ stdout: [], stderr: [] }),
|
|
920
|
+
* simulateUncaughtException: (error) => process.emit('uncaughtException', error),
|
|
921
|
+
* simulateUnhandledRejection: (reason) => process.emit('unhandledRejection', reason)
|
|
922
|
+
* };
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
884
925
|
export interface ProcessTestUtils {
|
|
885
926
|
simulateSignal: (signal: string) => void;
|
|
886
927
|
expectExit: (code?: number) => void;
|
|
@@ -891,6 +932,21 @@ export interface ProcessTestUtils {
|
|
|
891
932
|
simulateUncaughtException: (error: Error) => void;
|
|
892
933
|
simulateUnhandledRejection: (reason: unknown) => void;
|
|
893
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* Utilities for testing child process operations.
|
|
937
|
+
* Provides helpers for asserting and simulating child process behavior.
|
|
938
|
+
*
|
|
939
|
+
* @example
|
|
940
|
+
* ```typescript
|
|
941
|
+
* const utils: ChildProcessTestUtils = {
|
|
942
|
+
* expectCommand: (cmd, args) => expect(spawn).toHaveBeenCalledWith(cmd, args),
|
|
943
|
+
* simulateOutput: (stdout, stderr) => mockProcess.stdout.emit('data', stdout),
|
|
944
|
+
* simulateError: (error) => mockProcess.emit('error', error),
|
|
945
|
+
* simulateExit: (code) => mockProcess.emit('exit', code),
|
|
946
|
+
* getLastProcess: () => mockProcesses[mockProcesses.length - 1]
|
|
947
|
+
* };
|
|
948
|
+
* ```
|
|
949
|
+
*/
|
|
894
950
|
export interface ChildProcessTestUtils {
|
|
895
951
|
expectCommand: (command: string, args?: string[]) => void;
|
|
896
952
|
simulateOutput: (stdout: string, stderr?: string) => void;
|
|
@@ -898,12 +954,41 @@ export interface ChildProcessTestUtils {
|
|
|
898
954
|
simulateExit: (code: number) => void;
|
|
899
955
|
getLastProcess: () => unknown;
|
|
900
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Utilities for testing stream operations.
|
|
959
|
+
* Provides helpers for simulating stream behavior.
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* ```typescript
|
|
963
|
+
* const utils: StreamTestUtils = {
|
|
964
|
+
* pipeData: (data) => stream.write(data),
|
|
965
|
+
* endStream: () => stream.end(),
|
|
966
|
+
* expectPipedTo: (dest) => expect(stream.pipe).toHaveBeenCalledWith(dest),
|
|
967
|
+
* getWrittenData: () => writtenChunks
|
|
968
|
+
* };
|
|
969
|
+
* ```
|
|
970
|
+
*/
|
|
901
971
|
export interface StreamTestUtils {
|
|
902
972
|
pipeData: (data: string | globalThis.Buffer) => void;
|
|
903
973
|
endStream: () => void;
|
|
904
974
|
expectPipedTo: (destination: unknown) => void;
|
|
905
975
|
getWrittenData: () => Array<string | globalThis.Buffer>;
|
|
906
976
|
}
|
|
977
|
+
/**
|
|
978
|
+
* Utilities for testing event-driven systems.
|
|
979
|
+
* Provides helpers for event simulation and assertion.
|
|
980
|
+
*
|
|
981
|
+
* @example
|
|
982
|
+
* ```typescript
|
|
983
|
+
* const utils: EventDrivenTestUtils = {
|
|
984
|
+
* emitter: createMockEventEmitter(),
|
|
985
|
+
* expectEvent: (event, payload) => expect(emitter.emit).toHaveBeenCalledWith(event, payload),
|
|
986
|
+
* expectNoEvent: (event) => expect(emitter.emit).not.toHaveBeenCalledWith(event),
|
|
987
|
+
* simulateEvents: async (events) => { // simulate },
|
|
988
|
+
* getEventHistory: () => eventHistory
|
|
989
|
+
* };
|
|
990
|
+
* ```
|
|
991
|
+
*/
|
|
907
992
|
export interface EventDrivenTestUtils {
|
|
908
993
|
emitter: MockEventEmitter;
|
|
909
994
|
expectEvent: (event: string, payload?: unknown) => void;
|
|
@@ -911,18 +996,60 @@ export interface EventDrivenTestUtils {
|
|
|
911
996
|
simulateEvents: (events: Array<SimulatedEvent>) => Promise<void>;
|
|
912
997
|
getEventHistory: () => Array<EventHistoryEntry>;
|
|
913
998
|
}
|
|
999
|
+
/**
|
|
1000
|
+
* Test server instance for integration testing.
|
|
1001
|
+
* Provides methods to manage a test server lifecycle.
|
|
1002
|
+
*
|
|
1003
|
+
* @example
|
|
1004
|
+
* ```typescript
|
|
1005
|
+
* const server: TestServer = {
|
|
1006
|
+
* url: 'http://localhost:3000',
|
|
1007
|
+
* port: 3000,
|
|
1008
|
+
* close: async () => await serverInstance.close(),
|
|
1009
|
+
* on: (event, handler) => serverInstance.on(event, handler)
|
|
1010
|
+
* };
|
|
1011
|
+
* ```
|
|
1012
|
+
*/
|
|
914
1013
|
export interface TestServer {
|
|
915
1014
|
url: string;
|
|
916
1015
|
port: number;
|
|
917
1016
|
close: () => Promise<void>;
|
|
918
1017
|
on: (event: string, handler: Function) => void;
|
|
919
1018
|
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Result from a single concurrent operation.
|
|
1021
|
+
* Contains success status and timing information.
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* ```typescript
|
|
1025
|
+
* const result: ConcurrentOperationResult = {
|
|
1026
|
+
* success: true,
|
|
1027
|
+
* result: { id: 1, status: 'uploaded' },
|
|
1028
|
+
* duration: 250
|
|
1029
|
+
* };
|
|
1030
|
+
* ```
|
|
1031
|
+
*/
|
|
920
1032
|
export interface ConcurrentOperationResult {
|
|
921
1033
|
success: boolean;
|
|
922
1034
|
result?: unknown;
|
|
923
1035
|
error?: Error;
|
|
924
1036
|
duration: number;
|
|
925
1037
|
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Aggregated results from concurrent operations testing.
|
|
1040
|
+
* Contains statistics across all concurrent operations.
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```typescript
|
|
1044
|
+
* const result: ConcurrentTestResult = {
|
|
1045
|
+
* results: [ ...operation results ],
|
|
1046
|
+
* totalDuration: 5000,
|
|
1047
|
+
* successCount: 95,
|
|
1048
|
+
* errorCount: 5,
|
|
1049
|
+
* averageDuration: 250
|
|
1050
|
+
* };
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
926
1053
|
export interface ConcurrentTestResult {
|
|
927
1054
|
results: ConcurrentOperationResult[];
|
|
928
1055
|
totalDuration: number;
|
|
@@ -930,48 +1057,168 @@ export interface ConcurrentTestResult {
|
|
|
930
1057
|
errorCount: number;
|
|
931
1058
|
averageDuration: number;
|
|
932
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* Result from a single rate-limited request.
|
|
1062
|
+
* Contains timing and success information.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```typescript
|
|
1066
|
+
* const result: RateLimitResult = {
|
|
1067
|
+
* timestamp: Date.now(),
|
|
1068
|
+
* success: true
|
|
1069
|
+
* };
|
|
1070
|
+
* ```
|
|
1071
|
+
*/
|
|
933
1072
|
export interface RateLimitResult {
|
|
934
1073
|
timestamp: number;
|
|
935
1074
|
success: boolean;
|
|
936
1075
|
error?: Error;
|
|
937
1076
|
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Aggregated results from rate limit testing.
|
|
1079
|
+
* Contains actual rate and throttling information.
|
|
1080
|
+
*
|
|
1081
|
+
* @example
|
|
1082
|
+
* ```typescript
|
|
1083
|
+
* const result: RateLimitTestResult = {
|
|
1084
|
+
* results: [ ...individual results ],
|
|
1085
|
+
* actualRate: 9.5, // requests per second
|
|
1086
|
+
* wasThrottled: true
|
|
1087
|
+
* };
|
|
1088
|
+
* ```
|
|
1089
|
+
*/
|
|
938
1090
|
export interface RateLimitTestResult {
|
|
939
1091
|
results: RateLimitResult[];
|
|
940
1092
|
actualRate: number;
|
|
941
1093
|
wasThrottled: boolean;
|
|
942
1094
|
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Single polling attempt record.
|
|
1097
|
+
* Contains attempt number and result data.
|
|
1098
|
+
*
|
|
1099
|
+
* @example
|
|
1100
|
+
* ```typescript
|
|
1101
|
+
* const attempt: PollingAttempt = {
|
|
1102
|
+
* attempt: 3,
|
|
1103
|
+
* result: { status: 'processing' },
|
|
1104
|
+
* timestamp: Date.now()
|
|
1105
|
+
* };
|
|
1106
|
+
* ```
|
|
1107
|
+
*/
|
|
943
1108
|
export interface PollingAttempt {
|
|
944
1109
|
attempt: number;
|
|
945
1110
|
result: unknown;
|
|
946
1111
|
timestamp: number;
|
|
947
1112
|
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Results from polling operation testing.
|
|
1115
|
+
* Contains attempt history and success status.
|
|
1116
|
+
*
|
|
1117
|
+
* @example
|
|
1118
|
+
* ```typescript
|
|
1119
|
+
* const result: PollingTestResult = {
|
|
1120
|
+
* attempts: [ ..polling attempts ],
|
|
1121
|
+
* conditionMet: true,
|
|
1122
|
+
* totalAttempts: 5,
|
|
1123
|
+
* totalDuration: 4500
|
|
1124
|
+
* };
|
|
1125
|
+
* ```
|
|
1126
|
+
*/
|
|
948
1127
|
export interface PollingTestResult {
|
|
949
1128
|
attempts: PollingAttempt[];
|
|
950
1129
|
conditionMet: boolean;
|
|
951
1130
|
totalAttempts: number;
|
|
952
1131
|
totalDuration: number;
|
|
953
1132
|
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Results from debounce testing.
|
|
1135
|
+
* Tracks call count and timing.
|
|
1136
|
+
*
|
|
1137
|
+
* @example
|
|
1138
|
+
* ```typescript
|
|
1139
|
+
* const result: DebounceTestResult = {
|
|
1140
|
+
* callCount: 1,
|
|
1141
|
+
* lastCallTime: Date.now()
|
|
1142
|
+
* };
|
|
1143
|
+
* ```
|
|
1144
|
+
*/
|
|
954
1145
|
export interface DebounceTestResult {
|
|
955
1146
|
callCount: number;
|
|
956
1147
|
lastCallTime: number;
|
|
957
1148
|
}
|
|
1149
|
+
/**
|
|
1150
|
+
* Single throttled call record.
|
|
1151
|
+
* Contains arguments and delay information.
|
|
1152
|
+
*
|
|
1153
|
+
* @example
|
|
1154
|
+
* ```typescript
|
|
1155
|
+
* const call: ThrottleCall = {
|
|
1156
|
+
* args: ['data', { id: 1 }],
|
|
1157
|
+
* delay: 100
|
|
1158
|
+
* };
|
|
1159
|
+
* ```
|
|
1160
|
+
*/
|
|
958
1161
|
export interface ThrottleCall {
|
|
959
1162
|
args: unknown[];
|
|
960
1163
|
delay: number;
|
|
961
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Result from throttle testing.
|
|
1167
|
+
* Indicates whether call was executed.
|
|
1168
|
+
*
|
|
1169
|
+
* @example
|
|
1170
|
+
* ```typescript
|
|
1171
|
+
* const result: ThrottleResult = {
|
|
1172
|
+
* called: true,
|
|
1173
|
+
* args: ['test', 123]
|
|
1174
|
+
* };
|
|
1175
|
+
* ```
|
|
1176
|
+
*/
|
|
962
1177
|
export interface ThrottleResult {
|
|
963
1178
|
called: boolean;
|
|
964
1179
|
args?: unknown[];
|
|
965
1180
|
}
|
|
1181
|
+
/**
|
|
1182
|
+
* Async testing scenario definition.
|
|
1183
|
+
* Defines setup, action, and verification steps.
|
|
1184
|
+
*
|
|
1185
|
+
* @template T - Type of value returned by action
|
|
1186
|
+
*
|
|
1187
|
+
* @example
|
|
1188
|
+
* ```typescript
|
|
1189
|
+
* const scenario: AsyncScenario<User> = {
|
|
1190
|
+
* name: 'Create user flow',
|
|
1191
|
+
* setup: async () => await db.connect(),
|
|
1192
|
+
* action: async () => await createUser({ name: 'Test' }),
|
|
1193
|
+
* verify: (user) => expect(user.id).toBeDefined(),
|
|
1194
|
+
* cleanup: async () => await db.disconnect(),
|
|
1195
|
+
* expectedHooks: ['beforeCreate', 'afterCreate']
|
|
1196
|
+
* };
|
|
1197
|
+
* ```
|
|
1198
|
+
*/
|
|
966
1199
|
export interface AsyncScenario<T = void> {
|
|
967
1200
|
name: string;
|
|
968
1201
|
setup: () => Promise<void>;
|
|
969
1202
|
action: () => Promise<T>;
|
|
970
1203
|
verify: (result: T) => void | Promise<void>;
|
|
971
1204
|
cleanup?: () => Promise<void>;
|
|
972
|
-
/** Expected hooks */
|
|
973
1205
|
expectedHooks: string[];
|
|
974
1206
|
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Options for waiting for value changes.
|
|
1209
|
+
* Configures polling and comparison behavior.
|
|
1210
|
+
*
|
|
1211
|
+
* @template T - Type of value being watched
|
|
1212
|
+
*
|
|
1213
|
+
* @example
|
|
1214
|
+
* ```typescript
|
|
1215
|
+
* const options: WaitForChangeOptions<number> = {
|
|
1216
|
+
* timeout: 5000,
|
|
1217
|
+
* interval: 100,
|
|
1218
|
+
* compareFn: (a, b) => Math.abs(a - b) > 0.01
|
|
1219
|
+
* };
|
|
1220
|
+
* ```
|
|
1221
|
+
*/
|
|
975
1222
|
export interface WaitForChangeOptions<T> {
|
|
976
1223
|
timeout?: number;
|
|
977
1224
|
interval?: number;
|
|
@@ -1004,24 +1251,92 @@ export interface PerformanceMetrics {
|
|
|
1004
1251
|
p99: number;
|
|
1005
1252
|
runs: number[];
|
|
1006
1253
|
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Options for timing measurements.
|
|
1256
|
+
* Configures warmup and run counts.
|
|
1257
|
+
*
|
|
1258
|
+
* @example
|
|
1259
|
+
* ```typescript
|
|
1260
|
+
* const options: MeasureTimeOptions = {
|
|
1261
|
+
* warmup: 10,
|
|
1262
|
+
* runs: 100
|
|
1263
|
+
* };
|
|
1264
|
+
* ```
|
|
1265
|
+
*/
|
|
1007
1266
|
export interface MeasureTimeOptions {
|
|
1008
1267
|
warmup?: number;
|
|
1009
1268
|
runs?: number;
|
|
1010
1269
|
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Result from timing measurement.
|
|
1272
|
+
* Contains result value and performance metrics.
|
|
1273
|
+
*
|
|
1274
|
+
* @template T - Type of value returned by measured function
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* ```typescript
|
|
1278
|
+
* const result: MeasureTimeResult<string> = {
|
|
1279
|
+
* result: 'processed',
|
|
1280
|
+
* duration: 125,
|
|
1281
|
+
* metrics: { ...performance metrics }
|
|
1282
|
+
* };
|
|
1283
|
+
* ```
|
|
1284
|
+
*/
|
|
1011
1285
|
export interface MeasureTimeResult<T> {
|
|
1012
1286
|
result: T;
|
|
1013
1287
|
duration: number;
|
|
1014
1288
|
metrics?: PerformanceMetrics;
|
|
1015
1289
|
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Benchmark results by function name.
|
|
1292
|
+
* Maps function names to their performance metrics.
|
|
1293
|
+
*
|
|
1294
|
+
* @example
|
|
1295
|
+
* ```typescript
|
|
1296
|
+
* const result: BenchmarkResult = {
|
|
1297
|
+
* 'sort': { mean: 25, median: 24, ... },
|
|
1298
|
+
* 'filter': { mean: 15, median: 14, ... }
|
|
1299
|
+
* };
|
|
1300
|
+
* ```
|
|
1301
|
+
*/
|
|
1016
1302
|
export interface BenchmarkResult {
|
|
1017
1303
|
[functionName: string]: PerformanceMetrics;
|
|
1018
1304
|
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Options for load testing.
|
|
1307
|
+
* Configures duration, concurrency, and ramp-up.
|
|
1308
|
+
*
|
|
1309
|
+
* @example
|
|
1310
|
+
* ```typescript
|
|
1311
|
+
* const options: LoadTestOptions = {
|
|
1312
|
+
* duration: 60000, // 1 minute
|
|
1313
|
+
* concurrency: 50,
|
|
1314
|
+
* rampUp: 5000, // 5 seconds
|
|
1315
|
+
* onProgress: (stats) => console.log('Progress:', stats)
|
|
1316
|
+
* };
|
|
1317
|
+
* ```
|
|
1318
|
+
*/
|
|
1019
1319
|
export interface LoadTestOptions {
|
|
1020
1320
|
duration?: number;
|
|
1021
1321
|
concurrency?: number;
|
|
1022
1322
|
rampUp?: number;
|
|
1023
1323
|
onProgress?: (stats: LoadTestStats) => void;
|
|
1024
1324
|
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Statistics collected during load testing.
|
|
1327
|
+
* Contains request counts and latency data.
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* ```typescript
|
|
1331
|
+
* const stats: LoadTestStats = {
|
|
1332
|
+
* totalRequests: 5000,
|
|
1333
|
+
* successfulRequests: 4950,
|
|
1334
|
+
* failedRequests: 50,
|
|
1335
|
+
* latencies: [120, 125, 130, ...],
|
|
1336
|
+
* errors: [ ..rror objects ]
|
|
1337
|
+
* };
|
|
1338
|
+
* ```
|
|
1339
|
+
*/
|
|
1025
1340
|
export interface LoadTestStats {
|
|
1026
1341
|
totalRequests: number;
|
|
1027
1342
|
successfulRequests: number;
|
|
@@ -1054,35 +1369,146 @@ export interface LoadTestResult {
|
|
|
1054
1369
|
throughput: number;
|
|
1055
1370
|
errors: Error[];
|
|
1056
1371
|
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Options for CPU profiling.
|
|
1374
|
+
* Configures sampling interval.
|
|
1375
|
+
*
|
|
1376
|
+
* @example
|
|
1377
|
+
* ```typescript
|
|
1378
|
+
* const options: ProfileCPUOptions = {
|
|
1379
|
+
* sampleInterval: 10 // sample every 10ms
|
|
1380
|
+
* };
|
|
1381
|
+
* ```
|
|
1382
|
+
*/
|
|
1057
1383
|
export interface ProfileCPUOptions {
|
|
1058
1384
|
sampleInterval?: number;
|
|
1059
1385
|
}
|
|
1386
|
+
/**
|
|
1387
|
+
* CPU profile data.
|
|
1388
|
+
* Contains samples and timing information.
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```typescript
|
|
1392
|
+
* const profile: CPUProfile = {
|
|
1393
|
+
* samples: [15, 20, 18, 22, 25],
|
|
1394
|
+
* duration: 1000
|
|
1395
|
+
* };
|
|
1396
|
+
* ```
|
|
1397
|
+
*/
|
|
1060
1398
|
export interface CPUProfile {
|
|
1061
1399
|
samples: number[];
|
|
1062
1400
|
duration: number;
|
|
1063
1401
|
}
|
|
1402
|
+
/**
|
|
1403
|
+
* Result from CPU profiling.
|
|
1404
|
+
* Contains function result and CPU profile.
|
|
1405
|
+
*
|
|
1406
|
+
* @template T - Type of value returned by profiled function
|
|
1407
|
+
*
|
|
1408
|
+
* @example
|
|
1409
|
+
* ```typescript
|
|
1410
|
+
* const result: ProfileCPUResult<number> = {
|
|
1411
|
+
* result: 42,
|
|
1412
|
+
* profile: { samples: [...CPU samples ], duration: 1000 }
|
|
1413
|
+
* };
|
|
1414
|
+
* ```
|
|
1415
|
+
*/
|
|
1064
1416
|
export interface ProfileCPUResult<T> {
|
|
1065
1417
|
result: T;
|
|
1066
1418
|
profile: CPUProfile;
|
|
1067
1419
|
}
|
|
1420
|
+
/**
|
|
1421
|
+
* Options for scalability testing.
|
|
1422
|
+
* Configures expected complexity and tolerance.
|
|
1423
|
+
*
|
|
1424
|
+
* @example
|
|
1425
|
+
* ```typescript
|
|
1426
|
+
* const options: ScalabilityTestOptions = {
|
|
1427
|
+
* expectedComplexity: 'linear',
|
|
1428
|
+
* tolerance: 0.1 // 10% tolerance
|
|
1429
|
+
* };
|
|
1430
|
+
* ```
|
|
1431
|
+
*/
|
|
1068
1432
|
export interface ScalabilityTestOptions {
|
|
1069
1433
|
expectedComplexity?: 'constant' | 'logarithmic' | 'linear' | 'quadratic';
|
|
1070
1434
|
tolerance?: number;
|
|
1071
1435
|
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Single scalability measurement point.
|
|
1438
|
+
* Contains input size and execution time.
|
|
1439
|
+
*
|
|
1440
|
+
* @example
|
|
1441
|
+
* ```typescript
|
|
1442
|
+
* const measurement: ScalabilityMeasurement = {
|
|
1443
|
+
* size: 1000,
|
|
1444
|
+
* time: 250 // milliseconds
|
|
1445
|
+
* };
|
|
1446
|
+
* ```
|
|
1447
|
+
*/
|
|
1072
1448
|
export interface ScalabilityMeasurement {
|
|
1073
1449
|
size: number;
|
|
1074
1450
|
time: number;
|
|
1075
1451
|
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Results from scalability testing.
|
|
1454
|
+
* Contains complexity analysis and measurements.
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* ```typescript
|
|
1458
|
+
* const result: ScalabilityTestResult = {
|
|
1459
|
+
* measurements: [ ...measurement points ],
|
|
1460
|
+
* complexity: 'O(n)',
|
|
1461
|
+
* isWithinExpected: true
|
|
1462
|
+
* };
|
|
1463
|
+
* ```
|
|
1464
|
+
*/
|
|
1076
1465
|
export interface ScalabilityTestResult {
|
|
1077
1466
|
measurements: ScalabilityMeasurement[];
|
|
1078
1467
|
complexity: string;
|
|
1079
1468
|
isWithinExpected: boolean;
|
|
1080
1469
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1470
|
+
/**
|
|
1471
|
+
* Options for performance comparison testing.
|
|
1472
|
+
* Configures comparison runs and visualization preferences.
|
|
1473
|
+
*
|
|
1474
|
+
* @example
|
|
1475
|
+
* ```typescript
|
|
1476
|
+
* const options: PerformanceComparisonOptions = {
|
|
1477
|
+
* runs: 100,
|
|
1478
|
+
* chart: true
|
|
1479
|
+
* };
|
|
1480
|
+
*
|
|
1481
|
+
* const result = await comparePerformance([
|
|
1482
|
+
* { name: 'quickSort', fn: () => quickSort(data) },
|
|
1483
|
+
* { name: 'mergeSort', fn: () => mergeSort(data) }
|
|
1484
|
+
* ], options);
|
|
1485
|
+
* ```
|
|
1486
|
+
*/
|
|
1487
|
+
export interface PerformanceComparisonOptions {
|
|
1488
|
+
runs?: number;
|
|
1489
|
+
chart?: boolean;
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Input data for performance comparison testing.
|
|
1493
|
+
* Represents a named test case with associated value or function.
|
|
1494
|
+
*
|
|
1495
|
+
* @template T - Type of the comparison input value
|
|
1496
|
+
*
|
|
1497
|
+
* @example
|
|
1498
|
+
* ```typescript
|
|
1499
|
+
* const inputs: PerformanceComparisonInput<() => number[]>[] = [
|
|
1500
|
+
* {
|
|
1501
|
+
* name: 'Bubble Sort',
|
|
1502
|
+
* value: () => bubbleSort([...testData])
|
|
1503
|
+
* },
|
|
1504
|
+
* {
|
|
1505
|
+
* name: 'Quick Sort',
|
|
1506
|
+
* value: () => quickSort([...testData])
|
|
1507
|
+
* }
|
|
1508
|
+
* ];
|
|
1509
|
+
* ```
|
|
1510
|
+
*/
|
|
1511
|
+
export interface PerformanceComparisonInput<T> {
|
|
1086
1512
|
name: string;
|
|
1087
1513
|
value: T;
|
|
1088
1514
|
}
|
|
@@ -1106,33 +1532,152 @@ export interface MemoryMeasurement {
|
|
|
1106
1532
|
delta: number;
|
|
1107
1533
|
peak: number;
|
|
1108
1534
|
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Options for memory measurement during testing.
|
|
1537
|
+
* Configures garbage collection and test run parameters.
|
|
1538
|
+
*
|
|
1539
|
+
* @example
|
|
1540
|
+
* ```typescript
|
|
1541
|
+
* const options: MeasureMemoryOptions = {
|
|
1542
|
+
* forceGC: true,
|
|
1543
|
+
* runs: 5
|
|
1544
|
+
* };
|
|
1545
|
+
*
|
|
1546
|
+
* const result = await measureMemory(() => {
|
|
1547
|
+
* return processLargeDataset(data);
|
|
1548
|
+
* }, options);
|
|
1549
|
+
* ```
|
|
1550
|
+
*/
|
|
1109
1551
|
export interface MeasureMemoryOptions {
|
|
1110
1552
|
forceGC?: boolean;
|
|
1111
1553
|
runs?: number;
|
|
1112
1554
|
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Result from memory measurement testing.
|
|
1557
|
+
* Contains the function result and memory usage statistics.
|
|
1558
|
+
*
|
|
1559
|
+
* @template T - Type of the measured function's return value
|
|
1560
|
+
*
|
|
1561
|
+
* @example
|
|
1562
|
+
* ```typescript
|
|
1563
|
+
* const result: MeasureMemoryResult<ProcessedData> = {
|
|
1564
|
+
* result: processedData,
|
|
1565
|
+
* memory: {
|
|
1566
|
+
* before: 50 * 1024 * 1024,
|
|
1567
|
+
* after: 75 * 1024 * 1024,
|
|
1568
|
+
* delta: 25 * 1024 * 1024,
|
|
1569
|
+
* peak: 80 * 1024 * 1024
|
|
1570
|
+
* }
|
|
1571
|
+
* };
|
|
1572
|
+
* ```
|
|
1573
|
+
*/
|
|
1113
1574
|
export interface MeasureMemoryResult<T> {
|
|
1114
1575
|
result: T;
|
|
1115
1576
|
memory: MemoryMeasurement;
|
|
1116
1577
|
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Performance constraints for testing operations.
|
|
1580
|
+
* Defines maximum acceptable limits for time, memory, and throughput.
|
|
1581
|
+
*
|
|
1582
|
+
* @example
|
|
1583
|
+
* ```typescript
|
|
1584
|
+
* const constraints: PerformanceConstraints = {
|
|
1585
|
+
* maxTime: 1000, // 1 second
|
|
1586
|
+
* maxMemory: 100 * 1024 * 1024, // 100MB
|
|
1587
|
+
* minThroughput: 1000 // 1000 operations per second
|
|
1588
|
+
* };
|
|
1589
|
+
*
|
|
1590
|
+
* await assertPerformance(() => processData(), constraints);
|
|
1591
|
+
* ```
|
|
1592
|
+
*/
|
|
1117
1593
|
export interface PerformanceConstraints {
|
|
1118
1594
|
maxTime?: number;
|
|
1119
1595
|
maxMemory?: number;
|
|
1120
1596
|
minThroughput?: number;
|
|
1121
1597
|
}
|
|
1598
|
+
/**
|
|
1599
|
+
* Options for performance assertion testing.
|
|
1600
|
+
* Configures test runs and duration for performance validation.
|
|
1601
|
+
*
|
|
1602
|
+
* @example
|
|
1603
|
+
* ```typescript
|
|
1604
|
+
* const options: AssertPerformanceOptions = {
|
|
1605
|
+
* runs: 10,
|
|
1606
|
+
* duration: 5000 // 5 seconds total test duration
|
|
1607
|
+
* };
|
|
1608
|
+
*
|
|
1609
|
+
* await assertPerformance(() => {
|
|
1610
|
+
* return expensiveOperation();
|
|
1611
|
+
* }, constraints, options);
|
|
1612
|
+
* ```
|
|
1613
|
+
*/
|
|
1122
1614
|
export interface AssertPerformanceOptions {
|
|
1123
1615
|
runs?: number;
|
|
1124
1616
|
duration?: number;
|
|
1125
1617
|
}
|
|
1618
|
+
/**
|
|
1619
|
+
* Entry in event history tracking.
|
|
1620
|
+
* Records event name, payload, and timestamp for testing event sequences.
|
|
1621
|
+
*
|
|
1622
|
+
* @example
|
|
1623
|
+
* ```typescript
|
|
1624
|
+
* const entry: EventHistoryEntry = {
|
|
1625
|
+
* event: 'user:login',
|
|
1626
|
+
* payload: { userId: '123', timestamp: Date.now() },
|
|
1627
|
+
* timestamp: 1640995200000
|
|
1628
|
+
* };
|
|
1629
|
+
* ```
|
|
1630
|
+
*/
|
|
1126
1631
|
export interface EventHistoryEntry {
|
|
1127
1632
|
event: string;
|
|
1128
1633
|
payload: unknown;
|
|
1129
1634
|
timestamp: number;
|
|
1130
1635
|
}
|
|
1636
|
+
/**
|
|
1637
|
+
* Configuration for simulating events in tests.
|
|
1638
|
+
* Defines event name, payload, and optional delay for event simulation.
|
|
1639
|
+
*
|
|
1640
|
+
* @example
|
|
1641
|
+
* ```typescript
|
|
1642
|
+
* const simulatedEvents: SimulatedEvent[] = [
|
|
1643
|
+
* {
|
|
1644
|
+
* event: 'connect',
|
|
1645
|
+
* payload: { connectionId: 'conn-123' }
|
|
1646
|
+
* },
|
|
1647
|
+
* {
|
|
1648
|
+
* event: 'message',
|
|
1649
|
+
* payload: { text: 'Hello World' },
|
|
1650
|
+
* delay: 100
|
|
1651
|
+
* },
|
|
1652
|
+
* {
|
|
1653
|
+
* event: 'disconnect',
|
|
1654
|
+
* delay: 5000
|
|
1655
|
+
* }
|
|
1656
|
+
* ];
|
|
1657
|
+
* ```
|
|
1658
|
+
*/
|
|
1131
1659
|
export interface SimulatedEvent {
|
|
1132
1660
|
event: string;
|
|
1133
1661
|
payload?: unknown;
|
|
1134
1662
|
delay?: number;
|
|
1135
1663
|
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Configuration options for mocking WebSocket connections.
|
|
1666
|
+
* Defines WebSocket properties and state for testing.
|
|
1667
|
+
*
|
|
1668
|
+
* @example
|
|
1669
|
+
* ```typescript
|
|
1670
|
+
* const options: WebSocketMockOptions = {
|
|
1671
|
+
* url: 'ws://localhost:8080',
|
|
1672
|
+
* protocol: 'chat',
|
|
1673
|
+
* extensions: 'permessage-deflate',
|
|
1674
|
+
* readyState: WebSocket.OPEN,
|
|
1675
|
+
* bufferedAmount: 0
|
|
1676
|
+
* };
|
|
1677
|
+
*
|
|
1678
|
+
* const mockWS = createMockWebSocket(options);
|
|
1679
|
+
* ```
|
|
1680
|
+
*/
|
|
1136
1681
|
export interface WebSocketMockOptions {
|
|
1137
1682
|
url?: string;
|
|
1138
1683
|
protocol?: string;
|
|
@@ -1140,6 +1685,21 @@ export interface WebSocketMockOptions {
|
|
|
1140
1685
|
readyState?: number;
|
|
1141
1686
|
bufferedAmount?: number;
|
|
1142
1687
|
}
|
|
1688
|
+
/**
|
|
1689
|
+
* Configuration options for mocking WebSocket servers.
|
|
1690
|
+
* Defines server properties and connection limits for testing.
|
|
1691
|
+
*
|
|
1692
|
+
* @example
|
|
1693
|
+
* ```typescript
|
|
1694
|
+
* const serverOptions: WebSocketServerMockOptions = {
|
|
1695
|
+
* port: 8080,
|
|
1696
|
+
* host: 'localhost',
|
|
1697
|
+
* maxClients: 100
|
|
1698
|
+
* };
|
|
1699
|
+
*
|
|
1700
|
+
* const mockServer = createMockWebSocketServer(serverOptions);
|
|
1701
|
+
* ```
|
|
1702
|
+
*/
|
|
1143
1703
|
export interface WebSocketServerMockOptions {
|
|
1144
1704
|
port?: number;
|
|
1145
1705
|
host?: string;
|
|
@@ -1169,6 +1729,24 @@ export interface WebSocketTestScenario {
|
|
|
1169
1729
|
shouldError?: boolean;
|
|
1170
1730
|
errorMessage?: string;
|
|
1171
1731
|
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Configuration options for WebSocket connections in tests.
|
|
1734
|
+
* Defines connection parameters and behavior settings.
|
|
1735
|
+
*
|
|
1736
|
+
* @example
|
|
1737
|
+
* ```typescript
|
|
1738
|
+
* const connectionOptions: WebSocketConnectionOptions = {
|
|
1739
|
+
* url: 'wss://api.example.com/ws',
|
|
1740
|
+
* protocols: ['chat', 'notifications'],
|
|
1741
|
+
* headers: {
|
|
1742
|
+
* 'Authorization': 'Bearer token123'
|
|
1743
|
+
* },
|
|
1744
|
+
* timeout: 10000
|
|
1745
|
+
* };
|
|
1746
|
+
*
|
|
1747
|
+
* const ws = await connectWebSocket(connectionOptions);
|
|
1748
|
+
* ```
|
|
1749
|
+
*/
|
|
1172
1750
|
export interface WebSocketConnectionOptions {
|
|
1173
1751
|
url: string;
|
|
1174
1752
|
protocols?: string | string[];
|
|
@@ -1200,6 +1778,28 @@ export interface FileOperationTest {
|
|
|
1200
1778
|
expectedFiles?: Map<string, string | globalThis.Buffer>;
|
|
1201
1779
|
expectedError?: string | RegExp;
|
|
1202
1780
|
}
|
|
1781
|
+
/**
|
|
1782
|
+
* Test configuration for process signals.
|
|
1783
|
+
* Defines signal name and expected behavior for testing signal handling.
|
|
1784
|
+
*
|
|
1785
|
+
* @example
|
|
1786
|
+
* ```typescript
|
|
1787
|
+
* const signalTests: SignalTest[] = [
|
|
1788
|
+
* {
|
|
1789
|
+
* signal: 'SIGTERM',
|
|
1790
|
+
* expectedBehavior: () => {
|
|
1791
|
+
* expect(gracefulShutdown).toHaveBeenCalled();
|
|
1792
|
+
* }
|
|
1793
|
+
* },
|
|
1794
|
+
* {
|
|
1795
|
+
* signal: 'SIGINT',
|
|
1796
|
+
* expectedBehavior: () => {
|
|
1797
|
+
* expect(process.exit).toHaveBeenCalledWith(0);
|
|
1798
|
+
* }
|
|
1799
|
+
* }
|
|
1800
|
+
* ];
|
|
1801
|
+
* ```
|
|
1802
|
+
*/
|
|
1203
1803
|
export interface SignalTest {
|
|
1204
1804
|
signal: string;
|
|
1205
1805
|
expectedBehavior: () => void;
|
|
@@ -1241,17 +1841,82 @@ export interface AriaAttributes {
|
|
|
1241
1841
|
role?: string;
|
|
1242
1842
|
tabIndex?: number;
|
|
1243
1843
|
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Test configuration for keyboard navigation behavior.
|
|
1846
|
+
* Defines element, key press, and expected navigation outcome.
|
|
1847
|
+
*
|
|
1848
|
+
* @example
|
|
1849
|
+
* ```typescript
|
|
1850
|
+
* const navTests: KeyboardNavigationTest[] = [
|
|
1851
|
+
* {
|
|
1852
|
+
* element: submitButton,
|
|
1853
|
+
* key: 'Enter',
|
|
1854
|
+
* expectedBehavior: 'activate'
|
|
1855
|
+
* },
|
|
1856
|
+
* {
|
|
1857
|
+
* element: inputField,
|
|
1858
|
+
* key: 'Tab',
|
|
1859
|
+
* expectedBehavior: 'navigate',
|
|
1860
|
+
* expectedTarget: nextButton
|
|
1861
|
+
* }
|
|
1862
|
+
* ];
|
|
1863
|
+
* ```
|
|
1864
|
+
*/
|
|
1244
1865
|
export interface KeyboardNavigationTest {
|
|
1245
1866
|
element: HTMLElement;
|
|
1246
1867
|
key: string;
|
|
1247
1868
|
expectedBehavior: 'focus' | 'activate' | 'navigate' | 'ignore';
|
|
1248
1869
|
expectedTarget?: HTMLElement;
|
|
1249
1870
|
}
|
|
1871
|
+
/**
|
|
1872
|
+
* Test configuration for screen reader accessibility.
|
|
1873
|
+
* Defines element and expected screen reader text output.
|
|
1874
|
+
*
|
|
1875
|
+
* @example
|
|
1876
|
+
* ```typescript
|
|
1877
|
+
* const screenReaderTests: ScreenReaderTest[] = [
|
|
1878
|
+
* {
|
|
1879
|
+
* element: submitButton,
|
|
1880
|
+
* expectedText: 'Submit form button',
|
|
1881
|
+
* includeHidden: false
|
|
1882
|
+
* },
|
|
1883
|
+
* {
|
|
1884
|
+
* element: errorMessage,
|
|
1885
|
+
* expectedText: /error|invalid|required/i,
|
|
1886
|
+
* includeHidden: true
|
|
1887
|
+
* }
|
|
1888
|
+
* ];
|
|
1889
|
+
* ```
|
|
1890
|
+
*/
|
|
1250
1891
|
export interface ScreenReaderTest {
|
|
1251
1892
|
element: HTMLElement;
|
|
1252
1893
|
expectedText: string | RegExp;
|
|
1253
1894
|
includeHidden?: boolean;
|
|
1254
1895
|
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Configuration for lifecycle hook testing.
|
|
1898
|
+
* Defines hook properties and execution characteristics.
|
|
1899
|
+
*
|
|
1900
|
+
* @example
|
|
1901
|
+
* ```typescript
|
|
1902
|
+
* const hooks: LifecycleHook[] = [
|
|
1903
|
+
* {
|
|
1904
|
+
* name: 'componentDidMount',
|
|
1905
|
+
* method: 'componentDidMount',
|
|
1906
|
+
* phase: 'mount',
|
|
1907
|
+
* required: true,
|
|
1908
|
+
* async: false
|
|
1909
|
+
* },
|
|
1910
|
+
* {
|
|
1911
|
+
* name: 'onModuleInit',
|
|
1912
|
+
* method: 'onModuleInit',
|
|
1913
|
+
* phase: 'init',
|
|
1914
|
+
* required: false,
|
|
1915
|
+
* async: true
|
|
1916
|
+
* }
|
|
1917
|
+
* ];
|
|
1918
|
+
* ```
|
|
1919
|
+
*/
|
|
1255
1920
|
export interface LifecycleHook {
|
|
1256
1921
|
name: string;
|
|
1257
1922
|
method: string;
|
|
@@ -1289,6 +1954,31 @@ export interface ComponentLifecycleTest {
|
|
|
1289
1954
|
expectedHooksAfter: string[];
|
|
1290
1955
|
}>;
|
|
1291
1956
|
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Interface for services that support NestJS lifecycle hooks.
|
|
1959
|
+
* Defines optional lifecycle methods for service initialization and cleanup.
|
|
1960
|
+
*
|
|
1961
|
+
* @example
|
|
1962
|
+
* ```typescript
|
|
1963
|
+
* class DatabaseService implements ServiceWithLifecycle {
|
|
1964
|
+
* async onModuleInit() {
|
|
1965
|
+
* await this.connect();
|
|
1966
|
+
* }
|
|
1967
|
+
*
|
|
1968
|
+
* async onModuleDestroy() {
|
|
1969
|
+
* await this.disconnect();
|
|
1970
|
+
* }
|
|
1971
|
+
*
|
|
1972
|
+
* async onApplicationBootstrap() {
|
|
1973
|
+
* await this.runMigrations();
|
|
1974
|
+
* }
|
|
1975
|
+
*
|
|
1976
|
+
* async onApplicationShutdown() {
|
|
1977
|
+
* await this.gracefulShutdown();
|
|
1978
|
+
* }
|
|
1979
|
+
* }
|
|
1980
|
+
* ```
|
|
1981
|
+
*/
|
|
1292
1982
|
export interface ServiceWithLifecycle {
|
|
1293
1983
|
onModuleInit?: () => Promise<void>;
|
|
1294
1984
|
onModuleDestroy?: () => Promise<void>;
|
|
@@ -1296,6 +1986,24 @@ export interface ServiceWithLifecycle {
|
|
|
1296
1986
|
onApplicationShutdown?: () => Promise<void>;
|
|
1297
1987
|
[key: string]: unknown;
|
|
1298
1988
|
}
|
|
1989
|
+
/**
|
|
1990
|
+
* Test configuration for service lifecycle hooks.
|
|
1991
|
+
* Defines service class and expected lifecycle behavior for testing.
|
|
1992
|
+
*
|
|
1993
|
+
* @example
|
|
1994
|
+
* ```typescript
|
|
1995
|
+
* const serviceTest: ServiceLifecycleTest = {
|
|
1996
|
+
* name: 'DatabaseService lifecycle',
|
|
1997
|
+
* Service: DatabaseService,
|
|
1998
|
+
* dependencies: [mockConfig, mockLogger],
|
|
1999
|
+
* expectedHooks: [
|
|
2000
|
+
* { name: 'onModuleInit', method: 'onModuleInit', phase: 'init', async: true },
|
|
2001
|
+
* { name: 'onModuleDestroy', method: 'onModuleDestroy', phase: 'destroy', async: true }
|
|
2002
|
+
* ],
|
|
2003
|
+
* cleanupExpected: true
|
|
2004
|
+
* };
|
|
2005
|
+
* ```
|
|
2006
|
+
*/
|
|
1299
2007
|
export interface ServiceLifecycleTest {
|
|
1300
2008
|
name: string;
|
|
1301
2009
|
Service: new (...args: unknown[]) => ServiceWithLifecycle;
|
|
@@ -1303,6 +2011,19 @@ export interface ServiceLifecycleTest {
|
|
|
1303
2011
|
expectedHooks: LifecycleHook[];
|
|
1304
2012
|
cleanupExpected?: boolean;
|
|
1305
2013
|
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Provider with lifecycle hooks.
|
|
2016
|
+
* Contains constructor name and lifecycle methods.
|
|
2017
|
+
*
|
|
2018
|
+
* @example
|
|
2019
|
+
* ```typescript
|
|
2020
|
+
* const provider: ProviderWithLifecycle = {
|
|
2021
|
+
* constructor: { name: 'CacheProvider' },
|
|
2022
|
+
* onModuleInit: async () => { await cache.warm(); },
|
|
2023
|
+
* onModuleDestroy: async () => { await cache.clear(); }
|
|
2024
|
+
* };
|
|
2025
|
+
* ```
|
|
2026
|
+
*/
|
|
1306
2027
|
export interface ProviderWithLifecycle {
|
|
1307
2028
|
constructor: {
|
|
1308
2029
|
name: string;
|
|
@@ -1311,6 +2032,21 @@ export interface ProviderWithLifecycle {
|
|
|
1311
2032
|
onModuleDestroy?: () => Promise<void>;
|
|
1312
2033
|
[key: string]: unknown;
|
|
1313
2034
|
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Test configuration for module lifecycle.
|
|
2037
|
+
* Defines expected provider initialization order.
|
|
2038
|
+
*
|
|
2039
|
+
* @example
|
|
2040
|
+
* ```typescript
|
|
2041
|
+
* const test: ModuleLifecycleTest = {
|
|
2042
|
+
* name: 'AppModule lifecycle',
|
|
2043
|
+
* Module: AppModule,
|
|
2044
|
+
* providers: [ // providers with lifecycle],
|
|
2045
|
+
* expectedInitOrder: ['DatabaseProvider', 'CacheProvider'],
|
|
2046
|
+
* expectedDestroyOrder: ['CacheProvider', 'DatabaseProvider']
|
|
2047
|
+
* };
|
|
2048
|
+
* ```
|
|
2049
|
+
*/
|
|
1314
2050
|
export interface ModuleLifecycleTest {
|
|
1315
2051
|
name: string;
|
|
1316
2052
|
Module: new (...args: unknown[]) => unknown;
|
|
@@ -1318,6 +2054,21 @@ export interface ModuleLifecycleTest {
|
|
|
1318
2054
|
expectedInitOrder: string[];
|
|
1319
2055
|
expectedDestroyOrder: string[];
|
|
1320
2056
|
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Test configuration for application lifecycle.
|
|
2059
|
+
* Defines expected startup and shutdown sequences.
|
|
2060
|
+
*
|
|
2061
|
+
* @example
|
|
2062
|
+
* ```typescript
|
|
2063
|
+
* const test: ApplicationLifecycleTest = {
|
|
2064
|
+
* name: 'Application lifecycle',
|
|
2065
|
+
* app: applicationInstance,
|
|
2066
|
+
* modules: [CoreModule, AuthModule],
|
|
2067
|
+
* expectedStartupSequence: ['CoreModule', 'AuthModule'],
|
|
2068
|
+
* expectedShutdownSequence: ['AuthModule', 'CoreModule']
|
|
2069
|
+
* };
|
|
2070
|
+
* ```
|
|
2071
|
+
*/
|
|
1321
2072
|
export interface ApplicationLifecycleTest {
|
|
1322
2073
|
name: string;
|
|
1323
2074
|
app: Record<string, unknown>;
|
|
@@ -1352,9 +2103,38 @@ export interface TestSuiteConfig<T> {
|
|
|
1352
2103
|
teardownAfterEach?: () => void | Promise<void>;
|
|
1353
2104
|
teardownAfterAll?: () => void | Promise<void>;
|
|
1354
2105
|
}
|
|
2106
|
+
/**
|
|
2107
|
+
* Environment configuration for testing.
|
|
2108
|
+
* Maps environment variable names to values.
|
|
2109
|
+
*
|
|
2110
|
+
* @example
|
|
2111
|
+
* ```typescript
|
|
2112
|
+
* const config: EnvironmentConfig = {
|
|
2113
|
+
* NODE_ENV: 'test',
|
|
2114
|
+
* DATABASE_URL: 'postgres://localhost/test',
|
|
2115
|
+
* API_KEY: 'test-api-key'
|
|
2116
|
+
* };
|
|
2117
|
+
* ```
|
|
2118
|
+
*/
|
|
1355
2119
|
export interface EnvironmentConfig {
|
|
1356
2120
|
[key: string]: string | undefined;
|
|
1357
2121
|
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Options for testing CSS animations.
|
|
2124
|
+
* Configures animation properties and behavior.
|
|
2125
|
+
*
|
|
2126
|
+
* @example
|
|
2127
|
+
* ```typescript
|
|
2128
|
+
* const options: AnimationTestOptions = {
|
|
2129
|
+
* duration: 1000,
|
|
2130
|
+
* easing: 'ease-in-out',
|
|
2131
|
+
* delay: 200,
|
|
2132
|
+
* iterations: 2,
|
|
2133
|
+
* direction: 'alternate',
|
|
2134
|
+
* fillMode: 'forwards'
|
|
2135
|
+
* };
|
|
2136
|
+
* ```
|
|
2137
|
+
*/
|
|
1358
2138
|
export interface AnimationTestOptions {
|
|
1359
2139
|
duration?: number;
|
|
1360
2140
|
easing?: string;
|
|
@@ -1363,12 +2143,41 @@ export interface AnimationTestOptions {
|
|
|
1363
2143
|
direction?: 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';
|
|
1364
2144
|
fillMode?: 'none' | 'forwards' | 'backwards' | 'both';
|
|
1365
2145
|
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Options for testing CSS transitions.
|
|
2148
|
+
* Configures transition properties and timing.
|
|
2149
|
+
*
|
|
2150
|
+
* @example
|
|
2151
|
+
* ```typescript
|
|
2152
|
+
* const options: TransitionTestOptions = {
|
|
2153
|
+
* property: 'transform',
|
|
2154
|
+
* duration: 300,
|
|
2155
|
+
* timingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
2156
|
+
* delay: 50
|
|
2157
|
+
* };
|
|
2158
|
+
* ```
|
|
2159
|
+
*/
|
|
1366
2160
|
export interface TransitionTestOptions {
|
|
1367
2161
|
property?: string;
|
|
1368
2162
|
duration?: number;
|
|
1369
2163
|
timingFunction?: string;
|
|
1370
2164
|
delay?: number;
|
|
1371
2165
|
}
|
|
2166
|
+
/**
|
|
2167
|
+
* Keyframe test configuration.
|
|
2168
|
+
* Defines styles at specific animation percentage.
|
|
2169
|
+
*
|
|
2170
|
+
* @example
|
|
2171
|
+
* ```typescript
|
|
2172
|
+
* const keyframe: KeyframeTest = {
|
|
2173
|
+
* percentage: 50,
|
|
2174
|
+
* styles: {
|
|
2175
|
+
* opacity: '0.5',
|
|
2176
|
+
* transform: 'scale(1.2)'
|
|
2177
|
+
* }
|
|
2178
|
+
* };
|
|
2179
|
+
* ```
|
|
2180
|
+
*/
|
|
1372
2181
|
export interface KeyframeTest {
|
|
1373
2182
|
percentage: number;
|
|
1374
2183
|
styles: Record<string, string>;
|
|
@@ -1399,12 +2208,44 @@ export interface AnimationSequence {
|
|
|
1399
2208
|
easing?: string;
|
|
1400
2209
|
}>;
|
|
1401
2210
|
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Test case for environment-specific behavior.
|
|
2213
|
+
* Defines environment setup and expected behavior.
|
|
2214
|
+
*
|
|
2215
|
+
* @example
|
|
2216
|
+
* ```typescript
|
|
2217
|
+
* const testCase: EnvironmentTestCase = {
|
|
2218
|
+
* name: 'Production environment',
|
|
2219
|
+
* environment: { NODE_ENV: 'production' },
|
|
2220
|
+
* expectedBehavior: async () => {
|
|
2221
|
+
* expect(logger.level).toBe('error');
|
|
2222
|
+
* },
|
|
2223
|
+
* cleanup: async () => { process.env.NODE_ENV = 'test'; }
|
|
2224
|
+
* };
|
|
2225
|
+
* ```
|
|
2226
|
+
*/
|
|
1402
2227
|
export interface EnvironmentTestCase {
|
|
1403
2228
|
name: string;
|
|
1404
2229
|
environment: EnvironmentConfig;
|
|
1405
2230
|
expectedBehavior: () => void | Promise<void>;
|
|
1406
2231
|
cleanup?: () => void | Promise<void>;
|
|
1407
2232
|
}
|
|
2233
|
+
/**
|
|
2234
|
+
* Configuration test scenario.
|
|
2235
|
+
* Defines config values and expected results.
|
|
2236
|
+
*
|
|
2237
|
+
* @example
|
|
2238
|
+
* ```typescript
|
|
2239
|
+
* const scenario: ConfigTestScenario = {
|
|
2240
|
+
* name: 'Invalid database config',
|
|
2241
|
+
* config: { database: { host: '' } },
|
|
2242
|
+
* environment: { DB_HOST: '' },
|
|
2243
|
+
* expectedValues: {},
|
|
2244
|
+
* shouldThrow: true,
|
|
2245
|
+
* expectedError: /Database host is required/
|
|
2246
|
+
* };
|
|
2247
|
+
* ```
|
|
2248
|
+
*/
|
|
1408
2249
|
export interface ConfigTestScenario {
|
|
1409
2250
|
name: string;
|
|
1410
2251
|
config: Record<string, unknown>;
|
|
@@ -1413,35 +2254,139 @@ export interface ConfigTestScenario {
|
|
|
1413
2254
|
shouldThrow?: boolean;
|
|
1414
2255
|
expectedError?: string | RegExp;
|
|
1415
2256
|
}
|
|
2257
|
+
/**
|
|
2258
|
+
* Spring animation configuration.
|
|
2259
|
+
* Defines physical properties for spring animations.
|
|
2260
|
+
*
|
|
2261
|
+
* @example
|
|
2262
|
+
* ```typescript
|
|
2263
|
+
* const spring: SpringConfig = {
|
|
2264
|
+
* tension: 170,
|
|
2265
|
+
* friction: 26,
|
|
2266
|
+
* mass: 1
|
|
2267
|
+
* };
|
|
2268
|
+
* ```
|
|
2269
|
+
*/
|
|
1416
2270
|
export interface SpringConfig {
|
|
1417
2271
|
tension: number;
|
|
1418
2272
|
friction: number;
|
|
1419
2273
|
mass: number;
|
|
1420
2274
|
}
|
|
2275
|
+
/**
|
|
2276
|
+
* RequestAnimationFrame callback wrapper.
|
|
2277
|
+
* Stores callback ID and function reference.
|
|
2278
|
+
*
|
|
2279
|
+
* @example
|
|
2280
|
+
* ```typescript
|
|
2281
|
+
* const rafCallback: RAFCallback = {
|
|
2282
|
+
* id: 1,
|
|
2283
|
+
* callback: (timestamp) => { // animation logic }
|
|
2284
|
+
* };
|
|
2285
|
+
* ```
|
|
2286
|
+
*/
|
|
1421
2287
|
export interface RAFCallback {
|
|
1422
2288
|
id: number;
|
|
1423
2289
|
callback: FrameRequestCallback;
|
|
1424
2290
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
2291
|
+
/**
|
|
2292
|
+
* Loading state interface.
|
|
2293
|
+
* Represents loading status in async operations.
|
|
2294
|
+
*
|
|
2295
|
+
* @example
|
|
2296
|
+
* ```typescript
|
|
2297
|
+
* const state: LoadingState = {
|
|
2298
|
+
* isLoading: true,
|
|
2299
|
+
* loading: true
|
|
2300
|
+
* };
|
|
2301
|
+
* ```
|
|
2302
|
+
*/
|
|
2303
|
+
export interface LoadingState {
|
|
2304
|
+
isLoading?: boolean;
|
|
2305
|
+
loading?: boolean;
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Options for text waiting utilities.
|
|
2309
|
+
* Configures timeout for text appearance.
|
|
2310
|
+
*
|
|
2311
|
+
* @example
|
|
2312
|
+
* ```typescript
|
|
2313
|
+
* const options: ForTextOptions = {
|
|
2314
|
+
* timeout: 3000 // Wait up to 3 seconds
|
|
2315
|
+
* };
|
|
2316
|
+
* ```
|
|
2317
|
+
*/
|
|
2318
|
+
export interface ForTextOptions {
|
|
1430
2319
|
timeout?: number;
|
|
1431
2320
|
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Test value with index wrapper.
|
|
2323
|
+
* Associates test values with their position.
|
|
2324
|
+
*
|
|
2325
|
+
* @template T - Type of test value
|
|
2326
|
+
*
|
|
2327
|
+
* @example
|
|
2328
|
+
* ```typescript
|
|
2329
|
+
* const testValue: TestValueWithIndex<string> = {
|
|
2330
|
+
* value: 'test-data',
|
|
2331
|
+
* index: 2
|
|
2332
|
+
* };
|
|
2333
|
+
* ```
|
|
2334
|
+
*/
|
|
1432
2335
|
export interface TestValueWithIndex<T> {
|
|
1433
2336
|
value: T;
|
|
1434
2337
|
index: number;
|
|
1435
2338
|
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Record of a function call.
|
|
2341
|
+
* Tracks method name, arguments, and timestamp.
|
|
2342
|
+
*
|
|
2343
|
+
* @example
|
|
2344
|
+
* ```typescript
|
|
2345
|
+
* const call: CallRecord = {
|
|
2346
|
+
* method: 'saveUser',
|
|
2347
|
+
* args: [{ id: 1, name: 'John' }],
|
|
2348
|
+
* timestamp: Date.now()
|
|
2349
|
+
* };
|
|
2350
|
+
* ```
|
|
2351
|
+
*/
|
|
1436
2352
|
export interface CallRecord {
|
|
1437
2353
|
method: string;
|
|
1438
2354
|
args: unknown[];
|
|
1439
2355
|
timestamp: number;
|
|
1440
2356
|
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Module spy for tracking calls.
|
|
2359
|
+
* Wraps module with call tracking.
|
|
2360
|
+
*
|
|
2361
|
+
* @template T - Type of module being spied on
|
|
2362
|
+
*
|
|
2363
|
+
* @example
|
|
2364
|
+
* ```typescript
|
|
2365
|
+
* const spy: ModuleSpy<UserService> = {
|
|
2366
|
+
* module: userService,
|
|
2367
|
+
* calls: [...tracked calls]
|
|
2368
|
+
* };
|
|
2369
|
+
* ```
|
|
2370
|
+
*/
|
|
1441
2371
|
export interface ModuleSpy<T> {
|
|
1442
2372
|
module: T;
|
|
1443
2373
|
calls: CallRecord[];
|
|
1444
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Named test case for table-driven tests.
|
|
2377
|
+
* Associates name with input and expected output.
|
|
2378
|
+
*
|
|
2379
|
+
* @template T - Type of test input
|
|
2380
|
+
*
|
|
2381
|
+
* @example
|
|
2382
|
+
* ```typescript
|
|
2383
|
+
* const testCase: NamedTestCase<number> = {
|
|
2384
|
+
* name: 'handles negative numbers',
|
|
2385
|
+
* input: -5,
|
|
2386
|
+
* expected: 5
|
|
2387
|
+
* };
|
|
2388
|
+
* ```
|
|
2389
|
+
*/
|
|
1445
2390
|
export interface NamedTestCase<T> {
|
|
1446
2391
|
name: string;
|
|
1447
2392
|
input: T;
|
|
@@ -1470,25 +2415,75 @@ export interface NextPageResult {
|
|
|
1470
2415
|
};
|
|
1471
2416
|
notFound?: boolean;
|
|
1472
2417
|
}
|
|
2418
|
+
/**
|
|
2419
|
+
* Result of a mocked function call.
|
|
2420
|
+
* Captures arguments, return value, and any errors.
|
|
2421
|
+
*
|
|
2422
|
+
* @example
|
|
2423
|
+
* ```typescript
|
|
2424
|
+
* const result: MockCallResult = {
|
|
2425
|
+
* args: ['user123', { name: 'John' }],
|
|
2426
|
+
* result: { id: 1, success: true },
|
|
2427
|
+
* error: undefined
|
|
2428
|
+
* };
|
|
2429
|
+
* ```
|
|
2430
|
+
*/
|
|
1473
2431
|
export interface MockCallResult {
|
|
1474
2432
|
args: unknown[];
|
|
1475
2433
|
result: unknown;
|
|
1476
2434
|
error?: unknown;
|
|
1477
2435
|
}
|
|
2436
|
+
/**
|
|
2437
|
+
* File system watcher mock for testing file change events.
|
|
2438
|
+
* Simulates file watching with change, add, and unlink events.
|
|
2439
|
+
*
|
|
2440
|
+
* @example
|
|
2441
|
+
* ```typescript
|
|
2442
|
+
* const watcher: FileWatcher = createFileWatcher();
|
|
2443
|
+
* watcher.simulateChange('/src/app.ts');
|
|
2444
|
+
* watcher.simulateAdd('/src/new-file.ts');
|
|
2445
|
+
* watcher.simulateUnlink('/src/deleted.ts');
|
|
2446
|
+
* watcher.close();
|
|
2447
|
+
* ```
|
|
2448
|
+
*/
|
|
1478
2449
|
export interface FileWatcher extends MockEventEmitter {
|
|
1479
2450
|
add: Vitest.Mock;
|
|
1480
2451
|
unwatch: Vitest.Mock;
|
|
1481
|
-
close:
|
|
2452
|
+
close: () => void;
|
|
1482
2453
|
getWatched: Vitest.Mock;
|
|
1483
2454
|
simulateChange: (path: string) => void;
|
|
1484
2455
|
simulateAdd: (path: string) => void;
|
|
1485
2456
|
simulateUnlink: (path: string) => void;
|
|
1486
2457
|
}
|
|
2458
|
+
/**
|
|
2459
|
+
* NestJS testing module for unit and integration tests.
|
|
2460
|
+
* Provides dependency injection and module management.
|
|
2461
|
+
*
|
|
2462
|
+
* @example
|
|
2463
|
+
* ```typescript
|
|
2464
|
+
* const testBed: NestJSTestBed = await createTestBed();
|
|
2465
|
+
* const service = testBed.get<UserService>(UserService);
|
|
2466
|
+
* expect(service).toBeDefined();
|
|
2467
|
+
* await testBed.close();
|
|
2468
|
+
* ```
|
|
2469
|
+
*/
|
|
1487
2470
|
export interface NestJSTestBed {
|
|
1488
2471
|
get: <T>(token: unknown) => T;
|
|
1489
2472
|
close: () => Promise<void>;
|
|
1490
2473
|
moduleRef: Map<unknown, unknown>;
|
|
1491
2474
|
}
|
|
2475
|
+
/**
|
|
2476
|
+
* Test harness for module testing.
|
|
2477
|
+
* Provides module reference and dependency resolution.
|
|
2478
|
+
*
|
|
2479
|
+
* @example
|
|
2480
|
+
* ```typescript
|
|
2481
|
+
* const harness: ModuleTestHarness = await createModuleHarness();
|
|
2482
|
+
* const controller = harness.get<AppController>(AppController);
|
|
2483
|
+
* const result = await controller.getData();
|
|
2484
|
+
* await harness.close();
|
|
2485
|
+
* ```
|
|
2486
|
+
*/
|
|
1492
2487
|
export interface ModuleTestHarness {
|
|
1493
2488
|
moduleRef: {
|
|
1494
2489
|
get: <T>(token: unknown) => T;
|
|
@@ -1498,6 +2493,18 @@ export interface ModuleTestHarness {
|
|
|
1498
2493
|
get: <T>(token: unknown) => T;
|
|
1499
2494
|
close: () => Promise<void>;
|
|
1500
2495
|
}
|
|
2496
|
+
/**
|
|
2497
|
+
* Helper utilities for Next.js router testing.
|
|
2498
|
+
* Provides navigation simulation and route change testing.
|
|
2499
|
+
*
|
|
2500
|
+
* @example
|
|
2501
|
+
* ```typescript
|
|
2502
|
+
* const helpers: NextRouterHelpers = createRouterHelpers();
|
|
2503
|
+
* await helpers.navigateTo('/dashboard');
|
|
2504
|
+
* helpers.simulateRouteChange('/home', '/about');
|
|
2505
|
+
* helpers.expectNavigation('/login', 'push');
|
|
2506
|
+
* ```
|
|
2507
|
+
*/
|
|
1501
2508
|
export interface NextRouterHelpers {
|
|
1502
2509
|
navigateTo: (url: string, options?: NavigationOptions) => Promise<void>;
|
|
1503
2510
|
simulateRouteChange: (fromUrl: string, toUrl: string) => void;
|
|
@@ -1505,11 +2512,38 @@ export interface NextRouterHelpers {
|
|
|
1505
2512
|
expectNavigation: (url: string, type?: 'push' | 'replace') => void;
|
|
1506
2513
|
expectNoNavigation: () => void;
|
|
1507
2514
|
}
|
|
2515
|
+
/**
|
|
2516
|
+
* Complete Next.js router mock with restoration.
|
|
2517
|
+
* Includes router instance and useRouter hook mock.
|
|
2518
|
+
*
|
|
2519
|
+
* @example
|
|
2520
|
+
* ```typescript
|
|
2521
|
+
* const mock: MockNextRouterReturn = mockNextRouter();
|
|
2522
|
+
* mock.router.push('/new-route');
|
|
2523
|
+
* const { pathname } = mock.useRouter();
|
|
2524
|
+
* mock.restore();
|
|
2525
|
+
* ```
|
|
2526
|
+
*/
|
|
1508
2527
|
export interface MockNextRouterReturn {
|
|
1509
2528
|
router: MockNextRouter;
|
|
1510
2529
|
useRouter: CreateMockUseRouterReturn;
|
|
1511
2530
|
restore: () => void;
|
|
1512
2531
|
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Mock Next.js request object for API route testing.
|
|
2534
|
+
* Simulates incoming HTTP requests with headers, body, and metadata.
|
|
2535
|
+
*
|
|
2536
|
+
* @example
|
|
2537
|
+
* ```typescript
|
|
2538
|
+
* const request: MockNextRequest = {
|
|
2539
|
+
* url: '/api/users',
|
|
2540
|
+
* method: 'POST',
|
|
2541
|
+
* headers: new Headers({ 'content-type': 'application/json' }),
|
|
2542
|
+
* body: { name: 'John' },
|
|
2543
|
+
* ip: '192.168.1.1'
|
|
2544
|
+
* };
|
|
2545
|
+
* ```
|
|
2546
|
+
*/
|
|
1513
2547
|
export interface MockNextRequest {
|
|
1514
2548
|
url: string;
|
|
1515
2549
|
method: string;
|
|
@@ -1536,6 +2570,18 @@ export interface MockNextRequest {
|
|
|
1536
2570
|
longitude: string;
|
|
1537
2571
|
};
|
|
1538
2572
|
}
|
|
2573
|
+
/**
|
|
2574
|
+
* Mock Next.js response object for API route testing.
|
|
2575
|
+
* Provides response methods for redirects, rewrites, and JSON responses.
|
|
2576
|
+
*
|
|
2577
|
+
* @example
|
|
2578
|
+
* ```typescript
|
|
2579
|
+
* const response: MockNextResponse = createMockResponse();
|
|
2580
|
+
* response.status = 200;
|
|
2581
|
+
* response.json({ success: true });
|
|
2582
|
+
* response.redirect('/login');
|
|
2583
|
+
* ```
|
|
2584
|
+
*/
|
|
1539
2585
|
export interface MockNextResponse {
|
|
1540
2586
|
cookies: {
|
|
1541
2587
|
set: Vitest.Mock;
|
|
@@ -1548,6 +2594,18 @@ export interface MockNextResponse {
|
|
|
1548
2594
|
next: Vitest.Mock;
|
|
1549
2595
|
json: Vitest.Mock;
|
|
1550
2596
|
}
|
|
2597
|
+
/**
|
|
2598
|
+
* Mock WebSocket server for testing real-time connections.
|
|
2599
|
+
* Simulates WebSocket server with client management and broadcasting.
|
|
2600
|
+
*
|
|
2601
|
+
* @example
|
|
2602
|
+
* ```typescript
|
|
2603
|
+
* const server: MockWebSocketServer = createMockWebSocketServer();
|
|
2604
|
+
* const client = server.simulateConnection('client-1');
|
|
2605
|
+
* server.simulateBroadcast({ type: 'message', data: 'Hello' });
|
|
2606
|
+
* server.simulateClientDisconnect('client-1');
|
|
2607
|
+
* ```
|
|
2608
|
+
*/
|
|
1551
2609
|
export interface MockWebSocketServer extends MockEventEmitter {
|
|
1552
2610
|
clients: Set<CreateMockWebSocketReturn>;
|
|
1553
2611
|
port: number;
|
|
@@ -1562,14 +2620,52 @@ export interface MockWebSocketServer extends MockEventEmitter {
|
|
|
1562
2620
|
simulateBroadcast: (data: unknown, excludeClient?: string) => void;
|
|
1563
2621
|
simulateClientDisconnect: (clientId: string) => void;
|
|
1564
2622
|
}
|
|
2623
|
+
/**
|
|
2624
|
+
* Global WebSocket mock with restoration capability.
|
|
2625
|
+
* Replaces global WebSocket constructor for testing.
|
|
2626
|
+
*
|
|
2627
|
+
* @example
|
|
2628
|
+
* ```typescript
|
|
2629
|
+
* const mock: MockWebSocketGlobal = mockGlobalWebSocket();
|
|
2630
|
+
* const ws = new WebSocket('ws://localhost:8080');
|
|
2631
|
+
* // Test WebSocket functionality
|
|
2632
|
+
* mock.restore();
|
|
2633
|
+
* ```
|
|
2634
|
+
*/
|
|
1565
2635
|
export interface MockWebSocketGlobal {
|
|
1566
2636
|
restore: () => void;
|
|
1567
2637
|
}
|
|
2638
|
+
/**
|
|
2639
|
+
* System date mock for time-based testing.
|
|
2640
|
+
* Controls system time for testing time-dependent code.
|
|
2641
|
+
*
|
|
2642
|
+
* @example
|
|
2643
|
+
* ```typescript
|
|
2644
|
+
* const dateMock: MockSystemDateReturn = mockSystemDate();
|
|
2645
|
+
* dateMock.setDate('2024-01-01');
|
|
2646
|
+
* dateMock.advanceBy(3600000); // Advance 1 hour
|
|
2647
|
+
* ```
|
|
2648
|
+
*/
|
|
1568
2649
|
export interface MockSystemDateReturn {
|
|
1569
2650
|
setDate: (newDate: Date | string | number) => void;
|
|
1570
2651
|
advanceBy: (ms: number) => void;
|
|
1571
2652
|
}
|
|
1572
2653
|
export type GetStaticPathsResult = NextGetStaticPathsResult;
|
|
2654
|
+
/**
|
|
2655
|
+
* Expectations for Next.js getStaticPaths testing.
|
|
2656
|
+
* Validates static path generation behavior.
|
|
2657
|
+
*
|
|
2658
|
+
* @example
|
|
2659
|
+
* ```typescript
|
|
2660
|
+
* const expectations: GetStaticPathsExpectations = {
|
|
2661
|
+
* pathCount: 10,
|
|
2662
|
+
* fallback: 'blocking',
|
|
2663
|
+
* validatePaths: (paths) => {
|
|
2664
|
+
* expect(paths).toContainEqual({ params: { id: '1' } });
|
|
2665
|
+
* }
|
|
2666
|
+
* };
|
|
2667
|
+
* ```
|
|
2668
|
+
*/
|
|
1573
2669
|
export interface GetStaticPathsExpectations {
|
|
1574
2670
|
pathCount?: number;
|
|
1575
2671
|
fallback: boolean | 'blocking';
|
|
@@ -1577,6 +2673,22 @@ export interface GetStaticPathsExpectations {
|
|
|
1577
2673
|
params: Record<string, string | string[] | undefined>;
|
|
1578
2674
|
}>) => void;
|
|
1579
2675
|
}
|
|
2676
|
+
/**
|
|
2677
|
+
* Image optimization test scenario.
|
|
2678
|
+
* Defines expected image optimization behavior in Next.js.
|
|
2679
|
+
*
|
|
2680
|
+
* @example
|
|
2681
|
+
* ```typescript
|
|
2682
|
+
* const scenario: ImageOptimizationScenario = {
|
|
2683
|
+
* src: '/images/hero.jpg',
|
|
2684
|
+
* width: 1200,
|
|
2685
|
+
* quality: 85,
|
|
2686
|
+
* expectedUrl: '/_next/image?url=%2Fimages%2Fhero.jpg&w=1200&q=85',
|
|
2687
|
+
* alt: 'Hero image',
|
|
2688
|
+
* priority: true
|
|
2689
|
+
* };
|
|
2690
|
+
* ```
|
|
2691
|
+
*/
|
|
1580
2692
|
export interface ImageOptimizationScenario {
|
|
1581
2693
|
src: string;
|
|
1582
2694
|
width: number;
|
|
@@ -1586,20 +2698,75 @@ export interface ImageOptimizationScenario {
|
|
|
1586
2698
|
priority?: boolean;
|
|
1587
2699
|
height?: number;
|
|
1588
2700
|
}
|
|
2701
|
+
/**
|
|
2702
|
+
* Options for drag and drop testing.
|
|
2703
|
+
* Configures drag data and expected drop effects.
|
|
2704
|
+
*
|
|
2705
|
+
* @example
|
|
2706
|
+
* ```typescript
|
|
2707
|
+
* const options: DragAndDropOptions = {
|
|
2708
|
+
* dragData: { 'text/plain': 'Dragged item' },
|
|
2709
|
+
* expectedDropEffect: 'move'
|
|
2710
|
+
* };
|
|
2711
|
+
* ```
|
|
2712
|
+
*/
|
|
1589
2713
|
export interface DragAndDropOptions {
|
|
1590
2714
|
dragData?: Record<string, string>;
|
|
1591
2715
|
expectedDropEffect?: 'copy' | 'move' | 'link' | 'none';
|
|
1592
2716
|
}
|
|
2717
|
+
/**
|
|
2718
|
+
* Options for realistic typing simulation.
|
|
2719
|
+
* Simulates human-like typing with pauses and typos.
|
|
2720
|
+
*
|
|
2721
|
+
* @example
|
|
2722
|
+
* ```typescript
|
|
2723
|
+
* const options: TypeRealisticOptions = {
|
|
2724
|
+
* pauseBetweenChars: 50,
|
|
2725
|
+
* typos: true,
|
|
2726
|
+
* speed: 'normal'
|
|
2727
|
+
* };
|
|
2728
|
+
* ```
|
|
2729
|
+
*/
|
|
1593
2730
|
export interface TypeRealisticOptions {
|
|
1594
2731
|
pauseBetweenChars?: number;
|
|
1595
2732
|
typos?: boolean;
|
|
1596
2733
|
speed?: 'slow' | 'normal' | 'fast';
|
|
1597
2734
|
}
|
|
2735
|
+
/**
|
|
2736
|
+
* Expectations for loading component testing.
|
|
2737
|
+
* Validates loading state UI elements.
|
|
2738
|
+
*
|
|
2739
|
+
* @example
|
|
2740
|
+
* ```typescript
|
|
2741
|
+
* const expectations: LoadingComponentExpectations = {
|
|
2742
|
+
* testId: 'loading-spinner',
|
|
2743
|
+
* text: 'Loading...',
|
|
2744
|
+
* className: 'spinner-active'
|
|
2745
|
+
* };
|
|
2746
|
+
* ```
|
|
2747
|
+
*/
|
|
1598
2748
|
export interface LoadingComponentExpectations {
|
|
1599
2749
|
testId?: string;
|
|
1600
2750
|
text?: string;
|
|
1601
2751
|
className?: string;
|
|
1602
2752
|
}
|
|
2753
|
+
/**
|
|
2754
|
+
* Test scenario for Next.js middleware.
|
|
2755
|
+
* Defines request and expected middleware behavior.
|
|
2756
|
+
*
|
|
2757
|
+
* @example
|
|
2758
|
+
* ```typescript
|
|
2759
|
+
* const scenario: MiddlewareTestScenarioWithRequest = {
|
|
2760
|
+
* name: 'Auth redirect',
|
|
2761
|
+
* request: ['/admin', { headers: {} }],
|
|
2762
|
+
* expected: {
|
|
2763
|
+
* type: 'redirect',
|
|
2764
|
+
* url: '/login',
|
|
2765
|
+
* status: 302
|
|
2766
|
+
* }
|
|
2767
|
+
* };
|
|
2768
|
+
* ```
|
|
2769
|
+
*/
|
|
1603
2770
|
export interface MiddlewareTestScenarioWithRequest {
|
|
1604
2771
|
name: string;
|
|
1605
2772
|
request: Parameters<CreateMockNextRequestFunction>;
|
|
@@ -1610,6 +2777,19 @@ export interface MiddlewareTestScenarioWithRequest {
|
|
|
1610
2777
|
status?: number;
|
|
1611
2778
|
};
|
|
1612
2779
|
}
|
|
2780
|
+
/**
|
|
2781
|
+
* API route handler methods for Next.js.
|
|
2782
|
+
* Maps HTTP methods to handler functions.
|
|
2783
|
+
*
|
|
2784
|
+
* @example
|
|
2785
|
+
* ```typescript
|
|
2786
|
+
* const handlers: ApiRouteHandlerMethods = {
|
|
2787
|
+
* GET: async (req, res) => res.json({ users: [] }),
|
|
2788
|
+
* POST: async (req, res) => res.status(201).json({ id: 1 }),
|
|
2789
|
+
* DELETE: async (req, res) => res.status(204).end()
|
|
2790
|
+
* };
|
|
2791
|
+
* ```
|
|
2792
|
+
*/
|
|
1613
2793
|
export interface ApiRouteHandlerMethods {
|
|
1614
2794
|
GET?: Function;
|
|
1615
2795
|
POST?: Function;
|
|
@@ -1617,106 +2797,422 @@ export interface ApiRouteHandlerMethods {
|
|
|
1617
2797
|
DELETE?: Function;
|
|
1618
2798
|
PATCH?: Function;
|
|
1619
2799
|
}
|
|
2800
|
+
/**
|
|
2801
|
+
* Test scenario for route handlers.
|
|
2802
|
+
* Defines request method and expected response.
|
|
2803
|
+
*
|
|
2804
|
+
* @example
|
|
2805
|
+
* ```typescript
|
|
2806
|
+
* const scenario: RouteHandlerTestScenario = {
|
|
2807
|
+
* method: 'POST',
|
|
2808
|
+
* request: [{ url: '/api/users', body: { name: 'John' } }],
|
|
2809
|
+
* expectedStatus: 201,
|
|
2810
|
+
* expectedBody: { id: 1, name: 'John' }
|
|
2811
|
+
* };
|
|
2812
|
+
* ```
|
|
2813
|
+
*/
|
|
1620
2814
|
export interface RouteHandlerTestScenario {
|
|
1621
2815
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
1622
2816
|
request: Parameters<CreateMockNextRequestFunction>;
|
|
1623
2817
|
expectedStatus: number;
|
|
1624
2818
|
expectedBody?: unknown;
|
|
1625
2819
|
}
|
|
2820
|
+
/**
|
|
2821
|
+
* Test scenario for image loader.
|
|
2822
|
+
* Defines input parameters and expected URL.
|
|
2823
|
+
*
|
|
2824
|
+
* @example
|
|
2825
|
+
* ```typescript
|
|
2826
|
+
* const scenario: ImageLoaderTestScenario = {
|
|
2827
|
+
* input: { src: '/img.jpg', width: 800, quality: 75 },
|
|
2828
|
+
* expectedUrl: '/_next/image?url=%2Fimg.jpg&w=800&q=75'
|
|
2829
|
+
* };
|
|
2830
|
+
* ```
|
|
2831
|
+
*/
|
|
1626
2832
|
export interface ImageLoaderTestScenario {
|
|
1627
2833
|
input: ImageLoaderInput;
|
|
1628
2834
|
expectedUrl: string | RegExp;
|
|
1629
2835
|
}
|
|
2836
|
+
/**
|
|
2837
|
+
* Parameterized test runner.
|
|
2838
|
+
* Provides method to run tests with different inputs.
|
|
2839
|
+
*
|
|
2840
|
+
* @template T - Type of test input
|
|
2841
|
+
*
|
|
2842
|
+
* @example
|
|
2843
|
+
* ```typescript
|
|
2844
|
+
* const paramTest: ParameterizedTest<number> = {
|
|
2845
|
+
* test: (name, fn) => {
|
|
2846
|
+
* test(name, () => fn(5, 10));
|
|
2847
|
+
* }
|
|
2848
|
+
* };
|
|
2849
|
+
* ```
|
|
2850
|
+
*/
|
|
1630
2851
|
export interface ParameterizedTest<T> {
|
|
1631
2852
|
test: (name: string, fn: (input: T, expected: unknown) => void | Promise<void>) => void;
|
|
1632
2853
|
}
|
|
2854
|
+
/**
|
|
2855
|
+
* Test suite for service testing.
|
|
2856
|
+
* Provides methods for testing service behavior.
|
|
2857
|
+
*
|
|
2858
|
+
* @template T - Type of service being tested
|
|
2859
|
+
*
|
|
2860
|
+
* @example
|
|
2861
|
+
* ```typescript
|
|
2862
|
+
* const suite: ServiceTestSuite<UserService> = {
|
|
2863
|
+
* testMethods: () => { // test service methods },
|
|
2864
|
+
* testErrorHandling: (scenarios) => { // test error cases }
|
|
2865
|
+
* };
|
|
2866
|
+
* ```
|
|
2867
|
+
*/
|
|
1633
2868
|
export interface ServiceTestSuite<T> {
|
|
1634
2869
|
testMethods: () => void;
|
|
1635
2870
|
testErrorHandling: (errorScenarios: Array<ErrorScenario<T>>) => void;
|
|
1636
2871
|
}
|
|
2872
|
+
/**
|
|
2873
|
+
* Test suite for NestJS applications.
|
|
2874
|
+
* Provides methods for testing providers and injection.
|
|
2875
|
+
*
|
|
2876
|
+
* @example
|
|
2877
|
+
* ```typescript
|
|
2878
|
+
* const suite: NestJSTestSuiteReturn = {
|
|
2879
|
+
* testProviderRegistration: (tokens) => { // test providers },
|
|
2880
|
+
* testProviderInjection: (tests) => { // test DI }
|
|
2881
|
+
* };
|
|
2882
|
+
* ```
|
|
2883
|
+
*/
|
|
1637
2884
|
export interface NestJSTestSuiteReturn {
|
|
1638
2885
|
testProviderRegistration: (providerTokens: unknown[]) => void;
|
|
1639
2886
|
testProviderInjection: (injectionTests: Array<ProviderInjectionTest>) => void;
|
|
1640
2887
|
}
|
|
2888
|
+
/**
|
|
2889
|
+
* Test suite for Next.js pages.
|
|
2890
|
+
* Provides methods for testing SSG, SSR, and rendering.
|
|
2891
|
+
*
|
|
2892
|
+
* @example
|
|
2893
|
+
* ```typescript
|
|
2894
|
+
* const suite: NextJSTestSuite = {
|
|
2895
|
+
* testStaticGeneration: (getStaticProps, getStaticPaths) => { // test SSG },
|
|
2896
|
+
* testServerSideRendering: (getServerSideProps) => { // test SSR },
|
|
2897
|
+
* testPageRendering: (scenarios) => { // test rendering }
|
|
2898
|
+
* };
|
|
2899
|
+
* ```
|
|
2900
|
+
*/
|
|
1641
2901
|
export interface NextJSTestSuite {
|
|
1642
2902
|
testStaticGeneration: (getStaticProps?: Function, getStaticPaths?: Function) => void;
|
|
1643
2903
|
testServerSideRendering: (getServerSideProps?: Function) => void;
|
|
1644
2904
|
testPageRendering: (scenarios: Array<PropsTestScenario>) => void;
|
|
1645
2905
|
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Factory for creating test suites.
|
|
2908
|
+
* Provides methods for various test patterns.
|
|
2909
|
+
*
|
|
2910
|
+
* @template T - Type of object being tested
|
|
2911
|
+
*
|
|
2912
|
+
* @example
|
|
2913
|
+
* ```typescript
|
|
2914
|
+
* const factory: TestSuiteFactory<Calculator> = {
|
|
2915
|
+
* runScenarios: (scenarios) => { // run test scenarios },
|
|
2916
|
+
* testMethod: (method, cases) => { // test specific method },
|
|
2917
|
+
* testLifecycle: (hooks) => { // test lifecycle },
|
|
2918
|
+
* testErrorHandling: (errors) => { // test errors }
|
|
2919
|
+
* };
|
|
2920
|
+
* ```
|
|
2921
|
+
*/
|
|
1646
2922
|
export interface TestSuiteFactory<T extends UnknownRecord> {
|
|
1647
2923
|
runScenarios: (scenarios: TestScenario<T, unknown, unknown>[]) => void;
|
|
1648
2924
|
testMethod: (methodName: keyof T, testCases: Array<TestCaseWithSetup<T>>) => void;
|
|
1649
2925
|
testLifecycle: (lifecycleHooks: Array<LifecycleHookTestConfig<T>>) => void;
|
|
1650
2926
|
testErrorHandling: (errorScenarios: Array<ErrorHandlingScenario<T>>) => void;
|
|
1651
2927
|
}
|
|
2928
|
+
/**
|
|
2929
|
+
* Conditional behavior for mocks.
|
|
2930
|
+
* Returns different results based on predicate.
|
|
2931
|
+
*
|
|
2932
|
+
* @template T - Type of mock return value
|
|
2933
|
+
*
|
|
2934
|
+
* @example
|
|
2935
|
+
* ```typescript
|
|
2936
|
+
* const behavior: ConditionalMockBehavior<string> = {
|
|
2937
|
+
* predicate: (id) => id === 'admin',
|
|
2938
|
+
* result: 'admin-response'
|
|
2939
|
+
* };
|
|
2940
|
+
* ```
|
|
2941
|
+
*/
|
|
1652
2942
|
export interface ConditionalMockBehavior<T> {
|
|
1653
2943
|
predicate: (...args: unknown[]) => boolean;
|
|
1654
2944
|
result: T | (() => T);
|
|
1655
2945
|
}
|
|
2946
|
+
/**
|
|
2947
|
+
* Result from mocking a module.
|
|
2948
|
+
* Provides unmock function for cleanup.
|
|
2949
|
+
*
|
|
2950
|
+
* @example
|
|
2951
|
+
* ```typescript
|
|
2952
|
+
* const mockResult: MockModuleResult = mockModule('fs');
|
|
2953
|
+
* // Use mocked module
|
|
2954
|
+
* mockResult.unmock(); // Restore original
|
|
2955
|
+
* ```
|
|
2956
|
+
*/
|
|
1656
2957
|
export interface MockModuleResult {
|
|
1657
2958
|
unmock: () => void;
|
|
1658
2959
|
}
|
|
2960
|
+
/**
|
|
2961
|
+
* Result from mocking multiple modules.
|
|
2962
|
+
* Provides function to unmock all.
|
|
2963
|
+
*
|
|
2964
|
+
* @example
|
|
2965
|
+
* ```typescript
|
|
2966
|
+
* const result: MockManyResult = mockMany(['fs', 'path']);
|
|
2967
|
+
* // Use mocked modules
|
|
2968
|
+
* result.unmockAll(); // Restore all
|
|
2969
|
+
* ```
|
|
2970
|
+
*/
|
|
1659
2971
|
export interface MockManyResult {
|
|
1660
2972
|
unmockAll: () => void;
|
|
1661
2973
|
}
|
|
2974
|
+
/**
|
|
2975
|
+
* Result from route matching.
|
|
2976
|
+
* Contains extracted params and match status.
|
|
2977
|
+
*
|
|
2978
|
+
* @example
|
|
2979
|
+
* ```typescript
|
|
2980
|
+
* const result: RouteMatchResult = {
|
|
2981
|
+
* params: { id: '123', slug: 'post-title' },
|
|
2982
|
+
* isMatch: true
|
|
2983
|
+
* };
|
|
2984
|
+
* ```
|
|
2985
|
+
*/
|
|
1662
2986
|
export interface RouteMatchResult {
|
|
1663
2987
|
params: Record<string, string | string[]>;
|
|
1664
2988
|
isMatch: boolean;
|
|
1665
2989
|
}
|
|
2990
|
+
/**
|
|
2991
|
+
* Performance entry with metrics.
|
|
2992
|
+
* Contains name and performance data.
|
|
2993
|
+
*
|
|
2994
|
+
* @example
|
|
2995
|
+
* ```typescript
|
|
2996
|
+
* const entry: PerformanceEntryResult = {
|
|
2997
|
+
* name: 'api-call',
|
|
2998
|
+
* metrics: { mean: 50, median: 45, p95: 100 }
|
|
2999
|
+
* };
|
|
3000
|
+
* ```
|
|
3001
|
+
*/
|
|
1666
3002
|
export interface PerformanceEntryResult {
|
|
1667
3003
|
name: string;
|
|
1668
3004
|
metrics: PerformanceMetrics;
|
|
1669
3005
|
}
|
|
3006
|
+
/**
|
|
3007
|
+
* Result from memory measurement.
|
|
3008
|
+
* Contains memory data and function result.
|
|
3009
|
+
*
|
|
3010
|
+
* @template T - Type of function result
|
|
3011
|
+
*
|
|
3012
|
+
* @example
|
|
3013
|
+
* ```typescript
|
|
3014
|
+
* const result: MemoryMeasurementResult<string[]> = {
|
|
3015
|
+
* measurement: { before: 1000, after: 2000, delta: 1000, peak: 2500 },
|
|
3016
|
+
* result: ['item1', 'item2']
|
|
3017
|
+
* };
|
|
3018
|
+
* ```
|
|
3019
|
+
*/
|
|
1670
3020
|
export interface MemoryMeasurementResult<T> {
|
|
1671
3021
|
measurement: MemoryMeasurement;
|
|
1672
3022
|
result: T;
|
|
1673
3023
|
}
|
|
3024
|
+
/**
|
|
3025
|
+
* Global object with garbage collection.
|
|
3026
|
+
* Provides manual GC trigger for testing.
|
|
3027
|
+
*
|
|
3028
|
+
* @example
|
|
3029
|
+
* ```typescript
|
|
3030
|
+
* const global: GlobalWithGC = globalThis as GlobalWithGC;
|
|
3031
|
+
* if (global.gc) {
|
|
3032
|
+
* global.gc(); // Force garbage collection
|
|
3033
|
+
* }
|
|
3034
|
+
* ```
|
|
3035
|
+
*/
|
|
1674
3036
|
export interface GlobalWithGC {
|
|
1675
3037
|
gc?: () => void;
|
|
1676
3038
|
}
|
|
3039
|
+
/**
|
|
3040
|
+
* Result from memory leak testing.
|
|
3041
|
+
* Contains memory usage before and after.
|
|
3042
|
+
*
|
|
3043
|
+
* @example
|
|
3044
|
+
* ```typescript
|
|
3045
|
+
* const result: MemoryLeakTestResult = {
|
|
3046
|
+
* initialMemory: 50000000,
|
|
3047
|
+
* finalMemory: 55000000,
|
|
3048
|
+
* memoryIncrease: 5000000,
|
|
3049
|
+
* iterations: 1000
|
|
3050
|
+
* };
|
|
3051
|
+
* ```
|
|
3052
|
+
*/
|
|
1677
3053
|
export interface MemoryLeakTestResult {
|
|
1678
3054
|
initialMemory: number;
|
|
1679
3055
|
finalMemory: number;
|
|
1680
3056
|
memoryIncrease: number;
|
|
1681
3057
|
iterations: number;
|
|
1682
3058
|
}
|
|
3059
|
+
/**
|
|
3060
|
+
* Property variation for component testing.
|
|
3061
|
+
* Defines props and expected behavior.
|
|
3062
|
+
*
|
|
3063
|
+
* @example
|
|
3064
|
+
* ```typescript
|
|
3065
|
+
* const variation: PropVariation = {
|
|
3066
|
+
* name: 'with loading state',
|
|
3067
|
+
* props: { isLoading: true },
|
|
3068
|
+
* expectation: () => expect(screen.getByTestId('spinner')).toBeVisible()
|
|
3069
|
+
* };
|
|
3070
|
+
* ```
|
|
3071
|
+
*/
|
|
1683
3072
|
export interface PropVariation {
|
|
1684
3073
|
name: string;
|
|
1685
3074
|
props: Record<string, unknown>;
|
|
1686
3075
|
expectation: () => void;
|
|
1687
3076
|
}
|
|
3077
|
+
/**
|
|
3078
|
+
* Valid input test case.
|
|
3079
|
+
* Defines input that should succeed.
|
|
3080
|
+
*
|
|
3081
|
+
* @template T - Type of expected result
|
|
3082
|
+
*
|
|
3083
|
+
* @example
|
|
3084
|
+
* ```typescript
|
|
3085
|
+
* const testCase: ValidTestCase<User> = {
|
|
3086
|
+
* name: 'valid email format',
|
|
3087
|
+
* input: 'user@example.com',
|
|
3088
|
+
* expected: { email: 'user@example.com', valid: true }
|
|
3089
|
+
* };
|
|
3090
|
+
* ```
|
|
3091
|
+
*/
|
|
1688
3092
|
export interface ValidTestCase<T> {
|
|
1689
3093
|
name: string;
|
|
1690
3094
|
input: unknown;
|
|
1691
3095
|
expected?: T;
|
|
1692
3096
|
}
|
|
3097
|
+
/**
|
|
3098
|
+
* Invalid input test case.
|
|
3099
|
+
* Defines input that should fail with error.
|
|
3100
|
+
*
|
|
3101
|
+
* @example
|
|
3102
|
+
* ```typescript
|
|
3103
|
+
* const testCase: InvalidTestCase = {
|
|
3104
|
+
* name: 'invalid email format',
|
|
3105
|
+
* input: 'not-an-email',
|
|
3106
|
+
* expectedError: /Invalid email format/
|
|
3107
|
+
* };
|
|
3108
|
+
* ```
|
|
3109
|
+
*/
|
|
1693
3110
|
export interface InvalidTestCase {
|
|
1694
3111
|
name: string;
|
|
1695
3112
|
input: unknown;
|
|
1696
3113
|
expectedError: string | RegExp;
|
|
1697
3114
|
}
|
|
3115
|
+
/**
|
|
3116
|
+
* Created resource for cleanup tracking.
|
|
3117
|
+
* Stores resource reference and name.
|
|
3118
|
+
*
|
|
3119
|
+
* @example
|
|
3120
|
+
* ```typescript
|
|
3121
|
+
* const resource: CreatedResource = {
|
|
3122
|
+
* name: 'test-database',
|
|
3123
|
+
* resource: dbConnection
|
|
3124
|
+
* };
|
|
3125
|
+
* ```
|
|
3126
|
+
*/
|
|
1698
3127
|
export interface CreatedResource {
|
|
1699
3128
|
name: string;
|
|
1700
3129
|
resource: unknown;
|
|
1701
3130
|
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Record of lifecycle hook execution.
|
|
3133
|
+
* Tracks phase, method, and timestamp.
|
|
3134
|
+
*
|
|
3135
|
+
* @example
|
|
3136
|
+
* ```typescript
|
|
3137
|
+
* const record: LifecycleHookRecord = {
|
|
3138
|
+
* phase: 'mount',
|
|
3139
|
+
* method: 'componentDidMount',
|
|
3140
|
+
* timestamp: Date.now()
|
|
3141
|
+
* };
|
|
3142
|
+
* ```
|
|
3143
|
+
*/
|
|
1702
3144
|
export interface LifecycleHookRecord {
|
|
1703
3145
|
phase: string;
|
|
1704
3146
|
method: string;
|
|
1705
3147
|
timestamp: number;
|
|
1706
3148
|
}
|
|
3149
|
+
/**
|
|
3150
|
+
* Test case for path matching.
|
|
3151
|
+
* Defines path and expected match result.
|
|
3152
|
+
*
|
|
3153
|
+
* @example
|
|
3154
|
+
* ```typescript
|
|
3155
|
+
* const test: PathMatchTest = {
|
|
3156
|
+
* path: '/users/123',
|
|
3157
|
+
* shouldMatch: true
|
|
3158
|
+
* };
|
|
3159
|
+
* ```
|
|
3160
|
+
*/
|
|
1707
3161
|
export interface PathMatchTest {
|
|
1708
3162
|
path: string;
|
|
1709
3163
|
shouldMatch: boolean;
|
|
1710
3164
|
}
|
|
3165
|
+
/**
|
|
3166
|
+
* Error scenario for service testing.
|
|
3167
|
+
* Defines setup and expected error.
|
|
3168
|
+
*
|
|
3169
|
+
* @template T - Type of service being tested
|
|
3170
|
+
*
|
|
3171
|
+
* @example
|
|
3172
|
+
* ```typescript
|
|
3173
|
+
* const scenario: ErrorScenario<UserService> = {
|
|
3174
|
+
* method: 'createUser',
|
|
3175
|
+
* setup: (service) => vi.spyOn(db, 'save').mockRejectedValue(new Error()),
|
|
3176
|
+
* expectedError: 'Database error'
|
|
3177
|
+
* };
|
|
3178
|
+
* ```
|
|
3179
|
+
*/
|
|
1711
3180
|
export interface ErrorScenario<T> {
|
|
1712
3181
|
method: string;
|
|
1713
3182
|
setup: (service: T) => void;
|
|
1714
3183
|
expectedError: unknown;
|
|
1715
3184
|
}
|
|
3185
|
+
/**
|
|
3186
|
+
* Test scenario for component props.
|
|
3187
|
+
* Defines props and expected content.
|
|
3188
|
+
*
|
|
3189
|
+
* @example
|
|
3190
|
+
* ```typescript
|
|
3191
|
+
* const scenario: PropsTestScenario = {
|
|
3192
|
+
* props: { title: 'Hello', isActive: true },
|
|
3193
|
+
* expectedContent: 'Hello - Active'
|
|
3194
|
+
* };
|
|
3195
|
+
* ```
|
|
3196
|
+
*/
|
|
1716
3197
|
export interface PropsTestScenario {
|
|
1717
3198
|
props: Record<string, unknown>;
|
|
1718
3199
|
expectedContent?: string;
|
|
1719
3200
|
}
|
|
3201
|
+
/**
|
|
3202
|
+
* Responsive breakpoint test configuration.
|
|
3203
|
+
* Defines viewport size and expectations.
|
|
3204
|
+
*
|
|
3205
|
+
* @example
|
|
3206
|
+
* ```typescript
|
|
3207
|
+
* const breakpoint: ResponsiveBreakpoint = {
|
|
3208
|
+
* width: 768,
|
|
3209
|
+
* height: 1024,
|
|
3210
|
+
* expectations: () => {
|
|
3211
|
+
* expect(screen.getByTestId('mobile-menu')).toBeVisible();
|
|
3212
|
+
* }
|
|
3213
|
+
* };
|
|
3214
|
+
* ```
|
|
3215
|
+
*/
|
|
1720
3216
|
export interface ResponsiveBreakpoint {
|
|
1721
3217
|
width: number;
|
|
1722
3218
|
height: number;
|
|
@@ -1725,6 +3221,18 @@ export interface ResponsiveBreakpoint {
|
|
|
1725
3221
|
export type TestCombination<T extends Record<string, unknown[]>> = {
|
|
1726
3222
|
[K in keyof T]: T[K][number];
|
|
1727
3223
|
};
|
|
3224
|
+
/**
|
|
3225
|
+
* Test dependency configuration.
|
|
3226
|
+
* Maps token to test value.
|
|
3227
|
+
*
|
|
3228
|
+
* @example
|
|
3229
|
+
* ```typescript
|
|
3230
|
+
* const dependency: TestDependency = {
|
|
3231
|
+
* token: DatabaseService,
|
|
3232
|
+
* value: mockDatabaseService
|
|
3233
|
+
* };
|
|
3234
|
+
* ```
|
|
3235
|
+
*/
|
|
1728
3236
|
export interface TestDependency {
|
|
1729
3237
|
token: unknown;
|
|
1730
3238
|
value: unknown;
|
|
@@ -1763,12 +3271,43 @@ export interface TableTestCase<TInput, TExpected> {
|
|
|
1763
3271
|
only?: boolean;
|
|
1764
3272
|
error?: boolean;
|
|
1765
3273
|
}
|
|
3274
|
+
/**
|
|
3275
|
+
* Edge case test definition.
|
|
3276
|
+
* Tests boundary conditions and edge cases.
|
|
3277
|
+
*
|
|
3278
|
+
* @template T - Type of input
|
|
3279
|
+
* @template R - Type of expected result
|
|
3280
|
+
*
|
|
3281
|
+
* @example
|
|
3282
|
+
* ```typescript
|
|
3283
|
+
* const test: EdgeCaseTest<number, string> = {
|
|
3284
|
+
* name: 'handles MAX_SAFE_INTEGER',
|
|
3285
|
+
* input: Number.MAX_SAFE_INTEGER,
|
|
3286
|
+
* expected: '9007199254740991'
|
|
3287
|
+
* };
|
|
3288
|
+
* ```
|
|
3289
|
+
*/
|
|
1766
3290
|
export interface EdgeCaseTest<T, R> {
|
|
1767
3291
|
name: string;
|
|
1768
3292
|
input: T;
|
|
1769
3293
|
expected?: R;
|
|
1770
3294
|
shouldThrow?: string | RegExp | Error;
|
|
1771
3295
|
}
|
|
3296
|
+
/**
|
|
3297
|
+
* Metrics for animation performance.
|
|
3298
|
+
* Contains frame time statistics.
|
|
3299
|
+
*
|
|
3300
|
+
* @example
|
|
3301
|
+
* ```typescript
|
|
3302
|
+
* const metrics: AnimationPerformanceMetrics = {
|
|
3303
|
+
* avgFrameTime: 16.67,
|
|
3304
|
+
* avgFPS: 60,
|
|
3305
|
+
* maxFrameTime: 33,
|
|
3306
|
+
* minFrameTime: 8,
|
|
3307
|
+
* frameTimes: [16, 17, 16, 33, 8]
|
|
3308
|
+
* };
|
|
3309
|
+
* ```
|
|
3310
|
+
*/
|
|
1772
3311
|
export interface AnimationPerformanceMetrics {
|
|
1773
3312
|
avgFrameTime: number;
|
|
1774
3313
|
avgFPS: number;
|
|
@@ -1776,6 +3315,19 @@ export interface AnimationPerformanceMetrics {
|
|
|
1776
3315
|
minFrameTime: number;
|
|
1777
3316
|
frameTimes: number[];
|
|
1778
3317
|
}
|
|
3318
|
+
/**
|
|
3319
|
+
* Options for animation performance testing.
|
|
3320
|
+
* Configures iterations and thresholds.
|
|
3321
|
+
*
|
|
3322
|
+
* @example
|
|
3323
|
+
* ```typescript
|
|
3324
|
+
* const options: AnimationPerformanceOptions = {
|
|
3325
|
+
* iterations: 100,
|
|
3326
|
+
* maxFrameTime: 33, // 30 FPS minimum
|
|
3327
|
+
* minFPS: 30
|
|
3328
|
+
* };
|
|
3329
|
+
* ```
|
|
3330
|
+
*/
|
|
1779
3331
|
export interface AnimationPerformanceOptions {
|
|
1780
3332
|
iterations?: number;
|
|
1781
3333
|
maxFrameTime?: number;
|
|
@@ -1796,6 +3348,23 @@ export type StaticPropsResult<T> = {
|
|
|
1796
3348
|
} | {
|
|
1797
3349
|
notFound: true;
|
|
1798
3350
|
};
|
|
3351
|
+
/**
|
|
3352
|
+
* Test result for getServerSideProps.
|
|
3353
|
+
* Contains result and assertion helpers.
|
|
3354
|
+
*
|
|
3355
|
+
* @template T - Type of props
|
|
3356
|
+
*
|
|
3357
|
+
* @example
|
|
3358
|
+
* ```typescript
|
|
3359
|
+
* const result: ServerSidePropsTestResult<PageProps> = {
|
|
3360
|
+
* result: { props: { user: { id: 1 } } },
|
|
3361
|
+
* context: mockContext,
|
|
3362
|
+
* expectProps: (props) => expect(props).toMatchObject({ user: { id: 1 } }),
|
|
3363
|
+
* expectRedirect: (dest) => expect(result.redirect).toBe(dest),
|
|
3364
|
+
* expectNotFound: () => expect(result.notFound).toBe(true)
|
|
3365
|
+
* };
|
|
3366
|
+
* ```
|
|
3367
|
+
*/
|
|
1799
3368
|
export interface ServerSidePropsTestResult<T> {
|
|
1800
3369
|
result: ServerSidePropsResult<T>;
|
|
1801
3370
|
context: MockGetServerSidePropsContext;
|
|
@@ -1803,6 +3372,23 @@ export interface ServerSidePropsTestResult<T> {
|
|
|
1803
3372
|
expectRedirect: (destination: string, permanent?: boolean) => void;
|
|
1804
3373
|
expectNotFound: () => void;
|
|
1805
3374
|
}
|
|
3375
|
+
/**
|
|
3376
|
+
* Test result for getStaticProps.
|
|
3377
|
+
* Contains result and assertion helpers.
|
|
3378
|
+
*
|
|
3379
|
+
* @template T - Type of props
|
|
3380
|
+
*
|
|
3381
|
+
* @example
|
|
3382
|
+
* ```typescript
|
|
3383
|
+
* const result: StaticPropsTestResult<PageProps> = {
|
|
3384
|
+
* result: { props: { posts: [] }, revalidate: 60 },
|
|
3385
|
+
* context: mockContext,
|
|
3386
|
+
* expectProps: (props) => expect(props.posts).toHaveLength(0),
|
|
3387
|
+
* expectRevalidate: (seconds) => expect(result.revalidate).toBe(seconds),
|
|
3388
|
+
* expectNotFound: () => expect(result.notFound).toBe(true)
|
|
3389
|
+
* };
|
|
3390
|
+
* ```
|
|
3391
|
+
*/
|
|
1806
3392
|
export interface StaticPropsTestResult<T> {
|
|
1807
3393
|
result: StaticPropsResult<T>;
|
|
1808
3394
|
context: MockGetStaticPropsContext;
|
|
@@ -1811,27 +3397,103 @@ export interface StaticPropsTestResult<T> {
|
|
|
1811
3397
|
expectNotFound: () => void;
|
|
1812
3398
|
expectRevalidate: (seconds: number) => void;
|
|
1813
3399
|
}
|
|
3400
|
+
/**
|
|
3401
|
+
* Custom query methods for testing.
|
|
3402
|
+
* Provides additional DOM query functions.
|
|
3403
|
+
*
|
|
3404
|
+
* @example
|
|
3405
|
+
* ```typescript
|
|
3406
|
+
* const queries: CreateCustomQueriesReturn = {
|
|
3407
|
+
* getByClassName: (name) => container.querySelector(`.${name}`),
|
|
3408
|
+
* getAllByClassName: (name) => Array.from(container.querySelectorAll(`.${name}`)),
|
|
3409
|
+
* getByAttribute: (attr, value) => container.querySelector(`[${attr}="${value}"]`)
|
|
3410
|
+
* };
|
|
3411
|
+
* ```
|
|
3412
|
+
*/
|
|
1814
3413
|
export interface CreateCustomQueriesReturn {
|
|
1815
3414
|
getByClassName: (className: string) => HTMLElement;
|
|
1816
3415
|
getAllByClassName: (className: string) => HTMLElement[];
|
|
1817
3416
|
getByAttribute: (attribute: string, value?: string) => HTMLElement;
|
|
1818
3417
|
}
|
|
3418
|
+
/**
|
|
3419
|
+
* Boundary value test case.
|
|
3420
|
+
* Tests edge values and boundaries.
|
|
3421
|
+
*
|
|
3422
|
+
* @template T - Type of boundary value
|
|
3423
|
+
*
|
|
3424
|
+
* @example
|
|
3425
|
+
* ```typescript
|
|
3426
|
+
* const test: BoundaryValueTest<number> = {
|
|
3427
|
+
* value: 0,
|
|
3428
|
+
* description: 'minimum value',
|
|
3429
|
+
* expected: 'zero'
|
|
3430
|
+
* };
|
|
3431
|
+
* ```
|
|
3432
|
+
*/
|
|
1819
3433
|
export interface BoundaryValueTest<T> {
|
|
1820
3434
|
value: T;
|
|
1821
3435
|
description: string;
|
|
1822
3436
|
expected: unknown;
|
|
1823
3437
|
}
|
|
3438
|
+
/**
|
|
3439
|
+
* Equivalence class test case.
|
|
3440
|
+
* Tests multiple inputs with same expected result.
|
|
3441
|
+
*
|
|
3442
|
+
* @template T - Type of input samples
|
|
3443
|
+
* @template R - Type of expected result
|
|
3444
|
+
*
|
|
3445
|
+
* @example
|
|
3446
|
+
* ```typescript
|
|
3447
|
+
* const test: EquivalenceClassTest<string, boolean> = {
|
|
3448
|
+
* name: 'valid emails',
|
|
3449
|
+
* samples: ['user@example.com', 'test@domain.org'],
|
|
3450
|
+
* expected: true
|
|
3451
|
+
* };
|
|
3452
|
+
* ```
|
|
3453
|
+
*/
|
|
1824
3454
|
export interface EquivalenceClassTest<T, R> {
|
|
1825
3455
|
name: string;
|
|
1826
3456
|
samples: T[];
|
|
1827
3457
|
expected: R;
|
|
1828
3458
|
}
|
|
3459
|
+
/**
|
|
3460
|
+
* State transition test case.
|
|
3461
|
+
* Defines state change from action.
|
|
3462
|
+
*
|
|
3463
|
+
* @template TState - Type of state
|
|
3464
|
+
* @template TAction - Type of action
|
|
3465
|
+
*
|
|
3466
|
+
* @example
|
|
3467
|
+
* ```typescript
|
|
3468
|
+
* const test: StateTransitionTest<LoadingState, Action> = {
|
|
3469
|
+
* from: { status: 'idle' },
|
|
3470
|
+
* action: { type: 'FETCH_START' },
|
|
3471
|
+
* to: { status: 'loading' },
|
|
3472
|
+
* description: 'starts loading on fetch'
|
|
3473
|
+
* };
|
|
3474
|
+
* ```
|
|
3475
|
+
*/
|
|
1829
3476
|
export interface StateTransitionTest<TState, TAction> {
|
|
1830
3477
|
from: TState;
|
|
1831
3478
|
action: TAction;
|
|
1832
3479
|
to: TState;
|
|
1833
3480
|
description?: string;
|
|
1834
3481
|
}
|
|
3482
|
+
/**
|
|
3483
|
+
* Snapshot test case configuration.
|
|
3484
|
+
* Defines input for snapshot testing.
|
|
3485
|
+
*
|
|
3486
|
+
* @template T - Type of input
|
|
3487
|
+
*
|
|
3488
|
+
* @example
|
|
3489
|
+
* ```typescript
|
|
3490
|
+
* const test: SnapshotTestCase<ComponentProps> = {
|
|
3491
|
+
* name: 'default state',
|
|
3492
|
+
* input: { title: 'Test', isActive: false },
|
|
3493
|
+
* transform: (input) => renderComponent(input)
|
|
3494
|
+
* };
|
|
3495
|
+
* ```
|
|
3496
|
+
*/
|
|
1835
3497
|
export interface SnapshotTestCase<T> {
|
|
1836
3498
|
name: string;
|
|
1837
3499
|
input: T;
|
|
@@ -2035,9 +3697,38 @@ export interface ServerComponentTestScenario {
|
|
|
2035
3697
|
params?: Record<string, string>;
|
|
2036
3698
|
expectedContent?: string | RegExp;
|
|
2037
3699
|
}
|
|
3700
|
+
/**
|
|
3701
|
+
* Configuration for middleware path matching.
|
|
3702
|
+
* Defines which paths the middleware applies to.
|
|
3703
|
+
*
|
|
3704
|
+
* @example
|
|
3705
|
+
* ```typescript
|
|
3706
|
+
* const config: MiddlewareMatcherConfig = {
|
|
3707
|
+
* matcher: ['/api/:path*', '/admin/:path*']
|
|
3708
|
+
* };
|
|
3709
|
+
* ```
|
|
3710
|
+
*/
|
|
2038
3711
|
export interface MiddlewareMatcherConfig {
|
|
2039
3712
|
matcher: string | string[];
|
|
2040
3713
|
}
|
|
3714
|
+
/**
|
|
3715
|
+
* Result from mocking Next.js navigation.
|
|
3716
|
+
* Contains navigation methods and restore function.
|
|
3717
|
+
*
|
|
3718
|
+
* @example
|
|
3719
|
+
* ```typescript
|
|
3720
|
+
* const mockNav: MockNextNavigationResult = {
|
|
3721
|
+
* navigation: {
|
|
3722
|
+
* push: vi.fn(),
|
|
3723
|
+
* replace: vi.fn(),
|
|
3724
|
+
* refresh: vi.fn(),
|
|
3725
|
+
* back: vi.fn(),
|
|
3726
|
+
* forward: vi.fn()
|
|
3727
|
+
* },
|
|
3728
|
+
* restore: () => { // restore original }
|
|
3729
|
+
* };
|
|
3730
|
+
* ```
|
|
3731
|
+
*/
|
|
2041
3732
|
export interface MockNextNavigationResult {
|
|
2042
3733
|
navigation: {
|
|
2043
3734
|
push: ReturnType<typeof Vitest.vi.fn>;
|
|
@@ -2048,35 +3739,126 @@ export interface MockNextNavigationResult {
|
|
|
2048
3739
|
};
|
|
2049
3740
|
restore: () => void;
|
|
2050
3741
|
}
|
|
3742
|
+
/**
|
|
3743
|
+
* Options for creating test harness.
|
|
3744
|
+
* Configures instance creation and dependencies.
|
|
3745
|
+
*
|
|
3746
|
+
* @template TOptions - Type of options for creation
|
|
3747
|
+
*
|
|
3748
|
+
* @example
|
|
3749
|
+
* ```typescript
|
|
3750
|
+
* const options: TestHarnessOptions<ServiceOptions> = {
|
|
3751
|
+
* create: (deps, opts) => new Service(deps, opts),
|
|
3752
|
+
* dependencies: [{ token: 'DB', value: mockDb }]
|
|
3753
|
+
* };
|
|
3754
|
+
* ```
|
|
3755
|
+
*/
|
|
2051
3756
|
export interface TestHarnessOptions<TOptions> {
|
|
2052
3757
|
create: (deps: Map<unknown, unknown>, opts: TOptions) => unknown;
|
|
2053
3758
|
dependencies?: Array<TestDependency>;
|
|
2054
3759
|
}
|
|
3760
|
+
/**
|
|
3761
|
+
* Result from test harness creation.
|
|
3762
|
+
* Contains instance and helper methods.
|
|
3763
|
+
*
|
|
3764
|
+
* @template T - Type of instance created
|
|
3765
|
+
*
|
|
3766
|
+
* @example
|
|
3767
|
+
* ```typescript
|
|
3768
|
+
* const harness: TestHarnessResult<UserService> = {
|
|
3769
|
+
* instance: userService,
|
|
3770
|
+
* dependencies: new Map(),
|
|
3771
|
+
* logger: mockLogger,
|
|
3772
|
+
* getDependency: (token) => dependencies.get(token)
|
|
3773
|
+
* };
|
|
3774
|
+
* ```
|
|
3775
|
+
*/
|
|
2055
3776
|
export interface TestHarnessResult<T> {
|
|
2056
3777
|
instance: T;
|
|
2057
3778
|
dependencies: Map<unknown, unknown>;
|
|
2058
3779
|
logger?: unknown;
|
|
2059
3780
|
getDependency: <U>(token: unknown) => U;
|
|
2060
3781
|
}
|
|
3782
|
+
/**
|
|
3783
|
+
* Options for mocking console methods.
|
|
3784
|
+
* Controls which console methods to suppress.
|
|
3785
|
+
*
|
|
3786
|
+
* @example
|
|
3787
|
+
* ```typescript
|
|
3788
|
+
* const options: ConsoleMockOptions = {
|
|
3789
|
+
* suppressAll: false,
|
|
3790
|
+
* suppress: ['log', 'debug']
|
|
3791
|
+
* };
|
|
3792
|
+
* ```
|
|
3793
|
+
*/
|
|
2061
3794
|
export interface ConsoleMockOptions {
|
|
2062
3795
|
suppressAll?: boolean;
|
|
2063
3796
|
suppress?: Array<'log' | 'error' | 'warn' | 'info' | 'debug'>;
|
|
2064
3797
|
}
|
|
2065
3798
|
export type ConsoleMethod = 'log' | 'error' | 'warn' | 'info' | 'debug';
|
|
3799
|
+
/**
|
|
3800
|
+
* Result from hook error handling.
|
|
3801
|
+
* Contains error information if present.
|
|
3802
|
+
*
|
|
3803
|
+
* @example
|
|
3804
|
+
* ```typescript
|
|
3805
|
+
* const result: HookErrorResult = {
|
|
3806
|
+
* error: { message: 'Hook failed to initialize' }
|
|
3807
|
+
* };
|
|
3808
|
+
* ```
|
|
3809
|
+
*/
|
|
2066
3810
|
export interface HookErrorResult {
|
|
2067
3811
|
error?: {
|
|
2068
3812
|
message: string;
|
|
2069
3813
|
};
|
|
2070
3814
|
}
|
|
3815
|
+
/**
|
|
3816
|
+
* Component with loading state property.
|
|
3817
|
+
* Used for testing loading behavior.
|
|
3818
|
+
*
|
|
3819
|
+
* @example
|
|
3820
|
+
* ```typescript
|
|
3821
|
+
* const component: ComponentWithLoading = {
|
|
3822
|
+
* isLoading: true,
|
|
3823
|
+
* data: null,
|
|
3824
|
+
* error: null
|
|
3825
|
+
* };
|
|
3826
|
+
* ```
|
|
3827
|
+
*/
|
|
2071
3828
|
export interface ComponentWithLoading {
|
|
2072
3829
|
isLoading?: boolean;
|
|
2073
3830
|
[key: string]: unknown;
|
|
2074
3831
|
}
|
|
3832
|
+
/**
|
|
3833
|
+
* Test for conditional rendering logic.
|
|
3834
|
+
* Defines what should and shouldn't render.
|
|
3835
|
+
*
|
|
3836
|
+
* @example
|
|
3837
|
+
* ```typescript
|
|
3838
|
+
* const test: ConditionalRenderingTest = {
|
|
3839
|
+
* props: { isLoggedIn: true, isPremium: false },
|
|
3840
|
+
* shouldRender: ['user-menu', 'logout-button'],
|
|
3841
|
+
* shouldNotRender: ['login-form', 'premium-features']
|
|
3842
|
+
* };
|
|
3843
|
+
* ```
|
|
3844
|
+
*/
|
|
2075
3845
|
export interface ConditionalRenderingTest {
|
|
2076
3846
|
props: Record<string, unknown>;
|
|
2077
3847
|
shouldRender: string[];
|
|
2078
3848
|
shouldNotRender: string[];
|
|
2079
3849
|
}
|
|
3850
|
+
/**
|
|
3851
|
+
* Configuration for React context provider.
|
|
3852
|
+
* Defines provider component and props.
|
|
3853
|
+
*
|
|
3854
|
+
* @example
|
|
3855
|
+
* ```typescript
|
|
3856
|
+
* const config: ProviderConfig = {
|
|
3857
|
+
* Provider: ThemeProvider,
|
|
3858
|
+
* props: { theme: 'dark', primaryColor: '#007bff' }
|
|
3859
|
+
* };
|
|
3860
|
+
* ```
|
|
3861
|
+
*/
|
|
2080
3862
|
export interface ProviderConfig {
|
|
2081
3863
|
Provider: React.ComponentType<{
|
|
2082
3864
|
children: React.ReactNode;
|
|
@@ -2084,27 +3866,93 @@ export interface ProviderConfig {
|
|
|
2084
3866
|
}>;
|
|
2085
3867
|
props?: Record<string, unknown>;
|
|
2086
3868
|
}
|
|
3869
|
+
/**
|
|
3870
|
+
* Test case for user interactions.
|
|
3871
|
+
* Defines action and expected result.
|
|
3872
|
+
*
|
|
3873
|
+
* @example
|
|
3874
|
+
* ```typescript
|
|
3875
|
+
* const test: UserInteractionTest = {
|
|
3876
|
+
* name: 'submits form on button click',
|
|
3877
|
+
* action: async (user) => await user.click(submitButton),
|
|
3878
|
+
* expectation: () => expect(onSubmit).toHaveBeenCalled()
|
|
3879
|
+
* };
|
|
3880
|
+
* ```
|
|
3881
|
+
*/
|
|
2087
3882
|
export interface UserInteractionTest {
|
|
2088
3883
|
name: string;
|
|
2089
3884
|
action: (user: unknown) => Promise<void>;
|
|
2090
3885
|
expectation: () => void;
|
|
2091
3886
|
}
|
|
3887
|
+
/**
|
|
3888
|
+
* Test for error boundary behavior.
|
|
3889
|
+
* Validates error handling and recovery.
|
|
3890
|
+
*
|
|
3891
|
+
* @example
|
|
3892
|
+
* ```typescript
|
|
3893
|
+
* const test: ErrorBoundaryTest = {
|
|
3894
|
+
* error: new Error('Component crashed'),
|
|
3895
|
+
* expectedMessage: 'Something went wrong',
|
|
3896
|
+
* shouldHaveReset: true
|
|
3897
|
+
* };
|
|
3898
|
+
* ```
|
|
3899
|
+
*/
|
|
2092
3900
|
export interface ErrorBoundaryTest {
|
|
2093
3901
|
error: Error;
|
|
2094
3902
|
expectedMessage?: string;
|
|
2095
3903
|
shouldHaveReset?: boolean;
|
|
2096
3904
|
}
|
|
3905
|
+
/**
|
|
3906
|
+
* Result from component test suite.
|
|
3907
|
+
* Provides methods for various test types.
|
|
3908
|
+
*
|
|
3909
|
+
* @example
|
|
3910
|
+
* ```typescript
|
|
3911
|
+
* const suite: ComponentTestSuiteResult = {
|
|
3912
|
+
* testRendering: () => { rendering tests },
|
|
3913
|
+
* testUserInteractions: (interactions) => { interaction tests },
|
|
3914
|
+
* testProps: (variations) => { prop tests }
|
|
3915
|
+
* };
|
|
3916
|
+
* ```
|
|
3917
|
+
*/
|
|
2097
3918
|
export interface ComponentTestSuiteResult {
|
|
2098
3919
|
testRendering: () => void;
|
|
2099
3920
|
testUserInteractions: (interactions: Array<UserInteractionTest>) => void;
|
|
2100
3921
|
testProps: (propVariations: Array<PropVariation>) => void;
|
|
2101
3922
|
}
|
|
3923
|
+
/**
|
|
3924
|
+
* Test for resource cleanup behavior.
|
|
3925
|
+
* Validates proper resource disposal.
|
|
3926
|
+
*
|
|
3927
|
+
* @example
|
|
3928
|
+
* ```typescript
|
|
3929
|
+
* const test: ResourceCleanupTest = {
|
|
3930
|
+
* name: 'database connection cleanup',
|
|
3931
|
+
* create: () => db.connect(),
|
|
3932
|
+
* cleanup: async (conn) => await conn.close(),
|
|
3933
|
+
* isCleanedUp: (conn) => conn.isClosed()
|
|
3934
|
+
* };
|
|
3935
|
+
* ```
|
|
3936
|
+
*/
|
|
2102
3937
|
export interface ResourceCleanupTest {
|
|
2103
3938
|
name: string;
|
|
2104
3939
|
create: () => unknown;
|
|
2105
3940
|
cleanup: (resource: unknown) => Promise<void> | void;
|
|
2106
3941
|
isCleanedUp: (resource: unknown) => boolean;
|
|
2107
3942
|
}
|
|
3943
|
+
/**
|
|
3944
|
+
* Container for dependency injection.
|
|
3945
|
+
* Manages service registration and resolution.
|
|
3946
|
+
*
|
|
3947
|
+
* @example
|
|
3948
|
+
* ```typescript
|
|
3949
|
+
* const container: DependencyInjectionContainer = {
|
|
3950
|
+
* register: (token, factory, options) => { // register service },
|
|
3951
|
+
* resolve: (token) => { // resolve service },
|
|
3952
|
+
* dispose: async () => { // cleanup all services }
|
|
3953
|
+
* };
|
|
3954
|
+
* ```
|
|
3955
|
+
*/
|
|
2108
3956
|
export interface DependencyInjectionContainer {
|
|
2109
3957
|
register: (token: unknown, factory: () => unknown, options: {
|
|
2110
3958
|
lifecycle: 'singleton' | 'transient' | 'scoped';
|
|
@@ -2113,6 +3961,21 @@ export interface DependencyInjectionContainer {
|
|
|
2113
3961
|
resolve: (token: unknown) => unknown;
|
|
2114
3962
|
dispose: () => Promise<void>;
|
|
2115
3963
|
}
|
|
3964
|
+
/**
|
|
3965
|
+
* Configuration for dependency injection.
|
|
3966
|
+
* Defines service registration details.
|
|
3967
|
+
*
|
|
3968
|
+
* @example
|
|
3969
|
+
* ```typescript
|
|
3970
|
+
* const config: DependencyInjectionConfig = {
|
|
3971
|
+
* token: UserService,
|
|
3972
|
+
* factory: () => new UserService(db),
|
|
3973
|
+
* dependencies: [DatabaseService],
|
|
3974
|
+
* lifecycle: 'singleton',
|
|
3975
|
+
* cleanup: (instance) => instance.dispose()
|
|
3976
|
+
* };
|
|
3977
|
+
* ```
|
|
3978
|
+
*/
|
|
2116
3979
|
export interface DependencyInjectionConfig {
|
|
2117
3980
|
token: unknown;
|
|
2118
3981
|
factory: () => unknown;
|
|
@@ -2120,6 +3983,21 @@ export interface DependencyInjectionConfig {
|
|
|
2120
3983
|
lifecycle: 'singleton' | 'transient' | 'scoped';
|
|
2121
3984
|
cleanup?: (instance: unknown) => void;
|
|
2122
3985
|
}
|
|
3986
|
+
/**
|
|
3987
|
+
* Async lifecycle hook configuration.
|
|
3988
|
+
* Defines async hook behavior and timing.
|
|
3989
|
+
*
|
|
3990
|
+
* @example
|
|
3991
|
+
* ```typescript
|
|
3992
|
+
* const hook: AsyncLifecycleHook = {
|
|
3993
|
+
* name: 'onModuleInit',
|
|
3994
|
+
* method: 'initialize',
|
|
3995
|
+
* timeout: 5000,
|
|
3996
|
+
* shouldReject: false,
|
|
3997
|
+
* expectedError: undefined
|
|
3998
|
+
* };
|
|
3999
|
+
* ```
|
|
4000
|
+
*/
|
|
2123
4001
|
export interface AsyncLifecycleHook {
|
|
2124
4002
|
name: string;
|
|
2125
4003
|
method: string;
|
|
@@ -2127,6 +4005,25 @@ export interface AsyncLifecycleHook {
|
|
|
2127
4005
|
shouldReject?: boolean;
|
|
2128
4006
|
expectedError?: string | RegExp;
|
|
2129
4007
|
}
|
|
4008
|
+
/**
|
|
4009
|
+
* Result from lifecycle test harness.
|
|
4010
|
+
* Provides lifecycle tracking methods.
|
|
4011
|
+
*
|
|
4012
|
+
* @template T - Type of instance being tested
|
|
4013
|
+
*
|
|
4014
|
+
* @example
|
|
4015
|
+
* ```typescript
|
|
4016
|
+
* const harness: LifecycleTestHarnessResult<Service> = {
|
|
4017
|
+
* instance: service,
|
|
4018
|
+
* getHooks: () => recordedHooks,
|
|
4019
|
+
* clearHooks: () => { recordedHooks = []; },
|
|
4020
|
+
* getHooksByPhase: (phase) => recordedHooks.filter(h => h.phase === phase),
|
|
4021
|
+
* getLastHook: () => recordedHooks[recordedHooks.length - 1],
|
|
4022
|
+
* expectHookCalled: (method) => expect(recordedHooks).toContainEqual({ method }),
|
|
4023
|
+
* expectHookOrder: (order) => expect(recordedHooks.map(h => h.method)).toEqual(order)
|
|
4024
|
+
* };
|
|
4025
|
+
* ```
|
|
4026
|
+
*/
|
|
2130
4027
|
export interface LifecycleTestHarnessResult<T> {
|
|
2131
4028
|
instance: T;
|
|
2132
4029
|
getHooks: () => Array<LifecycleHookRecord>;
|
|
@@ -2136,14 +4033,52 @@ export interface LifecycleTestHarnessResult<T> {
|
|
|
2136
4033
|
expectHookCalled: (method: string) => void;
|
|
2137
4034
|
expectHookOrder: (expectedOrder: string[]) => void;
|
|
2138
4035
|
}
|
|
4036
|
+
/**
|
|
4037
|
+
* Options for graceful shutdown testing.
|
|
4038
|
+
* Configures shutdown behavior and expectations.
|
|
4039
|
+
*
|
|
4040
|
+
* @example
|
|
4041
|
+
* ```typescript
|
|
4042
|
+
* const options: GracefulShutdownOptions = {
|
|
4043
|
+
* shutdownTimeout: 10000,
|
|
4044
|
+
* signals: ['SIGTERM', 'SIGINT'],
|
|
4045
|
+
* expectedCleanupActions: ['close-db', 'stop-server', 'flush-cache']
|
|
4046
|
+
* };
|
|
4047
|
+
* ```
|
|
4048
|
+
*/
|
|
2139
4049
|
export interface GracefulShutdownOptions {
|
|
2140
4050
|
shutdownTimeout?: number;
|
|
2141
4051
|
signals?: globalThis.NodeJS.Signals[];
|
|
2142
4052
|
expectedCleanupActions?: string[];
|
|
2143
4053
|
}
|
|
4054
|
+
/**
|
|
4055
|
+
* Cleanup function for React hooks.
|
|
4056
|
+
* Provides unmount method.
|
|
4057
|
+
*
|
|
4058
|
+
* @example
|
|
4059
|
+
* ```typescript
|
|
4060
|
+
* const cleanup: HookCleanupFunction = {
|
|
4061
|
+
* unmount: () => { // cleanup hook }
|
|
4062
|
+
* };
|
|
4063
|
+
* ```
|
|
4064
|
+
*/
|
|
2144
4065
|
export interface HookCleanupFunction {
|
|
2145
4066
|
unmount: () => void;
|
|
2146
4067
|
}
|
|
4068
|
+
/**
|
|
4069
|
+
* Mock IntersectionObserver entry.
|
|
4070
|
+
* Simulates intersection observer behavior.
|
|
4071
|
+
*
|
|
4072
|
+
* @example
|
|
4073
|
+
* ```typescript
|
|
4074
|
+
* const entry: MockIntersectionObserverEntry = {
|
|
4075
|
+
* target: element,
|
|
4076
|
+
* isIntersecting: true,
|
|
4077
|
+
* intersectionRatio: 0.75,
|
|
4078
|
+
* boundingClientRect: element.getBoundingClientRect()
|
|
4079
|
+
* };
|
|
4080
|
+
* ```
|
|
4081
|
+
*/
|
|
2147
4082
|
export interface MockIntersectionObserverEntry {
|
|
2148
4083
|
target: Element;
|
|
2149
4084
|
isIntersecting: boolean;
|
|
@@ -2171,24 +4106,85 @@ export type PropertyTestFunction<T> = (value: T) => boolean | Promise<boolean>;
|
|
|
2171
4106
|
export type StateTransitionApplyFunction<TState, TAction> = (state: TState, action: TAction) => TState;
|
|
2172
4107
|
export type CombinationTestFunction<T extends Record<string, unknown[]>> = (combination: TestCombination<T>) => void | Promise<void>;
|
|
2173
4108
|
export type UnknownFunction = (...args: unknown[]) => unknown;
|
|
4109
|
+
/**
|
|
4110
|
+
* Configuration for spy target.
|
|
4111
|
+
* Defines object, method, and implementation.
|
|
4112
|
+
*
|
|
4113
|
+
* @example
|
|
4114
|
+
* ```typescript
|
|
4115
|
+
* const config: SpyTargetConfig = {
|
|
4116
|
+
* obj: userService,
|
|
4117
|
+
* method: 'findUser',
|
|
4118
|
+
* implementation: () => ({ id: 1, name: 'Test' })
|
|
4119
|
+
* };
|
|
4120
|
+
* ```
|
|
4121
|
+
*/
|
|
2174
4122
|
export interface SpyTargetConfig {
|
|
2175
4123
|
obj: UnknownRecord;
|
|
2176
4124
|
method: string;
|
|
2177
4125
|
implementation?: UnknownFunction;
|
|
2178
4126
|
}
|
|
2179
4127
|
export type ModuleMockFactories = Record<string, () => UnknownRecord>;
|
|
4128
|
+
/**
|
|
4129
|
+
* Test case with setup function.
|
|
4130
|
+
* Allows pre-test configuration.
|
|
4131
|
+
*
|
|
4132
|
+
* @template T - Type of instance being tested
|
|
4133
|
+
*
|
|
4134
|
+
* @example
|
|
4135
|
+
* ```typescript
|
|
4136
|
+
* const testCase: TestCaseWithSetup<Calculator> = {
|
|
4137
|
+
* name: 'adds with precision',
|
|
4138
|
+
* args: [0.1, 0.2],
|
|
4139
|
+
* expected: 0.3,
|
|
4140
|
+
* setup: (calc) => calc.setPrecision(10)
|
|
4141
|
+
* };
|
|
4142
|
+
* ```
|
|
4143
|
+
*/
|
|
2180
4144
|
export interface TestCaseWithSetup<T> {
|
|
2181
4145
|
name: string;
|
|
2182
4146
|
args: unknown[];
|
|
2183
4147
|
expected: unknown;
|
|
2184
4148
|
setup?: (instance: T) => void;
|
|
2185
4149
|
}
|
|
4150
|
+
/**
|
|
4151
|
+
* Configuration for lifecycle hook testing.
|
|
4152
|
+
* Validates hook execution.
|
|
4153
|
+
*
|
|
4154
|
+
* @template T - Type of instance with lifecycle hooks
|
|
4155
|
+
*
|
|
4156
|
+
* @example
|
|
4157
|
+
* ```typescript
|
|
4158
|
+
* const config: LifecycleHookTestConfig<Component> = {
|
|
4159
|
+
* name: 'componentDidMount',
|
|
4160
|
+
* hook: 'componentDidMount',
|
|
4161
|
+
* expectedCalls: 1,
|
|
4162
|
+
* expectError: false
|
|
4163
|
+
* };
|
|
4164
|
+
* ```
|
|
4165
|
+
*/
|
|
2186
4166
|
export interface LifecycleHookTestConfig<T> {
|
|
2187
4167
|
name: string;
|
|
2188
4168
|
hook: keyof T;
|
|
2189
4169
|
expectedCalls?: number;
|
|
2190
4170
|
expectError?: boolean;
|
|
2191
4171
|
}
|
|
4172
|
+
/**
|
|
4173
|
+
* Scenario for error handling tests.
|
|
4174
|
+
* Defines method, arguments, and expected error.
|
|
4175
|
+
*
|
|
4176
|
+
* @template T - Type of instance being tested
|
|
4177
|
+
*
|
|
4178
|
+
* @example
|
|
4179
|
+
* ```typescript
|
|
4180
|
+
* const scenario: ErrorHandlingScenario<UserService> = {
|
|
4181
|
+
* method: 'createUser',
|
|
4182
|
+
* args: [{ email: 'invalid' }],
|
|
4183
|
+
* expectedError: /Invalid email format/,
|
|
4184
|
+
* setup: (service) => service.enableValidation()
|
|
4185
|
+
* };
|
|
4186
|
+
* ```
|
|
4187
|
+
*/
|
|
2192
4188
|
export interface ErrorHandlingScenario<T> {
|
|
2193
4189
|
method: keyof T;
|
|
2194
4190
|
args: unknown[];
|
|
@@ -2202,6 +4198,21 @@ export type DataHandler<T> = (data: T) => void;
|
|
|
2202
4198
|
export type ValueGetter<T> = () => T;
|
|
2203
4199
|
export type GenericArgsFunction<T> = (...args: unknown[]) => T;
|
|
2204
4200
|
export type AsyncFunction<T> = () => Promise<T>;
|
|
4201
|
+
/**
|
|
4202
|
+
* Original console methods storage.
|
|
4203
|
+
* Preserves original console functions.
|
|
4204
|
+
*
|
|
4205
|
+
* @example
|
|
4206
|
+
* ```typescript
|
|
4207
|
+
* const original: OriginalConsole = {
|
|
4208
|
+
* log: console.log,
|
|
4209
|
+
* error: console.error,
|
|
4210
|
+
* warn: console.warn,
|
|
4211
|
+
* info: console.info,
|
|
4212
|
+
* debug: console.debug
|
|
4213
|
+
* };
|
|
4214
|
+
* ```
|
|
4215
|
+
*/
|
|
2205
4216
|
export interface OriginalConsole {
|
|
2206
4217
|
log: typeof globalThis.console.log;
|
|
2207
4218
|
error: typeof globalThis.console.error;
|
|
@@ -2209,6 +4220,21 @@ export interface OriginalConsole {
|
|
|
2209
4220
|
info: typeof globalThis.console.info;
|
|
2210
4221
|
debug: typeof globalThis.console.debug;
|
|
2211
4222
|
}
|
|
4223
|
+
/**
|
|
4224
|
+
* Information about DOM element.
|
|
4225
|
+
* Contains element metadata and attributes.
|
|
4226
|
+
*
|
|
4227
|
+
* @example
|
|
4228
|
+
* ```typescript
|
|
4229
|
+
* const info: ElementInfo = {
|
|
4230
|
+
* tagName: 'button',
|
|
4231
|
+
* id: 'submit-btn',
|
|
4232
|
+
* className: 'btn btn-primary',
|
|
4233
|
+
* textContent: 'Submit',
|
|
4234
|
+
* attributes: { 'data-testid': 'submit' }
|
|
4235
|
+
* };
|
|
4236
|
+
* ```
|
|
4237
|
+
*/
|
|
2212
4238
|
export interface ElementInfo {
|
|
2213
4239
|
tagName: string;
|
|
2214
4240
|
id: string;
|
|
@@ -2216,15 +4242,63 @@ export interface ElementInfo {
|
|
|
2216
4242
|
textContent: string | null;
|
|
2217
4243
|
attributes: Record<string, string>;
|
|
2218
4244
|
}
|
|
4245
|
+
/**
|
|
4246
|
+
* Debounced function with control methods.
|
|
4247
|
+
* Delays execution until after wait period.
|
|
4248
|
+
*
|
|
4249
|
+
* @template T - Type of original function
|
|
4250
|
+
*
|
|
4251
|
+
* @example
|
|
4252
|
+
* ```typescript
|
|
4253
|
+
* const debounced: DebouncedFunction<(value: string) => void> = debounce(
|
|
4254
|
+
* (value) => console.log(value),
|
|
4255
|
+
* 300
|
|
4256
|
+
* );
|
|
4257
|
+
* debounced('test'); // Waits 300ms
|
|
4258
|
+
* debounced.cancel(); // Cancel pending
|
|
4259
|
+
* debounced.flush(); // Execute immediately
|
|
4260
|
+
* ```
|
|
4261
|
+
*/
|
|
2219
4262
|
export interface DebouncedFunction<T extends (...args: unknown[]) => unknown> extends Function {
|
|
2220
4263
|
(...args: Parameters<T>): void;
|
|
2221
4264
|
cancel: () => void;
|
|
2222
4265
|
flush: () => void;
|
|
2223
4266
|
}
|
|
4267
|
+
/**
|
|
4268
|
+
* Throttled function with control methods.
|
|
4269
|
+
* Limits execution frequency.
|
|
4270
|
+
*
|
|
4271
|
+
* @template T - Type of original function
|
|
4272
|
+
*
|
|
4273
|
+
* @example
|
|
4274
|
+
* ```typescript
|
|
4275
|
+
* const throttled: ThrottledFunction<() => void> = throttle(
|
|
4276
|
+
* () => console.log('scroll'),
|
|
4277
|
+
* 100
|
|
4278
|
+
* );
|
|
4279
|
+
* window.addEventListener('scroll', throttled);
|
|
4280
|
+
* throttled.cancel(); // Cancel pending
|
|
4281
|
+
* ```
|
|
4282
|
+
*/
|
|
2224
4283
|
export interface ThrottledFunction<T extends (...args: unknown[]) => unknown> extends Function {
|
|
2225
4284
|
(...args: Parameters<T>): void;
|
|
2226
4285
|
cancel: () => void;
|
|
2227
4286
|
}
|
|
4287
|
+
/**
|
|
4288
|
+
* Stopwatch for timing operations.
|
|
4289
|
+
* Tracks elapsed time and lap times.
|
|
4290
|
+
*
|
|
4291
|
+
* @example
|
|
4292
|
+
* ```typescript
|
|
4293
|
+
* const stopwatch: Stopwatch = {
|
|
4294
|
+
* start: () => { startTime = Date.now(); },
|
|
4295
|
+
* lap: () => { // record lap return lapTime; },
|
|
4296
|
+
* stop: () => { // stop timing return elapsed; },
|
|
4297
|
+
* getLaps: () => [...laps],
|
|
4298
|
+
* reset: () => { // reset all }
|
|
4299
|
+
* };
|
|
4300
|
+
* ```
|
|
4301
|
+
*/
|
|
2228
4302
|
export interface Stopwatch {
|
|
2229
4303
|
start(): void;
|
|
2230
4304
|
lap(): number;
|
|
@@ -2232,6 +4306,21 @@ export interface Stopwatch {
|
|
|
2232
4306
|
getLaps(): number[];
|
|
2233
4307
|
reset(): void;
|
|
2234
4308
|
}
|
|
4309
|
+
/**
|
|
4310
|
+
* Return value from controller test harness.
|
|
4311
|
+
* Provides controller instance and dependencies.
|
|
4312
|
+
*
|
|
4313
|
+
* @template T - Type of controller
|
|
4314
|
+
*
|
|
4315
|
+
* @example
|
|
4316
|
+
* ```typescript
|
|
4317
|
+
* const harness: ControllerTestHarnessReturn<UserController> = {
|
|
4318
|
+
* controller: userController,
|
|
4319
|
+
* moduleRef: { get: (token) => mockService },
|
|
4320
|
+
* logger: mockLogger
|
|
4321
|
+
* };
|
|
4322
|
+
* ```
|
|
4323
|
+
*/
|
|
2235
4324
|
export interface ControllerTestHarnessReturn<T> {
|
|
2236
4325
|
controller: T;
|
|
2237
4326
|
moduleRef: {
|
|
@@ -2239,6 +4328,24 @@ export interface ControllerTestHarnessReturn<T> {
|
|
|
2239
4328
|
};
|
|
2240
4329
|
logger?: unknown;
|
|
2241
4330
|
}
|
|
4331
|
+
/**
|
|
4332
|
+
* Return value from service test harness.
|
|
4333
|
+
* Provides service instance and test utilities.
|
|
4334
|
+
*
|
|
4335
|
+
* @template T - Type of service
|
|
4336
|
+
*
|
|
4337
|
+
* @example
|
|
4338
|
+
* ```typescript
|
|
4339
|
+
* const harness: ServiceTestHarnessReturn<UserService> = {
|
|
4340
|
+
* service: userService,
|
|
4341
|
+
* dependencies: new Map([[DatabaseService, mockDb]]),
|
|
4342
|
+
* logger: mockLogger,
|
|
4343
|
+
* resetMocks: () => { // reset all mocks },
|
|
4344
|
+
* expectCalled: (method, times) => expect(service[method]).toHaveBeenCalledTimes(times),
|
|
4345
|
+
* expectCalledWith: (method, ...args) => expect(service[method]).toHaveBeenCalledWith(...args)
|
|
4346
|
+
* };
|
|
4347
|
+
* ```
|
|
4348
|
+
*/
|
|
2242
4349
|
export interface ServiceTestHarnessReturn<T> {
|
|
2243
4350
|
service: T;
|
|
2244
4351
|
dependencies: Map<unknown, unknown>;
|
|
@@ -2247,42 +4354,176 @@ export interface ServiceTestHarnessReturn<T> {
|
|
|
2247
4354
|
expectCalled: (method: keyof T, times?: number) => void;
|
|
2248
4355
|
expectCalledWith: (method: keyof T, ...args: unknown[]) => void;
|
|
2249
4356
|
}
|
|
4357
|
+
/**
|
|
4358
|
+
* Class for dynamic NestJS modules.
|
|
4359
|
+
* Provides configuration methods.
|
|
4360
|
+
*
|
|
4361
|
+
* @example
|
|
4362
|
+
* ```typescript
|
|
4363
|
+
* const moduleClass: DynamicModuleClass = {
|
|
4364
|
+
* forRoot: (config) => ({
|
|
4365
|
+
* module: DatabaseModule,
|
|
4366
|
+
* providers: [{ provide: 'CONFIG', useValue: config }],
|
|
4367
|
+
* exports: [DatabaseService]
|
|
4368
|
+
* })
|
|
4369
|
+
* };
|
|
4370
|
+
* ```
|
|
4371
|
+
*/
|
|
2250
4372
|
export interface DynamicModuleClass {
|
|
2251
4373
|
forRoot: (config: unknown) => Record<string, unknown>;
|
|
2252
4374
|
}
|
|
4375
|
+
/**
|
|
4376
|
+
* Expectations for dynamic module testing.
|
|
4377
|
+
* Validates module structure.
|
|
4378
|
+
*
|
|
4379
|
+
* @example
|
|
4380
|
+
* ```typescript
|
|
4381
|
+
* const expectations: DynamicModuleExpectations = {
|
|
4382
|
+
* providers: [DatabaseService, ConfigService],
|
|
4383
|
+
* imports: [CommonModule],
|
|
4384
|
+
* exports: [DatabaseService]
|
|
4385
|
+
* };
|
|
4386
|
+
* ```
|
|
4387
|
+
*/
|
|
2253
4388
|
export interface DynamicModuleExpectations {
|
|
2254
4389
|
providers?: unknown[];
|
|
2255
4390
|
imports?: unknown[];
|
|
2256
4391
|
exports?: unknown[];
|
|
2257
4392
|
}
|
|
4393
|
+
/**
|
|
4394
|
+
* Return value from NestJS test suite setup.
|
|
4395
|
+
* Contains module and providers.
|
|
4396
|
+
*
|
|
4397
|
+
* @example
|
|
4398
|
+
* ```typescript
|
|
4399
|
+
* const setup: NestJSTestSuiteSetupReturn = {
|
|
4400
|
+
* module: testingModule,
|
|
4401
|
+
* providers: new Map([[UserService, mockUserService]])
|
|
4402
|
+
* };
|
|
4403
|
+
* ```
|
|
4404
|
+
*/
|
|
2258
4405
|
export interface NestJSTestSuiteSetupReturn {
|
|
2259
4406
|
module: unknown;
|
|
2260
4407
|
providers: Map<unknown, unknown>;
|
|
2261
4408
|
}
|
|
4409
|
+
/**
|
|
4410
|
+
* Test for provider dependency injection.
|
|
4411
|
+
* Validates DI relationships.
|
|
4412
|
+
*
|
|
4413
|
+
* @example
|
|
4414
|
+
* ```typescript
|
|
4415
|
+
* const test: ProviderInjectionTest = {
|
|
4416
|
+
* token: UserService,
|
|
4417
|
+
* dependencies: [DatabaseService, CacheService],
|
|
4418
|
+
* testFn: (instance, deps) => {
|
|
4419
|
+
* expect(instance).toBeDefined();
|
|
4420
|
+
* expect(deps).toHaveLength(2);
|
|
4421
|
+
* }
|
|
4422
|
+
* };
|
|
4423
|
+
* ```
|
|
4424
|
+
*/
|
|
2262
4425
|
export interface ProviderInjectionTest {
|
|
2263
4426
|
token: unknown;
|
|
2264
4427
|
dependencies: unknown[];
|
|
2265
4428
|
testFn: (instance: unknown, deps: unknown[]) => void;
|
|
2266
4429
|
}
|
|
4430
|
+
/**
|
|
4431
|
+
* WebSocket ping message.
|
|
4432
|
+
* Used for connection keep-alive.
|
|
4433
|
+
*
|
|
4434
|
+
* @example
|
|
4435
|
+
* ```typescript
|
|
4436
|
+
* const ping: WebSocketPingMessage = {
|
|
4437
|
+
* type: 'ping'
|
|
4438
|
+
* };
|
|
4439
|
+
* ```
|
|
4440
|
+
*/
|
|
2267
4441
|
export interface WebSocketPingMessage {
|
|
2268
4442
|
type: 'ping';
|
|
2269
4443
|
}
|
|
4444
|
+
/**
|
|
4445
|
+
* WebSocket pong message.
|
|
4446
|
+
* Response to ping message.
|
|
4447
|
+
*
|
|
4448
|
+
* @example
|
|
4449
|
+
* ```typescript
|
|
4450
|
+
* const pong: WebSocketPongMessage = {
|
|
4451
|
+
* type: 'pong'
|
|
4452
|
+
* };
|
|
4453
|
+
* ```
|
|
4454
|
+
*/
|
|
2270
4455
|
export interface WebSocketPongMessage {
|
|
2271
4456
|
type: 'pong';
|
|
2272
4457
|
}
|
|
4458
|
+
/**
|
|
4459
|
+
* WebSocket echo message.
|
|
4460
|
+
* Echoes data back to sender.
|
|
4461
|
+
*
|
|
4462
|
+
* @example
|
|
4463
|
+
* ```typescript
|
|
4464
|
+
* const echo: WebSocketEchoMessage = {
|
|
4465
|
+
* type: 'echo',
|
|
4466
|
+
* data: 'Hello WebSocket'
|
|
4467
|
+
* };
|
|
4468
|
+
* ```
|
|
4469
|
+
*/
|
|
2273
4470
|
export interface WebSocketEchoMessage {
|
|
2274
4471
|
type: 'echo';
|
|
2275
4472
|
data: string;
|
|
2276
4473
|
}
|
|
4474
|
+
/**
|
|
4475
|
+
* Generic typed WebSocket message.
|
|
4476
|
+
* Base structure for custom messages.
|
|
4477
|
+
*
|
|
4478
|
+
* @example
|
|
4479
|
+
* ```typescript
|
|
4480
|
+
* const message: WebSocketTypedMessage = {
|
|
4481
|
+
* type: 'notification',
|
|
4482
|
+
* data: 'User joined the chat'
|
|
4483
|
+
* };
|
|
4484
|
+
* ```
|
|
4485
|
+
*/
|
|
2277
4486
|
export interface WebSocketTypedMessage {
|
|
2278
4487
|
type: string;
|
|
2279
4488
|
data: string;
|
|
2280
4489
|
}
|
|
4490
|
+
/**
|
|
4491
|
+
* Input for Next.js image loader.
|
|
4492
|
+
* Parameters for image optimization.
|
|
4493
|
+
*
|
|
4494
|
+
* @example
|
|
4495
|
+
* ```typescript
|
|
4496
|
+
* const input: ImageLoaderInput = {
|
|
4497
|
+
* src: '/images/hero.jpg',
|
|
4498
|
+
* width: 1920,
|
|
4499
|
+
* quality: 85
|
|
4500
|
+
* };
|
|
4501
|
+
* ```
|
|
4502
|
+
*/
|
|
2281
4503
|
export interface ImageLoaderInput {
|
|
2282
4504
|
src: string;
|
|
2283
4505
|
width: number;
|
|
2284
4506
|
quality?: number;
|
|
2285
4507
|
}
|
|
4508
|
+
/**
|
|
4509
|
+
* Step in user flow testing.
|
|
4510
|
+
* Defines interactions and assertions.
|
|
4511
|
+
*
|
|
4512
|
+
* @example
|
|
4513
|
+
* ```typescript
|
|
4514
|
+
* const step: UserFlowStep = {
|
|
4515
|
+
* name: 'Login flow',
|
|
4516
|
+
* interactions: [{ type: 'click', target: '#login' }],
|
|
4517
|
+
* assertions: async () => {
|
|
4518
|
+
* expect(screen.getByText('Dashboard')).toBeVisible();
|
|
4519
|
+
* },
|
|
4520
|
+
* navigation: {
|
|
4521
|
+
* expectedUrl: '/dashboard',
|
|
4522
|
+
* waitForNavigation: true
|
|
4523
|
+
* }
|
|
4524
|
+
* };
|
|
4525
|
+
* ```
|
|
4526
|
+
*/
|
|
2286
4527
|
export interface UserFlowStep {
|
|
2287
4528
|
name: string;
|
|
2288
4529
|
interactions: InteractionSequence[];
|
|
@@ -2292,6 +4533,23 @@ export interface UserFlowStep {
|
|
|
2292
4533
|
waitForNavigation?: boolean;
|
|
2293
4534
|
};
|
|
2294
4535
|
}
|
|
4536
|
+
/**
|
|
4537
|
+
* Parameters for creating mock Next.js request.
|
|
4538
|
+
* Configures request properties.
|
|
4539
|
+
*
|
|
4540
|
+
* @example
|
|
4541
|
+
* ```typescript
|
|
4542
|
+
* const params: MockNextRequestCreatorParams = {
|
|
4543
|
+
* url: 'https://example.com/api/users',
|
|
4544
|
+
* options: {
|
|
4545
|
+
* method: 'POST',
|
|
4546
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
4547
|
+
* body: { name: 'John' },
|
|
4548
|
+
* searchParams: { page: '1' }
|
|
4549
|
+
* }
|
|
4550
|
+
* };
|
|
4551
|
+
* ```
|
|
4552
|
+
*/
|
|
2295
4553
|
export interface MockNextRequestCreatorParams {
|
|
2296
4554
|
url: string;
|
|
2297
4555
|
options?: {
|
|
@@ -2301,11 +4559,44 @@ export interface MockNextRequestCreatorParams {
|
|
|
2301
4559
|
searchParams?: Record<string, string>;
|
|
2302
4560
|
};
|
|
2303
4561
|
}
|
|
4562
|
+
/**
|
|
4563
|
+
* Provider injection configuration.
|
|
4564
|
+
* Maps providers to dependencies.
|
|
4565
|
+
*
|
|
4566
|
+
* @example
|
|
4567
|
+
* ```typescript
|
|
4568
|
+
* const injection: ProviderInjection = {
|
|
4569
|
+
* token: UserService,
|
|
4570
|
+
* dependencies: [DatabaseService],
|
|
4571
|
+
* testFn: (instance, deps) => {
|
|
4572
|
+
* expect(instance).toBeInstanceOf(UserService);
|
|
4573
|
+
* }
|
|
4574
|
+
* };
|
|
4575
|
+
* ```
|
|
4576
|
+
*/
|
|
2304
4577
|
export interface ProviderInjection {
|
|
2305
4578
|
token: unknown;
|
|
2306
4579
|
dependencies: unknown[];
|
|
2307
4580
|
testFn: (instance: unknown, deps: unknown[]) => void;
|
|
2308
4581
|
}
|
|
4582
|
+
/**
|
|
4583
|
+
* Mock Redis client interface.
|
|
4584
|
+
* Provides mocked Redis operations.
|
|
4585
|
+
*
|
|
4586
|
+
* @example
|
|
4587
|
+
* ```typescript
|
|
4588
|
+
* const redis: CreateMockRedisClientMock = {
|
|
4589
|
+
* set: vi.fn().mockResolvedValue('OK'),
|
|
4590
|
+
* get: vi.fn().mockResolvedValue('value'),
|
|
4591
|
+
* del: vi.fn().mockResolvedValue(1),
|
|
4592
|
+
* keys: vi.fn().mockResolvedValue(['key1', 'key2']),
|
|
4593
|
+
* quit: vi.fn(),
|
|
4594
|
+
* on: vi.fn(),
|
|
4595
|
+
* multi: vi.fn(),
|
|
4596
|
+
* ping: vi.fn().mockResolvedValue('PONG')
|
|
4597
|
+
* };
|
|
4598
|
+
* ```
|
|
4599
|
+
*/
|
|
2309
4600
|
export interface CreateMockRedisClientMock {
|
|
2310
4601
|
set: Vitest.Mock;
|
|
2311
4602
|
get: Vitest.Mock;
|
|
@@ -2317,8 +4608,17 @@ export interface CreateMockRedisClientMock {
|
|
|
2317
4608
|
ping: Vitest.Mock;
|
|
2318
4609
|
}
|
|
2319
4610
|
/**
|
|
2320
|
-
* Call tracker
|
|
2321
|
-
*
|
|
4611
|
+
* Call tracker for monitoring function calls.
|
|
4612
|
+
* Records call history with arguments and timestamps.
|
|
4613
|
+
*
|
|
4614
|
+
* @example
|
|
4615
|
+
* ```typescript
|
|
4616
|
+
* const tracker: CallTracker = {
|
|
4617
|
+
* trackCall: (name, args) => calls.push({ name, args, timestamp: Date.now() }),
|
|
4618
|
+
* getCalls: (name) => name ? calls.filter(c => c.name === name) : calls,
|
|
4619
|
+
* reset: () => { calls = []; }
|
|
4620
|
+
* };
|
|
4621
|
+
* ```
|
|
2322
4622
|
*/
|
|
2323
4623
|
export interface CallTracker {
|
|
2324
4624
|
trackCall: (name: string, args: unknown[]) => void;
|
|
@@ -2330,9 +4630,20 @@ export interface CallTracker {
|
|
|
2330
4630
|
reset: () => void;
|
|
2331
4631
|
}
|
|
2332
4632
|
/**
|
|
2333
|
-
*
|
|
2334
|
-
*
|
|
2335
|
-
*
|
|
4633
|
+
* Enhanced spy with tracking capabilities.
|
|
4634
|
+
* Extends Vitest spy with call history methods.
|
|
4635
|
+
*
|
|
4636
|
+
* @example
|
|
4637
|
+
* ```typescript
|
|
4638
|
+
* const spy: TrackedSpy = Object.assign(vi.fn(), {
|
|
4639
|
+
* getCallCount: () => spy.mock.calls.length,
|
|
4640
|
+
* getCallHistory: () => spy.mock.calls.map((args, i) => ({
|
|
4641
|
+
* args,
|
|
4642
|
+
* result: spy.mock.results[i]?.value,
|
|
4643
|
+
* error: spy.mock.results[i]?.type === 'throw' ? spy.mock.results[i].value : undefined
|
|
4644
|
+
* }))
|
|
4645
|
+
* });
|
|
4646
|
+
* ```
|
|
2336
4647
|
*/
|
|
2337
4648
|
export interface TrackedSpy extends SpyInstance {
|
|
2338
4649
|
getCallCount: () => number;
|
|
@@ -2350,9 +4661,21 @@ export type SpyMap<T> = {
|
|
|
2350
4661
|
[K in keyof T]: SpyInstance;
|
|
2351
4662
|
};
|
|
2352
4663
|
/**
|
|
2353
|
-
*
|
|
2354
|
-
*
|
|
2355
|
-
*
|
|
4664
|
+
* Data wrapper with access tracking.
|
|
4665
|
+
* Records property access history.
|
|
4666
|
+
*
|
|
4667
|
+
* @template T - Type of data being tracked
|
|
4668
|
+
*
|
|
4669
|
+
* @example
|
|
4670
|
+
* ```typescript
|
|
4671
|
+
* const tracked: TrackedData<User> = {
|
|
4672
|
+
* data: { id: 1, name: 'John' },
|
|
4673
|
+
* accesses: [
|
|
4674
|
+
* { property: 'name', timestamp: 1699123456 },
|
|
4675
|
+
* { property: 'id', timestamp: 1699123457 }
|
|
4676
|
+
* ]
|
|
4677
|
+
* };
|
|
4678
|
+
* ```
|
|
2356
4679
|
*/
|
|
2357
4680
|
export interface TrackedData<T> {
|
|
2358
4681
|
data: T;
|
|
@@ -2362,8 +4685,17 @@ export interface TrackedData<T> {
|
|
|
2362
4685
|
}>;
|
|
2363
4686
|
}
|
|
2364
4687
|
/**
|
|
2365
|
-
*
|
|
2366
|
-
*
|
|
4688
|
+
* Information about property access.
|
|
4689
|
+
* Tracks access frequency and timing.
|
|
4690
|
+
*
|
|
4691
|
+
* @example
|
|
4692
|
+
* ```typescript
|
|
4693
|
+
* const access: AccessInfo = {
|
|
4694
|
+
* property: 'userName',
|
|
4695
|
+
* timestamp: Date.now(),
|
|
4696
|
+
* count: 5
|
|
4697
|
+
* };
|
|
4698
|
+
* ```
|
|
2367
4699
|
*/
|
|
2368
4700
|
export interface AccessInfo {
|
|
2369
4701
|
property: string | symbol;
|
|
@@ -2371,8 +4703,18 @@ export interface AccessInfo {
|
|
|
2371
4703
|
count: number;
|
|
2372
4704
|
}
|
|
2373
4705
|
/**
|
|
2374
|
-
*
|
|
2375
|
-
*
|
|
4706
|
+
* Unified interface for different worker implementations.
|
|
4707
|
+
* Compatible with Web Workers, Worker Threads, and custom workers.
|
|
4708
|
+
*
|
|
4709
|
+
* @example
|
|
4710
|
+
* ```typescript
|
|
4711
|
+
* const worker: WorkerLike = {
|
|
4712
|
+
* postMessage: (msg) => { // send message },
|
|
4713
|
+
* onmessage: (event) => { // handle message },
|
|
4714
|
+
* onerror: (error) => { // handle error },
|
|
4715
|
+
* terminate: () => { // cleanup }
|
|
4716
|
+
* };
|
|
4717
|
+
* ```
|
|
2376
4718
|
*/
|
|
2377
4719
|
export interface WorkerLike {
|
|
2378
4720
|
onError?: (error: Error) => void;
|
|
@@ -2393,8 +4735,27 @@ export interface WorkerLike {
|
|
|
2393
4735
|
terminate?: () => void;
|
|
2394
4736
|
}
|
|
2395
4737
|
/**
|
|
2396
|
-
*
|
|
2397
|
-
*
|
|
4738
|
+
* Pool of workers for parallel task execution.
|
|
4739
|
+
* Manages worker lifecycle and task distribution.
|
|
4740
|
+
*
|
|
4741
|
+
* @example
|
|
4742
|
+
* ```typescript
|
|
4743
|
+
* const pool: WorkerPool = {
|
|
4744
|
+
* addTask: (task) => taskQueue.push(task),
|
|
4745
|
+
* start: async () => { // initialize workers },
|
|
4746
|
+
* stop: () => { // terminate workers },
|
|
4747
|
+
* waitForCompletion: async () => { // wait for all tasks },
|
|
4748
|
+
* getStats: () => ({
|
|
4749
|
+
* totalWorkers: 4,
|
|
4750
|
+
* busyWorkers: 2,
|
|
4751
|
+
* idleWorkers: 2,
|
|
4752
|
+
* tasksCompleted: 100,
|
|
4753
|
+
* tasksFailed: 2,
|
|
4754
|
+
* tasksRemaining: 10,
|
|
4755
|
+
* workerStats: [// per-worker stats]
|
|
4756
|
+
* })
|
|
4757
|
+
* };
|
|
4758
|
+
* ```
|
|
2398
4759
|
*/
|
|
2399
4760
|
export interface WorkerPool {
|
|
2400
4761
|
addTask: (task: () => Promise<void>) => void;
|
|
@@ -2416,8 +4777,22 @@ export interface WorkerPool {
|
|
|
2416
4777
|
};
|
|
2417
4778
|
}
|
|
2418
4779
|
/**
|
|
2419
|
-
*
|
|
2420
|
-
*
|
|
4780
|
+
* Performance metrics for individual workers.
|
|
4781
|
+
* Tracks execution statistics and resource usage.
|
|
4782
|
+
*
|
|
4783
|
+
* @example
|
|
4784
|
+
* ```typescript
|
|
4785
|
+
* const metrics: WorkerMetrics = {
|
|
4786
|
+
* workerId: 1,
|
|
4787
|
+
* taskCount: 50,
|
|
4788
|
+
* executionTime: 5000,
|
|
4789
|
+
* errors: [],
|
|
4790
|
+
* throughput: 10, // tasks per second
|
|
4791
|
+
* avgTaskTime: 100,
|
|
4792
|
+
* memoryUsage: 50 * 1024 * 1024,
|
|
4793
|
+
* cpuUsage: 25
|
|
4794
|
+
* };
|
|
4795
|
+
* ```
|
|
2421
4796
|
*/
|
|
2422
4797
|
export interface WorkerMetrics {
|
|
2423
4798
|
workerId: number;
|
|
@@ -2430,8 +4805,31 @@ export interface WorkerMetrics {
|
|
|
2430
4805
|
cpuUsage?: number;
|
|
2431
4806
|
}
|
|
2432
4807
|
/**
|
|
2433
|
-
*
|
|
2434
|
-
*
|
|
4808
|
+
* Test harness for worker pool testing.
|
|
4809
|
+
* Provides methods to run and validate worker tests.
|
|
4810
|
+
*
|
|
4811
|
+
* @example
|
|
4812
|
+
* ```typescript
|
|
4813
|
+
* const harness: WorkerTestHarness = {
|
|
4814
|
+
* run: async () => ({
|
|
4815
|
+
* metrics: [// worker metrics],
|
|
4816
|
+
* totalExecutionTime: 10000,
|
|
4817
|
+
* totalTasks: 100,
|
|
4818
|
+
* totalErrors: 2
|
|
4819
|
+
* }),
|
|
4820
|
+
* assertResults: (results) => {
|
|
4821
|
+
* expect(results.totalErrors).toBeLessThan(5);
|
|
4822
|
+
* },
|
|
4823
|
+
* getMetrics: () => ({
|
|
4824
|
+
* workerCount: 4,
|
|
4825
|
+
* totalTasks: 100,
|
|
4826
|
+
* avgExecutionTime: 100,
|
|
4827
|
+
* avgThroughput: 10,
|
|
4828
|
+
* errorCount: 2,
|
|
4829
|
+
* workerMetrics: [// metrics]
|
|
4830
|
+
* })
|
|
4831
|
+
* };
|
|
4832
|
+
* ```
|
|
2435
4833
|
*/
|
|
2436
4834
|
export interface WorkerTestHarness {
|
|
2437
4835
|
run: () => Promise<{
|
|
@@ -2456,8 +4854,21 @@ export interface WorkerTestHarness {
|
|
|
2456
4854
|
};
|
|
2457
4855
|
}
|
|
2458
4856
|
/**
|
|
2459
|
-
*
|
|
2460
|
-
*
|
|
4857
|
+
* Spy for worker communication testing.
|
|
4858
|
+
* Tracks messages and simulates worker behavior.
|
|
4859
|
+
*
|
|
4860
|
+
* @example
|
|
4861
|
+
* ```typescript
|
|
4862
|
+
* const spy: WorkerSpy = {
|
|
4863
|
+
* getMessagesSent: () => sentMessages,
|
|
4864
|
+
* getMessagesReceived: () => receivedMessages,
|
|
4865
|
+
* getErrors: () => errors,
|
|
4866
|
+
* isTerminated: () => terminated,
|
|
4867
|
+
* simulateMessage: (msg) => worker.onmessage({ data: msg }),
|
|
4868
|
+
* simulateError: (err) => worker.onerror(err),
|
|
4869
|
+
* reset: () => { // clear all data }
|
|
4870
|
+
* };
|
|
4871
|
+
* ```
|
|
2461
4872
|
*/
|
|
2462
4873
|
export interface WorkerSpy {
|
|
2463
4874
|
getMessagesSent: () => unknown[];
|
|
@@ -2469,149 +4880,228 @@ export interface WorkerSpy {
|
|
|
2469
4880
|
reset: () => void;
|
|
2470
4881
|
}
|
|
2471
4882
|
/**
|
|
2472
|
-
*
|
|
2473
|
-
*
|
|
4883
|
+
* Options for performance profiling.
|
|
4884
|
+
* Configures what metrics to collect.
|
|
4885
|
+
*
|
|
4886
|
+
* @example
|
|
4887
|
+
* ```typescript
|
|
4888
|
+
* const options: ProfileOptions = {
|
|
4889
|
+
* sampleInterval: 10,
|
|
4890
|
+
* includeMemory: true,
|
|
4891
|
+
* includeCPU: true
|
|
4892
|
+
* };
|
|
4893
|
+
* ```
|
|
2474
4894
|
*/
|
|
2475
4895
|
export interface ProfileOptions {
|
|
2476
|
-
/** Sample interval in milliseconds */
|
|
2477
4896
|
sampleInterval?: number;
|
|
2478
|
-
/** Include memory profiling */
|
|
2479
4897
|
includeMemory?: boolean;
|
|
2480
|
-
/** Include CPU profiling */
|
|
2481
4898
|
includeCPU?: boolean;
|
|
2482
4899
|
}
|
|
2483
4900
|
/**
|
|
2484
|
-
*
|
|
2485
|
-
*
|
|
2486
|
-
*
|
|
4901
|
+
* Result from performance profiling.
|
|
4902
|
+
* Contains operation result and performance data.
|
|
4903
|
+
*
|
|
4904
|
+
* @template T - Type of profiled operation result
|
|
4905
|
+
*
|
|
4906
|
+
* @example
|
|
4907
|
+
* ```typescript
|
|
4908
|
+
* const profile: ProfileResult<string> = {
|
|
4909
|
+
* result: 'operation completed',
|
|
4910
|
+
* cpuProfile: {
|
|
4911
|
+
* samples: [10, 15, 20, 18],
|
|
4912
|
+
* timestamps: [0, 10, 20, 30],
|
|
4913
|
+
* duration: 30
|
|
4914
|
+
* },
|
|
4915
|
+
* memoryProfile: {
|
|
4916
|
+
* samples: [1000, 1500, 2000],
|
|
4917
|
+
* timestamps: [0, 15, 30]
|
|
4918
|
+
* }
|
|
4919
|
+
* };
|
|
4920
|
+
* ```
|
|
2487
4921
|
*/
|
|
2488
4922
|
export interface ProfileResult<T> {
|
|
2489
|
-
/** Operation result */
|
|
2490
4923
|
result: T;
|
|
2491
|
-
/** CPU profile data */
|
|
2492
4924
|
cpuProfile?: {
|
|
2493
|
-
/** Profile samples */
|
|
2494
4925
|
samples: number[];
|
|
2495
|
-
/** Sample timestamps */
|
|
2496
4926
|
timestamps: number[];
|
|
2497
4927
|
duration: number;
|
|
2498
4928
|
};
|
|
2499
|
-
/** Memory profile data */
|
|
2500
4929
|
memoryProfile?: {
|
|
2501
|
-
/** Memory usage samples */
|
|
2502
4930
|
samples: number[];
|
|
2503
|
-
/** Memory timestamps */
|
|
2504
4931
|
timestamps: number[];
|
|
2505
4932
|
};
|
|
2506
4933
|
}
|
|
2507
4934
|
/**
|
|
2508
|
-
*
|
|
2509
|
-
*
|
|
4935
|
+
* Options for stress testing.
|
|
4936
|
+
* Configures load parameters and error thresholds.
|
|
4937
|
+
*
|
|
4938
|
+
* @example
|
|
4939
|
+
* ```typescript
|
|
4940
|
+
* const options: StressTestOptions = {
|
|
4941
|
+
* duration: 60000, // 1 minute
|
|
4942
|
+
* concurrency: 100,
|
|
4943
|
+
* rampUp: 5000,
|
|
4944
|
+
* maxErrors: 50,
|
|
4945
|
+
* errorThreshold: 0.05 // 5% error rate
|
|
4946
|
+
* };
|
|
4947
|
+
* ```
|
|
2510
4948
|
*/
|
|
2511
4949
|
export interface StressTestOptions {
|
|
2512
|
-
/** Test duration in milliseconds */
|
|
2513
4950
|
duration?: number;
|
|
2514
|
-
/** Number of concurrent operations */
|
|
2515
4951
|
concurrency?: number;
|
|
2516
|
-
/** Ramp-up time */
|
|
2517
4952
|
rampUp?: number;
|
|
2518
4953
|
maxErrors?: number;
|
|
2519
4954
|
errorThreshold?: number;
|
|
2520
4955
|
}
|
|
2521
4956
|
/**
|
|
2522
|
-
*
|
|
2523
|
-
*
|
|
4957
|
+
* Results from stress testing.
|
|
4958
|
+
* Contains operation statistics and error information.
|
|
4959
|
+
*
|
|
4960
|
+
* @example
|
|
4961
|
+
* ```typescript
|
|
4962
|
+
* const result: StressTestResult = {
|
|
4963
|
+
* totalOperations: 10000,
|
|
4964
|
+
* successfulOperations: 9500,
|
|
4965
|
+
* failedOperations: 500,
|
|
4966
|
+
* averageResponseTime: 150,
|
|
4967
|
+
* operationsPerSecond: 166.67,
|
|
4968
|
+
* errorRate: 0.05,
|
|
4969
|
+
* errors: [// error objects]
|
|
4970
|
+
* };
|
|
4971
|
+
* ```
|
|
2524
4972
|
*/
|
|
2525
4973
|
export interface StressTestResult {
|
|
2526
|
-
/** Total operations performed */
|
|
2527
4974
|
totalOperations: number;
|
|
2528
|
-
/** Successful operations */
|
|
2529
4975
|
successfulOperations: number;
|
|
2530
|
-
/** Failed operations */
|
|
2531
4976
|
failedOperations: number;
|
|
2532
|
-
/** Average response time */
|
|
2533
4977
|
averageResponseTime: number;
|
|
2534
4978
|
operationsPerSecond: number;
|
|
2535
4979
|
errorRate: number;
|
|
2536
4980
|
errors: Error[];
|
|
2537
4981
|
}
|
|
2538
4982
|
/**
|
|
2539
|
-
*
|
|
2540
|
-
*
|
|
4983
|
+
* Results from throughput testing.
|
|
4984
|
+
* Measures operation rate and latency.
|
|
4985
|
+
*
|
|
4986
|
+
* @example
|
|
4987
|
+
* ```typescript
|
|
4988
|
+
* const result: ThroughputResult = {
|
|
4989
|
+
* operationsCompleted: 1000,
|
|
4990
|
+
* duration: 10000,
|
|
4991
|
+
* throughput: 100, // ops per second
|
|
4992
|
+
* averageLatency: 10,
|
|
4993
|
+
* minLatency: 5,
|
|
4994
|
+
* maxLatency: 50
|
|
4995
|
+
* };
|
|
4996
|
+
* ```
|
|
2541
4997
|
*/
|
|
2542
4998
|
export interface ThroughputResult {
|
|
2543
|
-
/** Operations completed */
|
|
2544
4999
|
operationsCompleted: number;
|
|
2545
|
-
/** Test duration */
|
|
2546
5000
|
duration: number;
|
|
2547
|
-
/** Throughput rate */
|
|
2548
5001
|
throughput: number;
|
|
2549
5002
|
averageLatency: number;
|
|
2550
5003
|
minLatency: number;
|
|
2551
5004
|
maxLatency: number;
|
|
2552
5005
|
}
|
|
2553
5006
|
/**
|
|
2554
|
-
*
|
|
2555
|
-
*
|
|
5007
|
+
* Options for performance monitoring.
|
|
5008
|
+
* Configures metrics collection.
|
|
5009
|
+
*
|
|
5010
|
+
* @example
|
|
5011
|
+
* ```typescript
|
|
5012
|
+
* const options: MonitorOptions = {
|
|
5013
|
+
* interval: 100, // sample every 100ms
|
|
5014
|
+
* metrics: ['cpu', 'memory', 'time']
|
|
5015
|
+
* };
|
|
5016
|
+
* ```
|
|
2556
5017
|
*/
|
|
2557
5018
|
export interface MonitorOptions {
|
|
2558
|
-
/** Monitoring interval */
|
|
2559
5019
|
interval?: number;
|
|
2560
|
-
/** Metrics to collect */
|
|
2561
5020
|
metrics?: Array<'cpu' | 'memory' | 'time'>;
|
|
2562
5021
|
}
|
|
2563
5022
|
/**
|
|
2564
|
-
*
|
|
2565
|
-
*
|
|
5023
|
+
* Monitor for collecting performance metrics.
|
|
5024
|
+
* Provides real-time performance tracking.
|
|
5025
|
+
*
|
|
5026
|
+
* @example
|
|
5027
|
+
* ```typescript
|
|
5028
|
+
* const monitor: PerformanceMonitor = {
|
|
5029
|
+
* start: () => { // begin monitoring },
|
|
5030
|
+
* stop: () => { // stop monitoring },
|
|
5031
|
+
* getMetrics: () => ({
|
|
5032
|
+
* cpu: [25, 30, 28, 35],
|
|
5033
|
+
* memory: [100, 110, 115, 120],
|
|
5034
|
+
* timestamps: [0, 100, 200, 300]
|
|
5035
|
+
* })
|
|
5036
|
+
* };
|
|
5037
|
+
* ```
|
|
2566
5038
|
*/
|
|
2567
5039
|
export interface PerformanceMonitor {
|
|
2568
|
-
/** Start monitoring */
|
|
2569
5040
|
start: () => void;
|
|
2570
|
-
/** Stop monitoring */
|
|
2571
5041
|
stop: () => void;
|
|
2572
|
-
/** Get collected metrics */
|
|
2573
5042
|
getMetrics: () => {
|
|
2574
|
-
/** CPU metrics */
|
|
2575
5043
|
cpu?: number[];
|
|
2576
|
-
/** Memory metrics */
|
|
2577
5044
|
memory?: number[];
|
|
2578
|
-
/** Time metrics */
|
|
2579
5045
|
timestamps: number[];
|
|
2580
5046
|
};
|
|
5047
|
+
reset: () => void;
|
|
2581
5048
|
}
|
|
2582
5049
|
/**
|
|
2583
|
-
*
|
|
2584
|
-
*
|
|
5050
|
+
* Options for memory leak testing.
|
|
5051
|
+
* Configures leak detection parameters.
|
|
5052
|
+
*
|
|
5053
|
+
* @example
|
|
5054
|
+
* ```typescript
|
|
5055
|
+
* const options: LeakOptions = {
|
|
5056
|
+
* iterations: 100,
|
|
5057
|
+
* threshold: 10 * 1024 * 1024, // 10MB
|
|
5058
|
+
* gcBetweenRuns: true
|
|
5059
|
+
* };
|
|
5060
|
+
* ```
|
|
2585
5061
|
*/
|
|
2586
5062
|
export interface LeakOptions {
|
|
2587
|
-
/** Number of test iterations */
|
|
2588
5063
|
iterations?: number;
|
|
2589
|
-
/** Memory threshold */
|
|
2590
5064
|
threshold?: number;
|
|
2591
|
-
/** Run GC between runs */
|
|
2592
5065
|
gcBetweenRuns?: boolean;
|
|
2593
5066
|
}
|
|
2594
5067
|
/**
|
|
2595
|
-
*
|
|
2596
|
-
*
|
|
5068
|
+
* Result from memory leak testing.
|
|
5069
|
+
* Indicates leak presence and growth rate.
|
|
5070
|
+
*
|
|
5071
|
+
* @example
|
|
5072
|
+
* ```typescript
|
|
5073
|
+
* const result: LeakResult = {
|
|
5074
|
+
* hasLeak: true,
|
|
5075
|
+
* memoryGrowth: 5 * 1024 * 1024, // 5MB growth
|
|
5076
|
+
* measurements: [
|
|
5077
|
+
* { iteration: 0, memory: 50000000 },
|
|
5078
|
+
* { iteration: 50, memory: 52500000 },
|
|
5079
|
+
* { iteration: 100, memory: 55000000 }
|
|
5080
|
+
* ]
|
|
5081
|
+
* };
|
|
5082
|
+
* ```
|
|
2597
5083
|
*/
|
|
2598
5084
|
export interface LeakResult {
|
|
2599
|
-
/** Whether leak was detected */
|
|
2600
5085
|
hasLeak: boolean;
|
|
2601
|
-
/** Memory growth amount */
|
|
2602
5086
|
memoryGrowth: number;
|
|
2603
|
-
/** Memory measurements */
|
|
2604
5087
|
measurements: Array<{
|
|
2605
|
-
/** Iteration number */
|
|
2606
5088
|
iteration: number;
|
|
2607
|
-
/** Memory usage */
|
|
2608
5089
|
memory: number;
|
|
2609
5090
|
}>;
|
|
2610
5091
|
}
|
|
2611
5092
|
/**
|
|
2612
|
-
*
|
|
2613
|
-
*
|
|
2614
|
-
*
|
|
5093
|
+
* Scenario for testing React hooks.
|
|
5094
|
+
* Defines actions and expected state.
|
|
5095
|
+
*
|
|
5096
|
+
* @example
|
|
5097
|
+
* ```typescript
|
|
5098
|
+
* const scenario: HookScenario = {
|
|
5099
|
+
* name: 'increment counter',
|
|
5100
|
+
* action: () => result.current.increment(),
|
|
5101
|
+
* expectedState: { count: 1, loading: false },
|
|
5102
|
+
* expectedError: null
|
|
5103
|
+
* };
|
|
5104
|
+
* ```
|
|
2615
5105
|
*/
|
|
2616
5106
|
export interface HookScenario {
|
|
2617
5107
|
name: string;
|
|
@@ -2798,7 +5288,7 @@ export interface DragOptions {
|
|
|
2798
5288
|
steps?: number;
|
|
2799
5289
|
dropEffect?: 'move' | 'copy' | 'link' | 'none';
|
|
2800
5290
|
}
|
|
2801
|
-
export type
|
|
5291
|
+
export type TouchGestureAdvanced = {
|
|
2802
5292
|
type: 'tap';
|
|
2803
5293
|
x: number;
|
|
2804
5294
|
y: number;
|
|
@@ -2847,37 +5337,23 @@ export interface Interaction {
|
|
|
2847
5337
|
* @interface SwipeGestureParams
|
|
2848
5338
|
*/
|
|
2849
5339
|
export interface SwipeGestureParams {
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
end: {
|
|
2857
|
-
x: number;
|
|
2858
|
-
y: number;
|
|
2859
|
-
};
|
|
2860
|
-
/** Gesture duration */
|
|
2861
|
-
duration?: number;
|
|
2862
|
-
/** Number of touch points */
|
|
2863
|
-
touches?: number;
|
|
5340
|
+
element: Element;
|
|
5341
|
+
startX: number;
|
|
5342
|
+
startY: number;
|
|
5343
|
+
endX: number;
|
|
5344
|
+
endY: number;
|
|
5345
|
+
duration: number;
|
|
2864
5346
|
}
|
|
2865
5347
|
/**
|
|
2866
5348
|
* Pinch gesture parameters
|
|
2867
5349
|
* @interface PinchGestureParams
|
|
2868
5350
|
*/
|
|
2869
5351
|
export interface PinchGestureParams {
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
/** Scale factor */
|
|
2876
|
-
scale: number;
|
|
2877
|
-
/** Gesture duration */
|
|
2878
|
-
duration?: number;
|
|
2879
|
-
/** Rotation angle */
|
|
2880
|
-
rotation?: number;
|
|
5352
|
+
element: Element;
|
|
5353
|
+
centerX: number;
|
|
5354
|
+
centerY: number;
|
|
5355
|
+
startDistance: number;
|
|
5356
|
+
endDistance: number;
|
|
2881
5357
|
}
|
|
2882
5358
|
/**
|
|
2883
5359
|
* Animation frame data
|
|
@@ -2928,12 +5404,9 @@ export interface IntervalHandle {
|
|
|
2928
5404
|
* @interface ScheduleHandle
|
|
2929
5405
|
*/
|
|
2930
5406
|
export interface ScheduleHandle {
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
cancel: () => void;
|
|
2935
|
-
/** Check if pending */
|
|
2936
|
-
isPending: () => boolean;
|
|
5407
|
+
stop: () => void;
|
|
5408
|
+
nextRun: () => Date | null;
|
|
5409
|
+
isRunning: () => boolean;
|
|
2937
5410
|
}
|
|
2938
5411
|
/**
|
|
2939
5412
|
* Timer interface
|
|
@@ -2960,14 +5433,11 @@ export interface Countdown {
|
|
|
2960
5433
|
* @interface HistoryEntry
|
|
2961
5434
|
*/
|
|
2962
5435
|
export interface MockHistoryEntry {
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
5436
|
+
pathname: string;
|
|
5437
|
+
search?: string;
|
|
5438
|
+
hash?: string;
|
|
2966
5439
|
state?: unknown;
|
|
2967
|
-
|
|
2968
|
-
title?: string;
|
|
2969
|
-
/** Entry timestamp */
|
|
2970
|
-
timestamp: number;
|
|
5440
|
+
key?: string;
|
|
2971
5441
|
}
|
|
2972
5442
|
/**
|
|
2973
5443
|
* Mock history object
|
|
@@ -2993,15 +5463,10 @@ export interface MockHistory {
|
|
|
2993
5463
|
* @interface MockLocation
|
|
2994
5464
|
*/
|
|
2995
5465
|
export interface MockLocation {
|
|
2996
|
-
/** Current pathname */
|
|
2997
5466
|
pathname: string;
|
|
2998
|
-
/** Current search */
|
|
2999
5467
|
search: string;
|
|
3000
|
-
/** Current hash */
|
|
3001
5468
|
hash: string;
|
|
3002
|
-
/** Current state */
|
|
3003
5469
|
state: unknown;
|
|
3004
|
-
/** Location key */
|
|
3005
5470
|
key: string;
|
|
3006
5471
|
href: string;
|
|
3007
5472
|
origin: string;
|
|
@@ -3044,9 +5509,7 @@ export interface GuardScenario {
|
|
|
3044
5509
|
* @interface NavOptions
|
|
3045
5510
|
*/
|
|
3046
5511
|
export interface NavOptions {
|
|
3047
|
-
/** Replace current entry */
|
|
3048
5512
|
replace?: boolean;
|
|
3049
|
-
/** Navigation state */
|
|
3050
5513
|
state?: unknown;
|
|
3051
5514
|
shallow?: boolean;
|
|
3052
5515
|
}
|
|
@@ -3118,13 +5581,9 @@ export interface APIRequest {
|
|
|
3118
5581
|
* @interface LifecycleScenario
|
|
3119
5582
|
*/
|
|
3120
5583
|
export interface LifecycleScenario {
|
|
3121
|
-
/** Scenario name */
|
|
3122
5584
|
name: string;
|
|
3123
|
-
/** Action to perform */
|
|
3124
5585
|
action: () => void | Promise<void>;
|
|
3125
|
-
/** Expected state after action */
|
|
3126
5586
|
expectedState?: Record<string, unknown>;
|
|
3127
|
-
/** Expected events */
|
|
3128
5587
|
expectedEvents?: string[];
|
|
3129
5588
|
}
|
|
3130
5589
|
/**
|
|
@@ -3132,21 +5591,17 @@ export interface LifecycleScenario {
|
|
|
3132
5591
|
* @interface LifecycleTracker
|
|
3133
5592
|
*/
|
|
3134
5593
|
export interface LifecycleTracker {
|
|
3135
|
-
/** Recorded events */
|
|
3136
5594
|
events: Array<{
|
|
3137
5595
|
type: string;
|
|
3138
5596
|
timestamp: number;
|
|
3139
5597
|
data?: unknown;
|
|
3140
5598
|
}>;
|
|
3141
|
-
/** Clear all events */
|
|
3142
5599
|
clear: () => void;
|
|
3143
|
-
/** Get all events */
|
|
3144
5600
|
getEvents: () => Array<{
|
|
3145
5601
|
type: string;
|
|
3146
5602
|
timestamp: number;
|
|
3147
5603
|
data?: unknown;
|
|
3148
5604
|
}>;
|
|
3149
|
-
/** Get events by type */
|
|
3150
5605
|
getEventsByType: (type: string) => Array<{
|
|
3151
5606
|
type: string;
|
|
3152
5607
|
timestamp: number;
|
|
@@ -3158,9 +5613,7 @@ export interface LifecycleTracker {
|
|
|
3158
5613
|
* @interface LifecycleEvent
|
|
3159
5614
|
*/
|
|
3160
5615
|
export interface LifecycleEvent {
|
|
3161
|
-
/** Event type */
|
|
3162
5616
|
type: string;
|
|
3163
|
-
/** Event data */
|
|
3164
5617
|
data?: unknown;
|
|
3165
5618
|
}
|
|
3166
5619
|
/**
|
|
@@ -3168,11 +5621,8 @@ export interface LifecycleEvent {
|
|
|
3168
5621
|
* @interface CleanupResult
|
|
3169
5622
|
*/
|
|
3170
5623
|
export interface CleanupResult {
|
|
3171
|
-
/** Whether cleanup was successful */
|
|
3172
5624
|
cleanedUp: boolean;
|
|
3173
|
-
/** Cleaned up resources */
|
|
3174
5625
|
resources: string[];
|
|
3175
|
-
/** Cleanup errors */
|
|
3176
5626
|
errors: Error[];
|
|
3177
5627
|
}
|
|
3178
5628
|
/**
|
|
@@ -3180,11 +5630,8 @@ export interface CleanupResult {
|
|
|
3180
5630
|
* @interface LifecycleMetrics
|
|
3181
5631
|
*/
|
|
3182
5632
|
export interface LifecycleMetrics {
|
|
3183
|
-
/** Mount time */
|
|
3184
5633
|
mountTime: number;
|
|
3185
|
-
/** Update time */
|
|
3186
5634
|
updateTime: number;
|
|
3187
|
-
/** Unmount time */
|
|
3188
5635
|
unmountTime: number;
|
|
3189
5636
|
totalLifecycleTime: number;
|
|
3190
5637
|
renderCount: number;
|
|
@@ -3194,15 +5641,10 @@ export interface LifecycleMetrics {
|
|
|
3194
5641
|
* @interface FileSnapshot
|
|
3195
5642
|
*/
|
|
3196
5643
|
export interface FileSnapshot {
|
|
3197
|
-
/** File path */
|
|
3198
5644
|
path: string;
|
|
3199
|
-
/** File size */
|
|
3200
5645
|
size: number;
|
|
3201
|
-
/** Modification time */
|
|
3202
5646
|
mtime: Date;
|
|
3203
|
-
/** File content */
|
|
3204
5647
|
content: string;
|
|
3205
|
-
/** Content hash */
|
|
3206
5648
|
hash: string;
|
|
3207
5649
|
}
|
|
3208
5650
|
/**
|
|
@@ -3220,7 +5662,6 @@ interface EnvConfig {
|
|
|
3220
5662
|
* @interface TestEnvironment
|
|
3221
5663
|
*/
|
|
3222
5664
|
export interface TestEnvironment {
|
|
3223
|
-
/** Get environment variable */
|
|
3224
5665
|
get: (key: string) => string | undefined;
|
|
3225
5666
|
set: (key: string, value: string) => void;
|
|
3226
5667
|
reset: () => void;
|
|
@@ -3231,7 +5672,6 @@ export interface TestEnvironment {
|
|
|
3231
5672
|
* @interface EnvMock
|
|
3232
5673
|
*/
|
|
3233
5674
|
export interface EnvMock {
|
|
3234
|
-
/** Restore original environment */
|
|
3235
5675
|
restore: () => void;
|
|
3236
5676
|
update: (vars: Record<string, string>) => void;
|
|
3237
5677
|
clear: () => void;
|
|
@@ -3241,7 +5681,6 @@ export interface EnvMock {
|
|
|
3241
5681
|
* @interface EnvSnapshot
|
|
3242
5682
|
*/
|
|
3243
5683
|
export interface EnvSnapshot {
|
|
3244
|
-
/** Environment variables */
|
|
3245
5684
|
variables: Record<string, string | undefined>;
|
|
3246
5685
|
timestamp: number;
|
|
3247
5686
|
}
|