@nestia/e2e 14.0.1 → 14.0.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.
@@ -22,27 +22,40 @@
22
22
  * - Return > 0 if first element should come after second
23
23
  * - Return 0 if elements are equal
24
24
  *
25
+ * Processing cost: Each comparison extracts both key lists and visits their
26
+ * common prefix until the first difference; date keys additionally parse all
27
+ * supplied strings once per comparison. No sort or repeated scan is performed
28
+ * inside a comparison.
29
+ *
25
30
  * @author Jeongho Nam - https://github.com/samchon
26
31
  * @example
27
- * ```typescript
28
32
  * // 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));
33
+ * users.sort(GaffComparator.strings((user) => user.name));
34
+ * posts.sort(GaffComparator.dates((post) => post.createdAt));
35
+ * products.sort(GaffComparator.numbers((product) => product.price));
32
36
  *
33
37
  * // 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]));
38
+ * users.sort(
39
+ * GaffComparator.strings((user) => [user.lastName, user.firstName]),
40
+ * );
41
+ * events.sort(
42
+ * GaffComparator.dates((event) => [event.startDate, event.endDate]),
43
+ * );
36
44
  *
37
45
  * // Integration with TestValidator's currying pattern
38
- * const validator = TestValidator.sort("user sorting",
39
- * (sortable) => api.getUsers({ sort: sortable })
40
- * )("name", "email")(
41
- * GaffComparator.strings(user => [user.name, user.email])
42
- * );
46
+ * const validator = TestValidator.sort("user sorting", (sortable) =>
47
+ * api.getUsers({ sort: sortable }),
48
+ * )(
49
+ * "name",
50
+ * "email",
51
+ * )(GaffComparator.strings((user) => [user.name, user.email]));
43
52
  * await validator("+"); // ascending
44
53
  * await validator("-"); // descending
45
- * ```;
54
+ *
55
+ * @evidence contracts/common.md#principled-implementation Each comparator maps both operands to arrays of comparable values and decides by the first position where they differ, then by array length, which is a lexicographic order that satisfies the sort contract for well-defined values; it is used to check server-side sorting from the client.
56
+ * @evidence contracts/common.md#clear-and-simple-design Three comparators share scalar-to-array wrapping. Strings compare each key by collation; dates and numbers use a shared strict mismatch search over their numeric keys.
57
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The ordering rule is generic in the getter, with no field, entity, or locale special case.
58
+ * @evidence contracts/common.md#meaningful-documentation The namespace prose lists the features and the sort contract with an example.
46
59
  */
