@nestia/e2e 7.0.3 → 7.1.1-dev.20250714

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.
@@ -1,280 +1,280 @@
1
- /**
2
- * Type-safe comparator functions for Array.sort() operations with advanced
3
- * field access.
4
- *
5
- * GaffComparator provides a collection of specialized comparator functions
6
- * designed to work seamlessly with Array.sort() and testing frameworks like
7
- * TestValidator.sort(). Each comparator supports both single values and arrays
8
- * of values, enabling complex multi-field sorting scenarios with lexicographic
9
- * ordering.
10
- *
11
- * Key features:
12
- *
13
- * - Generic type safety for any object structure
14
- * - Support for single values or arrays of values per field
15
- * - Lexicographic comparison for multi-value scenarios
16
- * - Locale-aware string comparison
17
- * - Automatic type conversion for dates and numbers
18
- *
19
- * The comparators follow the standard JavaScript sort contract:
20
- *
21
- * - Return < 0 if first element should come before second
22
- * - Return > 0 if first element should come after second
23
- * - Return 0 if elements are equal
24
- *
25
- * @author Jeongho Nam - https://github.com/samchon
26
- * @example
27
- * ```typescript
28
- * // Basic usage with single fields
29
- * users.sort(GaffComparator.strings(user => user.name));
30
- * posts.sort(GaffComparator.dates(post => post.createdAt));
31
- * products.sort(GaffComparator.numbers(product => product.price));
32
- *
33
- * // Multi-field sorting with arrays
34
- * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
35
- * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
36
- *
37
- * // Integration with TestValidator
38
- * await TestValidator.sort("user sorting")(
39
- * (sortable) => api.getUsers({ sort: sortable })
40
- * )("name", "email")(
41
- * GaffComparator.strings(user => [user.name, user.email])
42
- * )("+");
43
- * ```;
44
- */
45
- export namespace GaffComparator {
46
- /**
47
- * Creates a comparator function for string-based sorting with locale-aware
48
- * comparison.
49
- *
50
- * Generates a comparator that extracts string values from objects and
51
- * performs lexicographic comparison using locale-sensitive string comparison.
52
- * Supports both single strings and arrays of strings for multi-field sorting
53
- * scenarios.
54
- *
55
- * When comparing arrays, performs lexicographic ordering: compares the first
56
- * elements, then the second elements if the first are equal, and so on. This
57
- * enables complex sorting like "sort by last name, then by first name".
58
- *
59
- * @example
60
- * ```typescript
61
- * interface User {
62
- * id: string;
63
- * firstName: string;
64
- * lastName: string;
65
- * email: string;
66
- * status: 'active' | 'inactive';
67
- * }
68
- *
69
- * const users: User[] = [
70
- * { id: '1', firstName: 'John', lastName: 'Doe', email: 'john@example.com', status: 'active' },
71
- * { id: '2', firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', status: 'inactive' },
72
- * { id: '3', firstName: 'Bob', lastName: 'Smith', email: 'bob@example.com', status: 'active' }
73
- * ];
74
- *
75
- * // Single field sorting
76
- * users.sort(GaffComparator.strings(user => user.lastName));
77
- * // Result: Doe, Doe, Smith
78
- *
79
- * // Multi-field sorting: last name, then first name
80
- * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
81
- * // Result: Doe Jane, Doe John, Smith Bob
82
- *
83
- * // Status-based sorting
84
- * users.sort(GaffComparator.strings(user => user.status));
85
- * // Result: active users first, then inactive
86
- *
87
- * // Complex multi-field: status, then last name, then first name
88
- * users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
89
- *
90
- * // Integration with API sorting validation
91
- * await TestValidator.sort("user name sorting")(
92
- * (sortFields) => userApi.getUsers({ sort: sortFields })
93
- * )("lastName", "firstName")(
94
- * GaffComparator.strings(user => [user.lastName, user.firstName])
95
- * )("+");
96
- * ```;
97
- *
98
- * @template T - The type of objects being compared
99
- * @param getter - Function that extracts string value(s) from input objects
100
- * @returns A comparator function suitable for Array.sort()
101
- */
102
- export const strings =
103
- <T>(getter: (input: T) => string | string[]) =>
104
- (x: T, y: T): number => {
105
- const a: string[] = wrap(getter(x));
106
- const b: string[] = wrap(getter(y));
107
-
108
- const idx: number = a.findIndex((v, i) => v !== b[i]);
109
- return idx !== -1 ? compare(a[idx], b[idx]) : 0;
110
- };
111
-
112
- /**
113
- * Creates a comparator function for date-based sorting with automatic string
114
- * parsing.
115
- *
116
- * Generates a comparator that extracts date values from objects,
117
- * automatically converting string representations to Date objects for
118
- * numerical comparison. Supports both single dates and arrays of dates for
119
- * complex temporal sorting.
120
- *
121
- * Date strings are parsed using the standard Date constructor, which supports
122
- * ISO 8601 format, RFC 2822 format, and other common date representations.
123
- * The comparison is performed on millisecond timestamps for precise
124
- * ordering.
125
- *
126
- * @example
127
- * ```typescript
128
- * interface Event {
129
- * id: string;
130
- * title: string;
131
- * startDate: string;
132
- * endDate: string;
133
- * createdAt: string;
134
- * updatedAt: string;
135
- * }
136
- *
137
- * const events: Event[] = [
138
- * {
139
- * id: '1',
140
- * title: 'Conference',
141
- * startDate: '2024-03-15T09:00:00Z',
142
- * endDate: '2024-03-15T17:00:00Z',
143
- * createdAt: '2024-01-10T10:00:00Z',
144
- * updatedAt: '2024-02-01T15:30:00Z'
145
- * },
146
- * {
147
- * id: '2',
148
- * title: 'Workshop',
149
- * startDate: '2024-03-10T14:00:00Z',
150
- * endDate: '2024-03-10T16:00:00Z',
151
- * createdAt: '2024-01-15T11:00:00Z',
152
- * updatedAt: '2024-01-20T09:15:00Z'
153
- * }
154
- * ];
155
- *
156
- * // Sort by start date (chronological order)
157
- * events.sort(GaffComparator.dates(event => event.startDate));
158
- *
159
- * // Sort by creation date (oldest first)
160
- * events.sort(GaffComparator.dates(event => event.createdAt));
161
- *
162
- * // Multi-field: start date, then end date
163
- * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
164
- *
165
- * // Sort by modification history: created date, then updated date
166
- * events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
167
- *
168
- * // Validate API date sorting
169
- * await TestValidator.sort("event chronological sorting")(
170
- * (sortFields) => eventApi.getEvents({ sort: sortFields })
171
- * )("startDate")(
172
- * GaffComparator.dates(event => event.startDate)
173
- * )("+");
174
- *
175
- * // Test complex date-based sorting
176
- * const sortByEventSchedule = GaffComparator.dates(event => [
177
- * event.startDate,
178
- * event.endDate
179
- * ]);
180
- * ```;
181
- *
182
- * @template T - The type of objects being compared
183
- * @param getter - Function that extracts date string(s) from input objects
184
- * @returns A comparator function suitable for Array.sort()
185
- */
186
- export const dates =
187
- <T>(getter: (input: T) => string | string[]) =>
188
- (x: T, y: T): number => {
189
- const take = (v: T) =>
190
- wrap(getter(v)).map((str) => new Date(str).getTime());
191
- const a: number[] = take(x);
192
- const b: number[] = take(y);
193
-
194
- const idx: number = a.findIndex((v, i) => v !== b[i]);
195
- return idx !== -1 ? a[idx] - b[idx] : 0;
196
- };
197
-
198
- /**
199
- * Creates a comparator function for numerical sorting with multi-value
200
- * support.
201
- *
202
- * Generates a comparator that extracts numerical values from objects and
203
- * performs mathematical comparison. Supports both single numbers and arrays
204
- * of numbers for complex numerical sorting scenarios like sorting by price
205
- * then by rating.
206
- *
207
- * When comparing arrays, performs lexicographic numerical ordering: compares
208
- * the first numbers, then the second numbers if the first are equal, and so
209
- * on. This enables sophisticated sorting like "sort by price ascending, then
210
- * by rating descending".
211
- *
212
- * @example
213
- * ```typescript
214
- * interface Product {
215
- * id: string;
216
- * name: string;
217
- * price: number;
218
- * rating: number;
219
- * stock: number;
220
- * categoryId: number;
221
- * salesCount: number;
222
- * }
223
- *
224
- * const products: Product[] = [
225
- * { id: '1', name: 'Laptop', price: 999.99, rating: 4.5, stock: 15, categoryId: 1, salesCount: 150 },
226
- * { id: '2', name: 'Mouse', price: 29.99, rating: 4.2, stock: 50, categoryId: 1, salesCount: 300 },
227
- * { id: '3', name: 'Keyboard', price: 79.99, rating: 4.8, stock: 25, categoryId: 1, salesCount: 200 }
228
- * ];
229
- *
230
- * // Sort by price (ascending)
231
- * products.sort(GaffComparator.numbers(product => product.price));
232
- * // Result: Mouse ($29.99), Keyboard ($79.99), Laptop ($999.99)
233
- *
234
- * // Sort by rating (descending requires negation)
235
- * products.sort(GaffComparator.numbers(product => -product.rating));
236
- * // Result: Keyboard (4.8), Laptop (4.5), Mouse (4.2)
237
- *
238
- * // Multi-field: category, then price
239
- * products.sort(GaffComparator.numbers(product => [product.categoryId, product.price]));
240
- *
241
- * // Complex business logic: popularity (sales) then rating
242
- * products.sort(GaffComparator.numbers(product => [-product.salesCount, -product.rating]));
243
- * // Negative values for descending order
244
- *
245
- * // Sort by inventory priority: low stock first, then by sales
246
- * products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
247
- *
248
- * // Validate API numerical sorting
249
- * await TestValidator.sort("product price sorting")(
250
- * (sortFields) => productApi.getProducts({ sort: sortFields })
251
- * )("price")(
252
- * GaffComparator.numbers(product => product.price)
253
- * )("+");
254
- *
255
- * // Test multi-criteria sorting
256
- * const sortByBusinessValue = GaffComparator.numbers(product => [
257
- * -product.salesCount, // High sales first
258
- * -product.rating, // High rating first
259
- * product.price // Low price first (for tie-breaking)
260
- * ]);
261
- * ```;
262
- *
263
- * @template T - The type of objects being compared
264
- * @param closure - Function that extracts number value(s) from input objects
265
- * @returns A comparator function suitable for Array.sort()
266
- */
267
- export const numbers =
268
- <T>(closure: (input: T) => number | number[]) =>
269
- (x: T, y: T): number => {
270
- const a: number[] = wrap(closure(x));
271
- const b: number[] = wrap(closure(y));
272
-
273
- const idx: number = a.findIndex((v, i) => v !== b[i]);
274
- return idx !== -1 ? a[idx] - b[idx] : 0;
275
- };
276
-
277
- const compare = (x: string, y: string) => x.localeCompare(y);
278
-
279
- const wrap = <T>(elem: T | T[]): T[] => (Array.isArray(elem) ? elem : [elem]);
280
- }
1
+ /**
2
+ * Type-safe comparator functions for Array.sort() operations with advanced
3
+ * field access.
4
+ *
5
+ * GaffComparator provides a collection of specialized comparator functions
6
+ * designed to work seamlessly with Array.sort() and testing frameworks like
7
+ * TestValidator.sort(). Each comparator supports both single values and arrays
8
+ * of values, enabling complex multi-field sorting scenarios with lexicographic
9
+ * ordering.
10
+ *
11
+ * Key features:
12
+ *
13
+ * - Generic type safety for any object structure
14
+ * - Support for single values or arrays of values per field
15
+ * - Lexicographic comparison for multi-value scenarios
16
+ * - Locale-aware string comparison
17
+ * - Automatic type conversion for dates and numbers
18
+ *
19
+ * The comparators follow the standard JavaScript sort contract:
20
+ *
21
+ * - Return < 0 if first element should come before second
22
+ * - Return > 0 if first element should come after second
23
+ * - Return 0 if elements are equal
24
+ *
25
+ * @author Jeongho Nam - https://github.com/samchon
26
+ * @example
27
+ * ```typescript
28
+ * // Basic usage with single fields
29
+ * users.sort(GaffComparator.strings(user => user.name));
30
+ * posts.sort(GaffComparator.dates(post => post.createdAt));
31
+ * products.sort(GaffComparator.numbers(product => product.price));
32
+ *
33
+ * // Multi-field sorting with arrays
34
+ * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
35
+ * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
36
+ *
37
+ * // Integration with TestValidator
38
+ * await TestValidator.sort("user sorting")(
39
+ * (sortable) => api.getUsers({ sort: sortable })
40
+ * )("name", "email")(
41
+ * GaffComparator.strings(user => [user.name, user.email])
42
+ * )("+");
43
+ * ```;
44
+ */
45
+ export namespace GaffComparator {
46
+ /**
47
+ * Creates a comparator function for string-based sorting with locale-aware
48
+ * comparison.
49
+ *
50
+ * Generates a comparator that extracts string values from objects and
51
+ * performs lexicographic comparison using locale-sensitive string comparison.
52
+ * Supports both single strings and arrays of strings for multi-field sorting
53
+ * scenarios.
54
+ *
55
+ * When comparing arrays, performs lexicographic ordering: compares the first
56
+ * elements, then the second elements if the first are equal, and so on. This
57
+ * enables complex sorting like "sort by last name, then by first name".
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * interface User {
62
+ * id: string;
63
+ * firstName: string;
64
+ * lastName: string;
65
+ * email: string;
66
+ * status: 'active' | 'inactive';
67
+ * }
68
+ *
69
+ * const users: User[] = [
70
+ * { id: '1', firstName: 'John', lastName: 'Doe', email: 'john@example.com', status: 'active' },
71
+ * { id: '2', firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', status: 'inactive' },
72
+ * { id: '3', firstName: 'Bob', lastName: 'Smith', email: 'bob@example.com', status: 'active' }
73
+ * ];
74
+ *
75
+ * // Single field sorting
76
+ * users.sort(GaffComparator.strings(user => user.lastName));
77
+ * // Result: Doe, Doe, Smith
78
+ *
79
+ * // Multi-field sorting: last name, then first name
80
+ * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
81
+ * // Result: Doe Jane, Doe John, Smith Bob
82
+ *
83
+ * // Status-based sorting
84
+ * users.sort(GaffComparator.strings(user => user.status));
85
+ * // Result: active users first, then inactive
86
+ *
87
+ * // Complex multi-field: status, then last name, then first name
88
+ * users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
89
+ *
90
+ * // Integration with API sorting validation
91
+ * await TestValidator.sort("user name sorting")(
92
+ * (sortFields) => userApi.getUsers({ sort: sortFields })
93
+ * )("lastName", "firstName")(
94
+ * GaffComparator.strings(user => [user.lastName, user.firstName])
95
+ * )("+");
96
+ * ```;
97
+ *
98
+ * @template T - The type of objects being compared
99
+ * @param getter - Function that extracts string value(s) from input objects
100
+ * @returns A comparator function suitable for Array.sort()
101
+ */
102
+ export const strings =
103
+ <T>(getter: (input: T) => string | string[]) =>
104
+ (x: T, y: T): number => {
105
+ const a: string[] = wrap(getter(x));
106
+ const b: string[] = wrap(getter(y));
107
+
108
+ const idx: number = a.findIndex((v, i) => v !== b[i]);
109
+ return idx !== -1 ? compare(a[idx], b[idx]) : 0;
110
+ };
111
+
112
+ /**
113
+ * Creates a comparator function for date-based sorting with automatic string
114
+ * parsing.
115
+ *
116
+ * Generates a comparator that extracts date values from objects,
117
+ * automatically converting string representations to Date objects for
118
+ * numerical comparison. Supports both single dates and arrays of dates for
119
+ * complex temporal sorting.
120
+ *
121
+ * Date strings are parsed using the standard Date constructor, which supports
122
+ * ISO 8601 format, RFC 2822 format, and other common date representations.
123
+ * The comparison is performed on millisecond timestamps for precise
124
+ * ordering.
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * interface Event {
129
+ * id: string;
130
+ * title: string;
131
+ * startDate: string;
132
+ * endDate: string;
133
+ * createdAt: string;
134
+ * updatedAt: string;
135
+ * }
136
+ *
137
+ * const events: Event[] = [
138
+ * {
139
+ * id: '1',
140
+ * title: 'Conference',
141
+ * startDate: '2024-03-15T09:00:00Z',
142
+ * endDate: '2024-03-15T17:00:00Z',
143
+ * createdAt: '2024-01-10T10:00:00Z',
144
+ * updatedAt: '2024-02-01T15:30:00Z'
145
+ * },
146
+ * {
147
+ * id: '2',
148
+ * title: 'Workshop',
149
+ * startDate: '2024-03-10T14:00:00Z',
150
+ * endDate: '2024-03-10T16:00:00Z',
151
+ * createdAt: '2024-01-15T11:00:00Z',
152
+ * updatedAt: '2024-01-20T09:15:00Z'
153
+ * }
154
+ * ];
155
+ *
156
+ * // Sort by start date (chronological order)
157
+ * events.sort(GaffComparator.dates(event => event.startDate));
158
+ *
159
+ * // Sort by creation date (oldest first)
160
+ * events.sort(GaffComparator.dates(event => event.createdAt));
161
+ *
162
+ * // Multi-field: start date, then end date
163
+ * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
164
+ *
165
+ * // Sort by modification history: created date, then updated date
166
+ * events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
167
+ *
168
+ * // Validate API date sorting
169
+ * await TestValidator.sort("event chronological sorting")(
170
+ * (sortFields) => eventApi.getEvents({ sort: sortFields })
171
+ * )("startDate")(
172
+ * GaffComparator.dates(event => event.startDate)
173
+ * )("+");
174
+ *
175
+ * // Test complex date-based sorting
176
+ * const sortByEventSchedule = GaffComparator.dates(event => [
177
+ * event.startDate,
178
+ * event.endDate
179
+ * ]);
180
+ * ```;
181
+ *
182
+ * @template T - The type of objects being compared
183
+ * @param getter - Function that extracts date string(s) from input objects
184
+ * @returns A comparator function suitable for Array.sort()
185
+ */
186
+ export const dates =
187
+ <T>(getter: (input: T) => string | string[]) =>
188
+ (x: T, y: T): number => {
189
+ const take = (v: T) =>
190
+ wrap(getter(v)).map((str) => new Date(str).getTime());
191
+ const a: number[] = take(x);
192
+ const b: number[] = take(y);
193
+
194
+ const idx: number = a.findIndex((v, i) => v !== b[i]);
195
+ return idx !== -1 ? a[idx] - b[idx] : 0;
196
+ };
197
+
198
+ /**
199
+ * Creates a comparator function for numerical sorting with multi-value
200
+ * support.
201
+ *
202
+ * Generates a comparator that extracts numerical values from objects and
203
+ * performs mathematical comparison. Supports both single numbers and arrays
204
+ * of numbers for complex numerical sorting scenarios like sorting by price
205
+ * then by rating.
206
+ *
207
+ * When comparing arrays, performs lexicographic numerical ordering: compares
208
+ * the first numbers, then the second numbers if the first are equal, and so
209
+ * on. This enables sophisticated sorting like "sort by price ascending, then
210
+ * by rating descending".
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * interface Product {
215
+ * id: string;
216
+ * name: string;
217
+ * price: number;
218
+ * rating: number;
219
+ * stock: number;
220
+ * categoryId: number;
221
+ * salesCount: number;
222
+ * }
223
+ *
224
+ * const products: Product[] = [
225
+ * { id: '1', name: 'Laptop', price: 999.99, rating: 4.5, stock: 15, categoryId: 1, salesCount: 150 },
226
+ * { id: '2', name: 'Mouse', price: 29.99, rating: 4.2, stock: 50, categoryId: 1, salesCount: 300 },
227
+ * { id: '3', name: 'Keyboard', price: 79.99, rating: 4.8, stock: 25, categoryId: 1, salesCount: 200 }
228
+ * ];
229
+ *
230
+ * // Sort by price (ascending)
231
+ * products.sort(GaffComparator.numbers(product => product.price));
232
+ * // Result: Mouse ($29.99), Keyboard ($79.99), Laptop ($999.99)
233
+ *
234
+ * // Sort by rating (descending requires negation)
235
+ * products.sort(GaffComparator.numbers(product => -product.rating));
236
+ * // Result: Keyboard (4.8), Laptop (4.5), Mouse (4.2)
237
+ *
238
+ * // Multi-field: category, then price
239
+ * products.sort(GaffComparator.numbers(product => [product.categoryId, product.price]));
240
+ *
241
+ * // Complex business logic: popularity (sales) then rating
242
+ * products.sort(GaffComparator.numbers(product => [-product.salesCount, -product.rating]));
243
+ * // Negative values for descending order
244
+ *
245
+ * // Sort by inventory priority: low stock first, then by sales
246
+ * products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
247
+ *
248
+ * // Validate API numerical sorting
249
+ * await TestValidator.sort("product price sorting")(
250
+ * (sortFields) => productApi.getProducts({ sort: sortFields })
251
+ * )("price")(
252
+ * GaffComparator.numbers(product => product.price)
253
+ * )("+");
254
+ *
255
+ * // Test multi-criteria sorting
256
+ * const sortByBusinessValue = GaffComparator.numbers(product => [
257
+ * -product.salesCount, // High sales first
258
+ * -product.rating, // High rating first
259
+ * product.price // Low price first (for tie-breaking)
260
+ * ]);
261
+ * ```;
262
+ *
263
+ * @template T - The type of objects being compared
264
+ * @param closure - Function that extracts number value(s) from input objects
265
+ * @returns A comparator function suitable for Array.sort()
266
+ */
267
+ export const numbers =
268
+ <T>(closure: (input: T) => number | number[]) =>
269
+ (x: T, y: T): number => {
270
+ const a: number[] = wrap(closure(x));
271
+ const b: number[] = wrap(closure(y));
272
+
273
+ const idx: number = a.findIndex((v, i) => v !== b[i]);
274
+ return idx !== -1 ? a[idx] - b[idx] : 0;
275
+ };
276
+
277
+ const compare = (x: string, y: string) => x.localeCompare(y);
278
+
279
+ const wrap = <T>(elem: T | T[]): T[] => (Array.isArray(elem) ? elem : [elem]);
280
+ }