@plyaz/types 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.d.ts +1 -0
- package/dist/api/types.d.ts +84 -0
- package/dist/auth/enums.d.ts +32 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/schemas.d.ts +27 -0
- package/dist/auth/types.d.ts +34 -0
- package/dist/common/index.d.ts +2 -0
- package/dist/common/types.d.ts +22 -0
- package/dist/entities/index.d.ts +1 -0
- package/dist/errors/enums.d.ts +33 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/types.d.ts +79 -0
- package/dist/events/enums.d.ts +25 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/payload.d.ts +6 -0
- package/dist/events/types.d.ts +136 -0
- package/dist/features/cache/index.d.ts +1 -0
- package/dist/features/cache/types.d.ts +142 -0
- package/dist/features/feature-flag/index.d.ts +1 -0
- package/dist/features/feature-flag/types.d.ts +491 -0
- package/dist/features/index.d.ts +2 -0
- package/dist/index.d.ts +12 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/testing/common/assertions/index.d.ts +1 -0
- package/dist/testing/common/assertions/types.d.ts +137 -0
- package/dist/testing/common/factories/index.d.ts +1 -0
- package/dist/testing/common/factories/types.d.ts +701 -0
- package/dist/testing/common/index.d.ts +6 -0
- package/dist/testing/common/mocks/index.d.ts +1 -0
- package/dist/testing/common/mocks/types.d.ts +1662 -0
- package/dist/testing/common/patterns/index.d.ts +1 -0
- package/dist/testing/common/patterns/types.d.ts +397 -0
- package/dist/testing/common/utils/index.d.ts +1 -0
- package/dist/testing/common/utils/types.d.ts +1970 -0
- package/dist/testing/common/wrappers/index.d.ts +1 -0
- package/dist/testing/common/wrappers/types.d.ts +373 -0
- package/dist/testing/features/cache/index.d.ts +1 -0
- package/dist/testing/features/cache/types.d.ts +43 -0
- package/dist/testing/features/feature-flags/index.d.ts +1 -0
- package/dist/testing/features/feature-flags/types.d.ts +1133 -0
- package/dist/testing/features/index.d.ts +2 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/translations/index.d.ts +1 -0
- package/dist/translations/types.d.ts +390 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/web3/enums.d.ts +17 -0
- package/dist/web3/index.d.ts +2 -0
- package/dist/web3/types.d.ts +63 -0
- package/package.json +2 -2
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for factory utilities.
|
|
5
|
+
*/
|
|
6
|
+
import type * as Vitest from 'vitest';
|
|
7
|
+
/**
|
|
8
|
+
* Test user interface for user-related testing
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const user: TestUser = {
|
|
13
|
+
* id: 'user-123',
|
|
14
|
+
* email: 'test@example.com',
|
|
15
|
+
* name: 'Test User',
|
|
16
|
+
* roles: ['user', 'admin'],
|
|
17
|
+
* permissions: ['read', 'write'],
|
|
18
|
+
* metadata: { source: 'test' },
|
|
19
|
+
* createdAt: new Date(),
|
|
20
|
+
* updatedAt: new Date()
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export interface TestUser {
|
|
25
|
+
/** Unique user identifier */
|
|
26
|
+
id: string;
|
|
27
|
+
/** User email address */
|
|
28
|
+
email: string;
|
|
29
|
+
/** User display name */
|
|
30
|
+
name: string;
|
|
31
|
+
/** User roles */
|
|
32
|
+
roles: string[];
|
|
33
|
+
/** User permissions */
|
|
34
|
+
permissions: string[];
|
|
35
|
+
/** Additional user metadata */
|
|
36
|
+
metadata?: Record<string, unknown>;
|
|
37
|
+
/** User creation timestamp */
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
/** User last update timestamp */
|
|
40
|
+
updatedAt: Date;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Test context interface for environment and user context
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const context: TestContext = {
|
|
48
|
+
* userId: 'user-123',
|
|
49
|
+
* environment: 'test',
|
|
50
|
+
* locale: 'en-US',
|
|
51
|
+
* timezone: 'UTC',
|
|
52
|
+
* userAgent: 'test-agent/1.0',
|
|
53
|
+
* ip: '127.0.0.1',
|
|
54
|
+
* country: 'US',
|
|
55
|
+
* customField: 'custom-value'
|
|
56
|
+
* };
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export interface TestContext {
|
|
60
|
+
/** Current user ID */
|
|
61
|
+
userId?: string;
|
|
62
|
+
/** Runtime environment */
|
|
63
|
+
environment: string;
|
|
64
|
+
/** User locale */
|
|
65
|
+
locale?: string;
|
|
66
|
+
/** User timezone */
|
|
67
|
+
timezone?: string;
|
|
68
|
+
/** User agent string */
|
|
69
|
+
userAgent?: string;
|
|
70
|
+
/** Client IP address */
|
|
71
|
+
ip?: string;
|
|
72
|
+
/** Client country */
|
|
73
|
+
country?: string;
|
|
74
|
+
/** Client region */
|
|
75
|
+
region?: string;
|
|
76
|
+
/** Client city */
|
|
77
|
+
city?: string;
|
|
78
|
+
/** Additional context fields */
|
|
79
|
+
[key: string]: string | undefined;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Test API response interface for HTTP response testing
|
|
83
|
+
*
|
|
84
|
+
* @typeParam T - Type of the response data
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const response: TestApiResponse<User> = {
|
|
89
|
+
* data: { id: '123', name: 'John' },
|
|
90
|
+
* status: 200,
|
|
91
|
+
* statusText: 'OK',
|
|
92
|
+
* headers: { 'content-type': 'application/json' },
|
|
93
|
+
* timestamp: new Date(),
|
|
94
|
+
* requestId: 'req-123'
|
|
95
|
+
* };
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export interface TestApiResponse<T = unknown> {
|
|
99
|
+
/** Response data payload */
|
|
100
|
+
data: T;
|
|
101
|
+
/** HTTP status code */
|
|
102
|
+
status: number;
|
|
103
|
+
/** HTTP status text */
|
|
104
|
+
statusText: string;
|
|
105
|
+
/** Response headers */
|
|
106
|
+
headers: Record<string, string>;
|
|
107
|
+
/** Response timestamp */
|
|
108
|
+
timestamp: Date;
|
|
109
|
+
/** Unique request identifier */
|
|
110
|
+
requestId: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Test error response interface for error handling testing
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const errorResponse: TestErrorResponse = {
|
|
118
|
+
* error: 'ValidationError',
|
|
119
|
+
* message: 'Email is required',
|
|
120
|
+
* statusCode: 400,
|
|
121
|
+
* timestamp: new Date(),
|
|
122
|
+
* path: '/api/users',
|
|
123
|
+
* details: { field: 'email' }
|
|
124
|
+
* };
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export interface TestErrorResponse {
|
|
128
|
+
/** Error type/name */
|
|
129
|
+
error: string;
|
|
130
|
+
/** Human-readable error message */
|
|
131
|
+
message: string;
|
|
132
|
+
/** HTTP status code */
|
|
133
|
+
statusCode: number;
|
|
134
|
+
/** Error timestamp */
|
|
135
|
+
timestamp: Date;
|
|
136
|
+
/** Request path where error occurred */
|
|
137
|
+
path?: string;
|
|
138
|
+
/** Additional error details */
|
|
139
|
+
details?: unknown;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Test pagination data interface for paginated response testing
|
|
143
|
+
*
|
|
144
|
+
* @typeParam T - Type of the paginated items
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const pagination: TestPaginationData<User> = {
|
|
149
|
+
* items: [user1, user2, user3],
|
|
150
|
+
* total: 100,
|
|
151
|
+
* page: 2,
|
|
152
|
+
* pageSize: 10,
|
|
153
|
+
* totalPages: 10,
|
|
154
|
+
* hasNext: true,
|
|
155
|
+
* hasPrevious: true
|
|
156
|
+
* };
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
export interface TestPaginationData<T> {
|
|
160
|
+
/** Items in current page */
|
|
161
|
+
items: T[];
|
|
162
|
+
/** Total number of items */
|
|
163
|
+
total: number;
|
|
164
|
+
/** Current page number */
|
|
165
|
+
page: number;
|
|
166
|
+
/** Number of items per page */
|
|
167
|
+
pageSize: number;
|
|
168
|
+
/** Total number of pages */
|
|
169
|
+
totalPages: number;
|
|
170
|
+
/** Whether there's a next page */
|
|
171
|
+
hasNext: boolean;
|
|
172
|
+
/** Whether there's a previous page */
|
|
173
|
+
hasPrevious: boolean;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Test metadata interface for entity metadata testing
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const metadata: TestMetadata = {
|
|
181
|
+
* version: '1.2.3',
|
|
182
|
+
* source: 'api',
|
|
183
|
+
* createdBy: 'system',
|
|
184
|
+
* updatedBy: 'admin',
|
|
185
|
+
* tags: ['important', 'user-data'],
|
|
186
|
+
* labels: { environment: 'production', tier: 'premium' },
|
|
187
|
+
* annotations: { lastMigration: '2023-01-01' }
|
|
188
|
+
* };
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export interface TestMetadata {
|
|
192
|
+
/** Version string */
|
|
193
|
+
version: string;
|
|
194
|
+
/** Data source identifier */
|
|
195
|
+
source: string;
|
|
196
|
+
/** Creator identifier */
|
|
197
|
+
createdBy: string;
|
|
198
|
+
/** Last updater identifier */
|
|
199
|
+
updatedBy: string;
|
|
200
|
+
/** Metadata tags */
|
|
201
|
+
tags: string[];
|
|
202
|
+
/** Key-value labels */
|
|
203
|
+
labels: Record<string, string>;
|
|
204
|
+
/** Additional annotations */
|
|
205
|
+
annotations: Record<string, unknown>;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Test timestamps interface for entity lifecycle testing
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const timestamps: TestTimestamps = {
|
|
213
|
+
* createdAt: new Date('2023-01-01'),
|
|
214
|
+
* updatedAt: new Date('2023-01-02'),
|
|
215
|
+
* deletedAt: null,
|
|
216
|
+
* expiresAt: new Date('2024-01-01'),
|
|
217
|
+
* lastAccessedAt: new Date('2023-12-31')
|
|
218
|
+
* };
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export interface TestTimestamps {
|
|
222
|
+
/** Entity creation date */
|
|
223
|
+
createdAt: Date;
|
|
224
|
+
/** Entity last update date */
|
|
225
|
+
updatedAt: Date;
|
|
226
|
+
/** Entity deletion date (soft delete) */
|
|
227
|
+
deletedAt?: Date | null;
|
|
228
|
+
/** Entity expiration date */
|
|
229
|
+
expiresAt?: Date | null;
|
|
230
|
+
/** Entity last access date */
|
|
231
|
+
lastAccessedAt?: Date | null;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Test scenario interface for scenario-driven testing
|
|
235
|
+
*
|
|
236
|
+
* @typeParam TContext - Type of the test context
|
|
237
|
+
* @typeParam TInput - Type of the test input
|
|
238
|
+
* @typeParam TExpected - Type of the expected result
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const scenario: TestScenario<UserService, CreateUserInput, User> = {
|
|
243
|
+
* name: 'Create user with valid data',
|
|
244
|
+
* description: 'Should create user when valid data is provided',
|
|
245
|
+
* data: () => ({ userService: new UserService() }),
|
|
246
|
+
* setup: async (context) => { await context.userService.initialize(); },
|
|
247
|
+
* arrange: async () => ({ userService: mockUserService }),
|
|
248
|
+
* act: async (context) => context.userService.create(validUserData),
|
|
249
|
+
* assert: (result, context) => { expect(result).toBeDefined(); },
|
|
250
|
+
* input: { name: 'John', email: 'john@test.com' },
|
|
251
|
+
* expected: { id: '123', name: 'John', email: 'john@test.com' }
|
|
252
|
+
* };
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export interface TestScenario<TContext, TInput, TExpected> {
|
|
256
|
+
/** Test scenario name */
|
|
257
|
+
name: string;
|
|
258
|
+
/** Test scenario description */
|
|
259
|
+
description: string;
|
|
260
|
+
/** Test data or factory function */
|
|
261
|
+
data: TContext | (() => TContext);
|
|
262
|
+
/** Setup function executed before test */
|
|
263
|
+
setup?: (context?: TContext) => void | Promise<void>;
|
|
264
|
+
/** Teardown function executed after test */
|
|
265
|
+
teardown?: (context?: TContext) => void | Promise<void>;
|
|
266
|
+
/** Arrange phase - prepare test context */
|
|
267
|
+
arrange: () => TContext | Promise<TContext>;
|
|
268
|
+
/** Act phase - execute the action being tested */
|
|
269
|
+
act: (instance: TContext) => unknown | Promise<unknown>;
|
|
270
|
+
/** Assert phase - verify the results */
|
|
271
|
+
assert: (result: unknown, instance: TContext) => void | Promise<void>;
|
|
272
|
+
/** Cleanup function executed after assertions */
|
|
273
|
+
cleanup?: (context?: Awaited<TContext>) => void | Promise<void>;
|
|
274
|
+
/** Optional test context */
|
|
275
|
+
context?: TContext;
|
|
276
|
+
/** Test input data */
|
|
277
|
+
input: TInput;
|
|
278
|
+
/** Expected test result */
|
|
279
|
+
expected: TExpected;
|
|
280
|
+
/** Test timeout in milliseconds */
|
|
281
|
+
timeout?: number;
|
|
282
|
+
/** Skip this scenario */
|
|
283
|
+
skip?: boolean;
|
|
284
|
+
/** Run only this scenario */
|
|
285
|
+
only?: boolean;
|
|
286
|
+
/** Additional expectations */
|
|
287
|
+
expectations?: Array<(data: TContext) => void>;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Scenario test suite configuration for organizing related test scenarios
|
|
291
|
+
*
|
|
292
|
+
* @typeParam TContext - Type of the test context
|
|
293
|
+
* @typeParam TInput - Type of the test input
|
|
294
|
+
* @typeParam TExpected - Type of the expected result
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* const suite: ScenarioTestSuite<UserService, CreateUserInput, User> = {
|
|
299
|
+
* suiteName: 'User Creation Tests',
|
|
300
|
+
* beforeAll: async () => { await setupDatabase(); },
|
|
301
|
+
* afterAll: async () => { await cleanupDatabase(); },
|
|
302
|
+
* beforeEach: (scenario) => { console.log(`Running: ${scenario.name}`); },
|
|
303
|
+
* scenarios: [scenario1, scenario2, scenario3],
|
|
304
|
+
* testFn: (input, context) => context.userService.create(input),
|
|
305
|
+
* assertFn: (actual, expected) => { expect(actual).toEqual(expected); }
|
|
306
|
+
* };
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
export interface ScenarioTestSuite<TContext, TInput, TExpected> {
|
|
310
|
+
/** Test suite name */
|
|
311
|
+
suiteName: string;
|
|
312
|
+
/** Setup function executed before all scenarios */
|
|
313
|
+
beforeAll?: () => void | Promise<void>;
|
|
314
|
+
/** Cleanup function executed after all scenarios */
|
|
315
|
+
afterAll?: () => void | Promise<void>;
|
|
316
|
+
/** Setup function executed before each scenario */
|
|
317
|
+
beforeEach?: (scenario: TestScenario<TContext, TInput, TExpected>) => void | Promise<void>;
|
|
318
|
+
/** Cleanup function executed after each scenario */
|
|
319
|
+
afterEach?: (scenario: TestScenario<TContext, TInput, TExpected>) => void | Promise<void>;
|
|
320
|
+
/** Array of test scenarios */
|
|
321
|
+
scenarios: TestScenario<TContext, TInput, TExpected>[];
|
|
322
|
+
/** Function to execute for each scenario */
|
|
323
|
+
testFn: (input: TInput, context?: TContext) => Promise<TExpected> | TExpected;
|
|
324
|
+
/** Custom assertion function */
|
|
325
|
+
assertFn?: (actual: TExpected, expected: TExpected, scenario: TestScenario<TContext, TInput, TExpected>) => void;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Auto-mocked repository interface for database operation testing
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* const repository: AutoMockedRepository = {
|
|
333
|
+
* find: vi.fn().mockResolvedValue([]),
|
|
334
|
+
* findOne: vi.fn().mockResolvedValue(null),
|
|
335
|
+
* save: vi.fn().mockImplementation(entity => entity),
|
|
336
|
+
* create: vi.fn().mockImplementation(data => ({ id: '123', ...data })),
|
|
337
|
+
* // ... other methods
|
|
338
|
+
* };
|
|
339
|
+
*
|
|
340
|
+
* // Use in tests
|
|
341
|
+
* repository.find.mockResolvedValue([user1, user2]);
|
|
342
|
+
* const users = await repository.find();
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
export interface AutoMockedRepository {
|
|
346
|
+
/** Find entities matching criteria */
|
|
347
|
+
find: Vitest.Mock;
|
|
348
|
+
/** Find single entity */
|
|
349
|
+
findOne: Vitest.Mock;
|
|
350
|
+
/** Find single entity by criteria */
|
|
351
|
+
findOneBy: Vitest.Mock;
|
|
352
|
+
/** Find single entity or throw */
|
|
353
|
+
findOneOrFail: Vitest.Mock;
|
|
354
|
+
/** Find entities by criteria */
|
|
355
|
+
findBy: Vitest.Mock;
|
|
356
|
+
/** Find entities and get count */
|
|
357
|
+
findAndCount: Vitest.Mock;
|
|
358
|
+
/** Save entity */
|
|
359
|
+
save: Vitest.Mock;
|
|
360
|
+
/** Create entity instance */
|
|
361
|
+
create: Vitest.Mock;
|
|
362
|
+
/** Update entity */
|
|
363
|
+
update: Vitest.Mock;
|
|
364
|
+
/** Delete entity */
|
|
365
|
+
delete: Vitest.Mock;
|
|
366
|
+
/** Remove entity */
|
|
367
|
+
remove: Vitest.Mock;
|
|
368
|
+
/** Count entities */
|
|
369
|
+
count: Vitest.Mock;
|
|
370
|
+
/** Execute raw query */
|
|
371
|
+
query: Vitest.Mock;
|
|
372
|
+
/** Create query builder */
|
|
373
|
+
createQueryBuilder: Vitest.Mock;
|
|
374
|
+
/** Preload entity with relations */
|
|
375
|
+
preload: Vitest.Mock;
|
|
376
|
+
/** Merge entity changes */
|
|
377
|
+
merge: Vitest.Mock;
|
|
378
|
+
/** Soft delete entity */
|
|
379
|
+
softDelete: Vitest.Mock;
|
|
380
|
+
/** Restore soft deleted entity */
|
|
381
|
+
restore: Vitest.Mock;
|
|
382
|
+
/** Check if entity exists */
|
|
383
|
+
exist: Vitest.Mock;
|
|
384
|
+
/** Clear all entities */
|
|
385
|
+
clear: Vitest.Mock;
|
|
386
|
+
/** Increment field value */
|
|
387
|
+
increment: Vitest.Mock;
|
|
388
|
+
/** Decrement field value */
|
|
389
|
+
decrement: Vitest.Mock;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Auto-mocked HTTP service interface for HTTP client testing
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```typescript
|
|
396
|
+
* const httpService: AutoMockedHttpService = {
|
|
397
|
+
* get: vi.fn().mockResolvedValue({ data: {} }),
|
|
398
|
+
* post: vi.fn().mockResolvedValue({ data: { id: '123' } }),
|
|
399
|
+
* put: vi.fn().mockResolvedValue({ data: { updated: true } }),
|
|
400
|
+
* // ... other methods
|
|
401
|
+
* };
|
|
402
|
+
*
|
|
403
|
+
* // Use in tests
|
|
404
|
+
* httpService.get.mockResolvedValue({ data: { users: [] } });
|
|
405
|
+
* const response = await httpService.get('/users');
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
export interface AutoMockedHttpService {
|
|
409
|
+
/** HTTP GET request */
|
|
410
|
+
get: Vitest.Mock;
|
|
411
|
+
/** HTTP POST request */
|
|
412
|
+
post: Vitest.Mock;
|
|
413
|
+
/** HTTP PUT request */
|
|
414
|
+
put: Vitest.Mock;
|
|
415
|
+
/** HTTP PATCH request */
|
|
416
|
+
patch: Vitest.Mock;
|
|
417
|
+
/** HTTP DELETE request */
|
|
418
|
+
delete: Vitest.Mock;
|
|
419
|
+
/** HTTP HEAD request */
|
|
420
|
+
head: Vitest.Mock;
|
|
421
|
+
/** HTTP OPTIONS request */
|
|
422
|
+
options: Vitest.Mock;
|
|
423
|
+
/** Generic HTTP request */
|
|
424
|
+
request: Vitest.Mock;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Auto-mocked configuration service interface for config testing
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* ```typescript
|
|
431
|
+
* const configService: AutoMockedConfigService = {
|
|
432
|
+
* get: vi.fn().mockImplementation((key) => mockConfig[key]),
|
|
433
|
+
* getOrThrow: vi.fn().mockImplementation((key) => {
|
|
434
|
+
* const value = mockConfig[key];
|
|
435
|
+
* if (value === undefined) throw new Error(`Config ${key} not found`);
|
|
436
|
+
* return value;
|
|
437
|
+
* }),
|
|
438
|
+
* has: vi.fn().mockImplementation((key) => key in mockConfig),
|
|
439
|
+
* set: vi.fn()
|
|
440
|
+
* };
|
|
441
|
+
* ```
|
|
442
|
+
*/
|
|
443
|
+
export interface AutoMockedConfigService {
|
|
444
|
+
/** Get configuration value */
|
|
445
|
+
get: Vitest.Mock;
|
|
446
|
+
/** Get configuration value or throw */
|
|
447
|
+
getOrThrow: Vitest.Mock;
|
|
448
|
+
/** Check if configuration key exists */
|
|
449
|
+
has: Vitest.Mock;
|
|
450
|
+
/** Set configuration value */
|
|
451
|
+
set: Vitest.Mock;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Database update operation result
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```typescript
|
|
458
|
+
* const result: UpdateResult = {
|
|
459
|
+
* affected: 3,
|
|
460
|
+
* raw: { changedRows: 3 },
|
|
461
|
+
* generatedMaps: []
|
|
462
|
+
* };
|
|
463
|
+
*
|
|
464
|
+
* expect(result.affected).toBe(3);
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
export interface UpdateResult {
|
|
468
|
+
/** Number of affected rows */
|
|
469
|
+
affected: number;
|
|
470
|
+
/** Raw database response */
|
|
471
|
+
raw: Record<string, unknown>;
|
|
472
|
+
/** Generated entity maps */
|
|
473
|
+
generatedMaps: unknown[];
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Database delete operation result
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```typescript
|
|
480
|
+
* const result: DeleteResult = {
|
|
481
|
+
* affected: 1,
|
|
482
|
+
* raw: { deletedRows: 1 }
|
|
483
|
+
* };
|
|
484
|
+
*
|
|
485
|
+
* expect(result.affected).toBe(1);
|
|
486
|
+
* ```
|
|
487
|
+
*/
|
|
488
|
+
export interface DeleteResult {
|
|
489
|
+
/** Number of affected rows */
|
|
490
|
+
affected: number;
|
|
491
|
+
/** Raw database response */
|
|
492
|
+
raw: Record<string, unknown>;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* HTTP HEAD response interface
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* ```typescript
|
|
499
|
+
* const response: HeadResponse = {
|
|
500
|
+
* headers: {
|
|
501
|
+
* 'content-length': '1024',
|
|
502
|
+
* 'last-modified': 'Wed, 21 Oct 2015 07:28:00 GMT'
|
|
503
|
+
* }
|
|
504
|
+
* };
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
export interface HeadResponse {
|
|
508
|
+
/** Response headers */
|
|
509
|
+
headers: Record<string, unknown>;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Generic data response interface
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* const response: DataResponse = {
|
|
517
|
+
* data: {
|
|
518
|
+
* users: [{ id: '1', name: 'John' }],
|
|
519
|
+
* total: 1
|
|
520
|
+
* }
|
|
521
|
+
* };
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
export interface DataResponse {
|
|
525
|
+
/** Response data */
|
|
526
|
+
data: Record<string, unknown>;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Mock definition interface for configuring mock objects
|
|
530
|
+
*
|
|
531
|
+
* @typeParam T - Type being mocked
|
|
532
|
+
*
|
|
533
|
+
* @example
|
|
534
|
+
* ```typescript
|
|
535
|
+
* const definition: MockDefinition<UserService> = {
|
|
536
|
+
* methods: ['create', 'update', 'delete'],
|
|
537
|
+
* properties: { isInitialized: true },
|
|
538
|
+
* defaultImplementations: {
|
|
539
|
+
* create: vi.fn().mockResolvedValue({ id: '123' })
|
|
540
|
+
* }
|
|
541
|
+
* };
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
export interface MockDefinition<T> {
|
|
545
|
+
/** Methods to mock */
|
|
546
|
+
methods?: Array<keyof T | string>;
|
|
547
|
+
/** Properties to set */
|
|
548
|
+
properties?: Partial<T>;
|
|
549
|
+
/** Default method implementations */
|
|
550
|
+
defaultImplementations?: Partial<T>;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Auto mock schema for defining mock behavior
|
|
554
|
+
*
|
|
555
|
+
* @typeParam T - Type being mocked
|
|
556
|
+
*
|
|
557
|
+
* @example
|
|
558
|
+
* ```typescript
|
|
559
|
+
* const schema: AutoMockSchema<UserService> = {
|
|
560
|
+
* create: 'promise',
|
|
561
|
+
* update: { returns: { success: true } },
|
|
562
|
+
* delete: 'function',
|
|
563
|
+
* isActive: 'value'
|
|
564
|
+
* };
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
export type AutoMockSchema<T> = {
|
|
568
|
+
[K in keyof T]: 'function' | 'promise' | 'value' | {
|
|
569
|
+
returns: unknown;
|
|
570
|
+
};
|
|
571
|
+
};
|
|
572
|
+
/**
|
|
573
|
+
* Conditional mock condition for dynamic mock behavior
|
|
574
|
+
*
|
|
575
|
+
* @typeParam TArgs - Function argument types
|
|
576
|
+
* @typeParam TReturn - Return type
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* ```typescript
|
|
580
|
+
* const condition: ConditionalMockCondition<[string], User | null> = {
|
|
581
|
+
* when: (id: string) => id === 'invalid',
|
|
582
|
+
* then: null
|
|
583
|
+
* };
|
|
584
|
+
*
|
|
585
|
+
* // Apply condition to mock
|
|
586
|
+
* mock.findUser.mockImplementation((id) => {
|
|
587
|
+
* if (condition.when(id)) return condition.then;
|
|
588
|
+
* return defaultUser;
|
|
589
|
+
* });
|
|
590
|
+
* ```
|
|
591
|
+
*/
|
|
592
|
+
export interface ConditionalMockCondition<TArgs extends unknown[], TReturn> {
|
|
593
|
+
/** Condition function */
|
|
594
|
+
when: (...args: TArgs) => boolean;
|
|
595
|
+
/** Value to return when condition is met */
|
|
596
|
+
then: TReturn | Error;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Mock call expectation for verifying method calls
|
|
600
|
+
*
|
|
601
|
+
* @typeParam T - Type being mocked
|
|
602
|
+
*
|
|
603
|
+
* @example
|
|
604
|
+
* ```typescript
|
|
605
|
+
* const expectation: MockCallExpectation<UserService> = {
|
|
606
|
+
* method: 'create',
|
|
607
|
+
* args: [{ name: 'John', email: 'john@test.com' }],
|
|
608
|
+
* times: 1,
|
|
609
|
+
* returns: { id: '123', name: 'John' }
|
|
610
|
+
* };
|
|
611
|
+
*
|
|
612
|
+
* // Verify expectation
|
|
613
|
+
* expect(mockUserService.create).toHaveBeenCalledTimes(expectation.times);
|
|
614
|
+
* expect(mockUserService.create).toHaveBeenCalledWith(...expectation.args);
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
export interface MockCallExpectation<T> {
|
|
618
|
+
/** Method name to expect */
|
|
619
|
+
method: keyof T;
|
|
620
|
+
/** Expected arguments */
|
|
621
|
+
args?: unknown[];
|
|
622
|
+
/** Expected number of calls */
|
|
623
|
+
times?: number;
|
|
624
|
+
/** Expected return value */
|
|
625
|
+
returns?: unknown;
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Scenario group for organizing related test scenarios
|
|
629
|
+
*
|
|
630
|
+
* @typeParam TContext - Type of the test context
|
|
631
|
+
* @typeParam TInput - Type of the test input
|
|
632
|
+
* @typeParam TExpected - Type of the expected result
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```typescript
|
|
636
|
+
* const userValidationGroup: ScenarioGroup<UserService, CreateUserInput, ValidationResult> = {
|
|
637
|
+
* name: 'User Validation Tests',
|
|
638
|
+
* scenarios: [
|
|
639
|
+
* emailValidationScenario,
|
|
640
|
+
* nameValidationScenario,
|
|
641
|
+
* ageValidationScenario
|
|
642
|
+
* ],
|
|
643
|
+
* commonSetup: async (context) => {
|
|
644
|
+
* await context.userService.initialize();
|
|
645
|
+
* },
|
|
646
|
+
* commonTeardown: async (context) => {
|
|
647
|
+
* await context.userService.cleanup();
|
|
648
|
+
* }
|
|
649
|
+
* };
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
export interface ScenarioGroup<TContext, TInput, TExpected> {
|
|
653
|
+
/** Group name */
|
|
654
|
+
name: string;
|
|
655
|
+
/** Scenarios in this group */
|
|
656
|
+
scenarios: TestScenario<TContext, TInput, TExpected>[];
|
|
657
|
+
/** Common setup for all scenarios */
|
|
658
|
+
commonSetup?: (context?: TContext) => void | Promise<void>;
|
|
659
|
+
/** Common teardown for all scenarios */
|
|
660
|
+
commonTeardown?: (context?: TContext) => void | Promise<void>;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Scenario result tracker for complex assertions and reporting
|
|
664
|
+
*
|
|
665
|
+
* @typeParam T - Type of the result value
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```typescript
|
|
669
|
+
* const result: ScenarioResult<User> = {
|
|
670
|
+
* scenario: 'Create user with valid email',
|
|
671
|
+
* passed: true,
|
|
672
|
+
* actual: { id: '123', name: 'John', email: 'john@test.com' },
|
|
673
|
+
* expected: { id: expect.any(String), name: 'John', email: 'john@test.com' },
|
|
674
|
+
* duration: 45 // milliseconds
|
|
675
|
+
* };
|
|
676
|
+
*
|
|
677
|
+
* // Failed scenario
|
|
678
|
+
* const failedResult: ScenarioResult<User> = {
|
|
679
|
+
* scenario: 'Create user with invalid email',
|
|
680
|
+
* passed: false,
|
|
681
|
+
* actual: null,
|
|
682
|
+
* expected: { error: 'Invalid email format' },
|
|
683
|
+
* error: new Error('Validation failed'),
|
|
684
|
+
* duration: 12
|
|
685
|
+
* };
|
|
686
|
+
* ```
|
|
687
|
+
*/
|
|
688
|
+
export interface ScenarioResult<T> {
|
|
689
|
+
/** Scenario name */
|
|
690
|
+
scenario: string;
|
|
691
|
+
/** Whether scenario passed */
|
|
692
|
+
passed: boolean;
|
|
693
|
+
/** Actual result */
|
|
694
|
+
actual: T;
|
|
695
|
+
/** Expected result */
|
|
696
|
+
expected: T;
|
|
697
|
+
/** Error if scenario failed */
|
|
698
|
+
error?: Error;
|
|
699
|
+
/** Execution duration in milliseconds */
|
|
700
|
+
duration: number;
|
|
701
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from './types';
|