47
60
  export declare namespace GaffComparator {
48
61
  /**
@@ -56,52 +69,89 @@ export declare namespace GaffComparator {
56
69
  *
57
70
  * When comparing arrays, performs lexicographic ordering: compares the first
58
71
  * elements, then the second elements if the first are equal, and so on. This
59
- * enables complex sorting like "sort by last name, then by first name".
72
+ * enables complex sorting like "sort by last name, then by first name". Keys
73
+ * that compare equal under the runtime's collation, including different
74
+ * canonically equivalent Unicode spellings, continue to the next key. If the
75
+ * whole common prefix compares equal, the shorter key list sorts first.
76
+ *
77
+ * Processing cost: Both getters run once and a bounded loop visits only
78
+ * common keys until the first collation difference. Work depends on examined
79
+ * keys and string comparison cost; scalar wrapping adds constant space.
60
80
  *
61
81
  * @example
62
- * ```typescript
63
82
  * interface User {
64
83
  * id: string;
65
84
  * firstName: string;
66
85
  * lastName: string;
67
86
  * email: string;
68
- * status: 'active' | 'inactive';
87
+ * status: "active" | "inactive";
69
88
  * }
70
89
  *
71
90
  * const users: User[] = [
72
- * { id: '1', firstName: 'John', lastName: 'Doe', email: 'john@example.com', status: 'active' },
73
- * { id: '2', firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', status: 'inactive' },
74
- * { id: '3', firstName: 'Bob', lastName: 'Smith', email: 'bob@example.com', status: 'active' }
91
+ * {
92
+ * id: "1",
93
+ * firstName: "John",
94
+ * lastName: "Doe",
95
+ * email: "john@example.com",
96
+ * status: "active",
97
+ * },
98
+ * {
99
+ * id: "2",
100
+ * firstName: "Jane",
101
+ * lastName: "Doe",
102
+ * email: "jane@example.com",
103
+ * status: "inactive",
104
+ * },
105
+ * {
106
+ * id: "3",
107
+ * firstName: "Bob",
108
+ * lastName: "Smith",
109
+ * email: "bob@example.com",
110
+ * status: "active",
111
+ * },
75
112
  * ];
76
113
  *
77
114
  * // Single field sorting
78
- * users.sort(GaffComparator.strings(user => user.lastName));
115
+ * users.sort(GaffComparator.strings((user) => user.lastName));
79
116
  * // Result: Doe, Doe, Smith
80
117
  *
81
118
  * // Multi-field sorting: last name, then first name
82
- * users.sort(GaffComparator.strings(user => [user.lastName, user.firstName]));
119
+ * users.sort(
120
+ * GaffComparator.strings((user) => [user.lastName, user.firstName]),
121
+ * );
83
122
  * // Result: Doe Jane, Doe John, Smith Bob
84
123
  *
85
124
  * // Status-based sorting
86
- * users.sort(GaffComparator.strings(user => user.status));
125
+ * users.sort(GaffComparator.strings((user) => user.status));
87
126
  * // Result: active users first, then inactive
88
127
  *
89
128
  * // Complex multi-field: status, then last name, then first name
90
- * users.sort(GaffComparator.strings(user => [user.status, user.lastName, user.firstName]));
129
+ * users.sort(
130
+ * GaffComparator.strings((user) => [
131
+ * user.status,
132
+ * user.lastName,
133
+ * user.firstName,
134
+ * ]),
135
+ * );
91
136
  *
92
137
  * // Integration with TestValidator sorting validation
93
- * const sortValidator = TestValidator.sort("user name sorting",
94
- * (sortFields) => userApi.getUsers({ sort: sortFields })
95
- * )("lastName", "firstName")(
96
- * GaffComparator.strings(user => [user.lastName, user.firstName])
97
- * );
138
+ * const sortValidator = TestValidator.sort(
139
+ * "user name sorting",
140
+ * (sortFields) => userApi.getUsers({ sort: sortFields }),
141
+ * )(
142
+ * "lastName",
143
+ * "firstName",
144
+ * )(GaffComparator.strings((user) => [user.lastName, user.firstName]));
98
145
  * await sortValidator("+"); // test ascending order
99
146
  * await sortValidator("-"); // test descending order
100
- * ```;
101
147
  *
102
148
  * @template T - The type of objects being compared
103
149
  * @param getter - Function that extracts string value(s) from input objects
104
150
  * @returns A comparator function suitable for Array.sort()
151
+ * @evidence contracts/common.md#principled-implementation Each common key position is compared once with localeCompare; a nonzero result decides the order, while collation-equal spellings continue to later keys. Only an entirely equal common prefix falls through to array length, establishing lexicographic order under the runtime's actual collation without assuming strict string equality.
152
+ * @evidence contracts/common.md#clear-and-simple-design Shared wrapping accepts scalar or array keys; one bounded loop returns the first nonzero collation result or the length difference.
153
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The comparison is the platform's locale collation, not a hand-written ordering.
154
+ * @evidence contracts/common.md#meaningful-documentation The comment states the locale sensitivity, the multi-value rule, and the arguments, with examples.
105
155
  */
106
156
  const strings: <T>(getter: (input: T) => string | string[]) => (x: T, y: T) => number;
107
157
  /**
@@ -118,8 +168,11 @@ export declare namespace GaffComparator {
118
168
  * The comparison is performed on millisecond timestamps for precise
119
169
  * ordering.
120
170
  *
171
+ * Processing cost: Both getters run once, each returned string is parsed
172
+ * once, and the bounded mismatch search visits at most the common key count.
173
+ * Numeric key arrays require space proportional to the two lists.
174
+ *
121
175
  * @example
122
- * ```typescript
123
176
  * interface Event {
124
177
  * id: string;
125
178
  * title: string;
@@ -131,53 +184,59 @@ export declare namespace GaffComparator {
131
184
  *
132
185
  * const events: Event[] = [
133
186
  * {
134
- * id: '1',
135
- * title: 'Conference',
136
- * startDate: '2024-03-15T09:00:00Z',
137
- * endDate: '2024-03-15T17:00:00Z',
138
- * createdAt: '2024-01-10T10:00:00Z',
139
- * updatedAt: '2024-02-01T15:30:00Z'
187
+ * id: "1",
188
+ * title: "Conference",
189
+ * startDate: "2024-03-15T09:00:00Z",
190
+ * endDate: "2024-03-15T17:00:00Z",
191
+ * createdAt: "2024-01-10T10:00:00Z",
192
+ * updatedAt: "2024-02-01T15:30:00Z",
140
193
  * },
141
194
  * {
142
- * id: '2',
143
- * title: 'Workshop',
144
- * startDate: '2024-03-10T14:00:00Z',
145
- * endDate: '2024-03-10T16:00:00Z',
146
- * createdAt: '2024-01-15T11:00:00Z',
147
- * updatedAt: '2024-01-20T09:15:00Z'
148
- * }
195
+ * id: "2",
196
+ * title: "Workshop",
197
+ * startDate: "2024-03-10T14:00:00Z",
198
+ * endDate: "2024-03-10T16:00:00Z",
199
+ * createdAt: "2024-01-15T11:00:00Z",
200
+ * updatedAt: "2024-01-20T09:15:00Z",
201
+ * },
149
202
  * ];
150
203
  *
151
204
  * // Sort by start date (chronological order)
152
- * events.sort(GaffComparator.dates(event => event.startDate));
205
+ * events.sort(GaffComparator.dates((event) => event.startDate));
153
206
  *
154
207
  * // Sort by creation date (oldest first)
155
- * events.sort(GaffComparator.dates(event => event.createdAt));
208
+ * events.sort(GaffComparator.dates((event) => event.createdAt));
156
209
  *
157
210
  * // Multi-field: start date, then end date
158
- * events.sort(GaffComparator.dates(event => [event.startDate, event.endDate]));
211
+ * events.sort(
212
+ * GaffComparator.dates((event) => [event.startDate, event.endDate]),
213
+ * );
159
214
  *
160
215
  * // Sort by modification history: created date, then updated date
161
- * events.sort(GaffComparator.dates(event => [event.createdAt, event.updatedAt]));
216
+ * events.sort(
217
+ * GaffComparator.dates((event) => [event.createdAt, event.updatedAt]),
218
+ * );
162
219
  *
163
220
  * // Validate API date sorting with TestValidator
164
- * const dateValidator = TestValidator.sort("event chronological sorting",
165
- * (sortFields) => eventApi.getEvents({ sort: sortFields })
166
- * )("startDate")(
167
- * GaffComparator.dates(event => event.startDate)
168
- * );
221
+ * const dateValidator = TestValidator.sort(
222
+ * "event chronological sorting",
223
+ * (sortFields) => eventApi.getEvents({ sort: sortFields }),
224
+ * )("startDate")(GaffComparator.dates((event) => event.startDate));
169
225
  * await dateValidator("+", true); // ascending with trace logging
170
226
  *
171
227
  * // Test complex date-based sorting
172
- * const sortByEventSchedule = GaffComparator.dates(event => [
228
+ * const sortByEventSchedule = GaffComparator.dates((event) => [
173
229
  * event.startDate,
174
- * event.endDate
230
+ * event.endDate,
175
231
  * ]);
176
- * ```;
177
232
  *
178
233
  * @template T - The type of objects being compared
179
234
  * @param getter - Function that extracts date string(s) from input objects
180
235
  * @returns A comparator function suitable for Array.sort()
236
+ * @evidence contracts/common.md#principled-implementation Each value is parsed by the `Date` constructor and compared by its millisecond timestamp, so ISO 8601 and the other formats the constructor accepts order correctly; a string the constructor cannot parse yields NaN, and the comparator then returns NaN, which a sort treats as equality, a limit the caller must respect by giving valid dates.
237
+ * @evidence contracts/common.md#clear-and-simple-design It uses the shared `wrap` and `mismatch`, and adds only the parsing.
238
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Parsing is the standard constructor with no format special cases.
239
+ * @evidence contracts/common.md#meaningful-documentation The comment states the accepted formats and the millisecond comparison, with examples.
181
240
  */
182
241
  const dates: <T>(getter: (input: T) => string | string[]) => (x: T, y: T) => number;
183
242
  /**
@@ -194,8 +253,11 @@ export declare namespace GaffComparator {
194
253
  * on. This enables sophisticated sorting like "sort by price ascending, then
195
254
  * by rating descending".
196
255
  *
256
+ * Processing cost: Both getters run once and mismatch visits only the common
257
+ * prefix until the first unequal key. Existing key arrays are reused, and
258
+ * scalar wrapping takes constant auxiliary space.
259
+ *
197
260
  * @example
198
- * ```typescript
199
261
  * interface Product {
200
262
  * id: string;
201
263
  * name: string;
@@ -207,49 +269,90 @@ export declare namespace GaffComparator {
207
269
  * }
208
270
  *
209
271
  * const products: Product[] = [
210
- * { id: '1', name: 'Laptop', price: 999.99, rating: 4.5, stock: 15, categoryId: 1, salesCount: 150 },
211
- * { id: '2', name: 'Mouse', price: 29.99, rating: 4.2, stock: 50, categoryId: 1, salesCount: 300 },
212
- * { id: '3', name: 'Keyboard', price: 79.99, rating: 4.8, stock: 25, categoryId: 1, salesCount: 200 }
272
+ * {
273
+ * id: "1",
274
+ * name: "Laptop",
275
+ * price: 999.99,
276
+ * rating: 4.5,
277
+ * stock: 15,
278
+ * categoryId: 1,
279
+ * salesCount: 150,
280
+ * },
281
+ * {
282
+ * id: "2",
283
+ * name: "Mouse",
284
+ * price: 29.99,
285
+ * rating: 4.2,
286
+ * stock: 50,
287
+ * categoryId: 1,
288
+ * salesCount: 300,
289
+ * },
290
+ * {
291
+ * id: "3",
292
+ * name: "Keyboard",
293
+ * price: 79.99,
294
+ * rating: 4.8,
295
+ * stock: 25,
296
+ * categoryId: 1,
297
+ * salesCount: 200,
298
+ * },
213
299
  * ];
214
300
  *
215
301
  * // Sort by price (ascending)
216
- * products.sort(GaffComparator.numbers(product => product.price));
302
+ * products.sort(GaffComparator.numbers((product) => product.price));
217
303
  * // Result: Mouse ($29.99), Keyboard ($79.99), Laptop ($999.99)
218
304
  *
219
305
  * // Sort by rating (descending requires negation)
220
- * products.sort(GaffComparator.numbers(product => -product.rating));
306
+ * products.sort(GaffComparator.numbers((product) => -product.rating));
221
307
  * // Result: Keyboard (4.8), Laptop (4.5), Mouse (4.2)
222
308
  *
223
309
  * // Multi-field: category, then price
224
- * products.sort(GaffComparator.numbers(product => [product.categoryId, product.price]));
310
+ * products.sort(
311
+ * GaffComparator.numbers((product) => [
312
+ * product.categoryId,
313
+ * product.price,
314
+ * ]),
315
+ * );
225
316
  *
226
317
  * // Complex business logic: popularity (sales) then rating
227
- * products.sort(GaffComparator.numbers(product => [-product.salesCount, -product.rating]));
318
+ * products.sort(
319
+ * GaffComparator.numbers((product) => [
320
+ * -product.salesCount,
321
+ * -product.rating,
322
+ * ]),
323
+ * );
228
324
  * // Negative values for descending order
229
325
  *
230
326
  * // Sort by inventory priority: low stock first, then by sales
231
- * products.sort(GaffComparator.numbers(product => [product.stock, -product.salesCount]));
327
+ * products.sort(
328
+ * GaffComparator.numbers((product) => [
329
+ * product.stock,
330
+ * -product.salesCount,
331
+ * ]),
332
+ * );
232
333
  *
233
334
  * // Validate API numerical sorting with TestValidator
234
- * const priceValidator = TestValidator.sort("product price sorting",
235
- * (sortFields) => productApi.getProducts({ sort: sortFields })
236
- * )("price")(
237
- * GaffComparator.numbers(product => product.price)
238
- * );
335
+ * const priceValidator = TestValidator.sort(
336
+ * "product price sorting",
337
+ * (sortFields) => productApi.getProducts({ sort: sortFields }),
338
+ * )("price")(GaffComparator.numbers((product) => product.price));
239
339
  * await priceValidator("+"); // test ascending order
240
340
  * await priceValidator("-"); // test descending order
241
341
  *
242
342
  * // Test multi-criteria sorting
243
- * const sortByBusinessValue = GaffComparator.numbers(product => [
244
- * -product.salesCount, // High sales first
245
- * -product.rating, // High rating first
246
- * product.price // Low price first (for tie-breaking)
343
+ * const sortByBusinessValue = GaffComparator.numbers((product) => [
344
+ * -product.salesCount, // High sales first
345
+ * -product.rating, // High rating first
346
+ * product.price, // Low price first (for tie-breaking)
247
347
  * ]);
248
- * ```;
249
348
  *
250
349
  * @template T - The type of objects being compared
251
350
  * @param closure - Function that extracts number value(s) from input objects
252
351
  * @returns A comparator function suitable for Array.sort()
352
+ * @evidence contracts/common.md#principled-implementation The sign of subtraction at the first differing position orders finite numeric values, and a shorter equal prefix sorts first. Subtraction can round or overflow, so the result's magnitude is not an exact-distance guarantee; callers must supply ordered numeric values rather than NaN.
353
+ * @evidence contracts/common.md#clear-and-simple-design It uses the shared `wrap` and `mismatch`, and adds only the subtraction.
354
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The comparison is the arithmetic difference, with no rounding or thresholds.
355
+ * @evidence contracts/common.md#meaningful-documentation The comment states the multi-value rule and the arguments, with examples.
253
356
  */
254
357
  const numbers: <T>(closure: (input: T) => number | number[]) => (x: T, y: T) => number;
255
358
  }