@nestia/e2e 14.0.0 → 14.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/ArrayUtil.d.ts +152 -70
- package/lib/ArrayUtil.js +169 -75
- package/lib/ArrayUtil.js.map +1 -1
- package/lib/DynamicExecutor.d.ts +139 -11
- package/lib/DynamicExecutor.js +98 -10
- package/lib/DynamicExecutor.js.map +1 -1
- package/lib/GaffComparator.d.ts +176 -73
- package/lib/GaffComparator.js +196 -77
- package/lib/GaffComparator.js.map +1 -1
- package/lib/MapUtil.d.ts +37 -6
- package/lib/MapUtil.js +37 -6
- package/lib/MapUtil.js.map +1 -1
- package/lib/RandomGenerator.d.ts +157 -84
- package/lib/RandomGenerator.js +173 -89
- package/lib/RandomGenerator.js.map +1 -1
- package/lib/TestValidator.d.ts +253 -74
- package/lib/TestValidator.js +274 -97
- package/lib/TestValidator.js.map +1 -1
- package/lib/internal/json_equal_to.d.ts +21 -0
- package/lib/internal/json_equal_to.js +35 -6
- package/lib/internal/json_equal_to.js.map +1 -1
- package/package.json +3 -2
- package/src/ArrayUtil.ts +173 -77
- package/src/DynamicExecutor.ts +158 -15
- package/src/GaffComparator.ts +195 -77
- package/src/MapUtil.ts +37 -6
- package/src/RandomGenerator.ts +172 -89
- package/src/TestValidator.ts +302 -107
- package/src/internal/json_equal_to.ts +36 -4
package/lib/RandomGenerator.js
CHANGED
|
@@ -6,8 +6,8 @@ exports.RandomGenerator = void 0;
|
|
|
6
6
|
*
|
|
7
7
|
* RandomGenerator provides a collection of functions for generating random data
|
|
8
8
|
* including strings, names, content, dates, and array sampling. All functions
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* draw from `Math.random()`, so they are not seeded and produce varied output
|
|
10
|
+
* across executions, which suits testing scenarios that need arbitrary data.
|
|
11
11
|
*
|
|
12
12
|
* The namespace includes specialized generators for:
|
|
13
13
|
*
|
|
@@ -16,21 +16,33 @@ exports.RandomGenerator = void 0;
|
|
|
16
16
|
* - Date ranges and time-based data
|
|
17
17
|
* - Array sampling and element selection
|
|
18
18
|
*
|
|
19
|
+
* Processing cost: Text construction scales with generated characters, sparse
|
|
20
|
+
* sampling with selected positions, and fixed-size draws use constant work. The
|
|
21
|
+
* namespace retains only fixed character tables; each generator owns its
|
|
22
|
+
* invocation-local result.
|
|
23
|
+
*
|
|
19
24
|
* @author Jeongho Nam - https://github.com/samchon
|
|
20
25
|
* @example
|
|
21
|
-
* ```typescript
|
|
22
26
|
* // Generate test user data
|
|
23
27
|
* const testUser = {
|
|
24
28
|
* id: RandomGenerator.alphaNumeric(8),
|
|
25
29
|
* name: RandomGenerator.name(),
|
|
26
|
-
* bio: RandomGenerator.paragraph({
|
|
30
|
+
* bio: RandomGenerator.paragraph({
|
|
31
|
+
* sentences: 3,
|
|
32
|
+
* wordMin: 5,
|
|
33
|
+
* wordMax: 10,
|
|
34
|
+
* }),
|
|
27
35
|
* phone: RandomGenerator.mobile(),
|
|
28
|
-
* createdAt: RandomGenerator.date(new Date(), 1000 * 60 * 60 * 24 * 30) // 30 days
|
|
36
|
+
* createdAt: RandomGenerator.date(new Date(), 1000 * 60 * 60 * 24 * 30), // 30 days
|
|
29
37
|
* };
|
|
30
38
|
*
|
|
31
39
|
* // Sample data for testing
|
|
32
40
|
* const testSample = RandomGenerator.sample(allUsers, 5);
|
|
33
|
-
*
|
|
41
|
+
*
|
|
42
|
+
* @evidence contracts/common.md#principled-implementation The private integer helper partitions Math.random output into equally sized bins for finite ordered integer bounds, and generators compose text, dates and selections from those draws. Math.random is approximately uniform and not cryptographically secure; exact probability guarantees do not follow from its finite precision.
|
|
43
|
+
* @evidence contracts/common.md#clear-and-simple-design Small generators build on each other (`name` on `paragraph`, `content` on `paragraph`, both on `alphabets`), so one integer helper decides the randomness.
|
|
44
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The data are drawn, not taken from a fixed list of test values.
|
|
45
|
+
* @evidence contracts/common.md#meaningful-documentation The namespace prose says the functions are not seeded and lists the kinds of data, with an example.
|
|
34
46
|
*/
|
|
35
47
|
var RandomGenerator;
|
|
36
48
|
(function (RandomGenerator) {
|
|
@@ -50,10 +62,12 @@ var RandomGenerator;
|
|
|
50
62
|
* appear multiple times. Useful for generating random identifiers, test
|
|
51
63
|
* names, or placeholder text.
|
|
52
64
|
*
|
|
65
|
+
* Processing cost: Constructing L characters costs O(L) time and
|
|
66
|
+
* intermediate/result space.
|
|
67
|
+
*
|
|
53
68
|
* @example
|
|
54
|
-
*
|
|
55
|
-
* RandomGenerator.alphabets(
|
|
56
|
-
* RandomGenerator.alphabets(3); // e.g. "mzr"
|
|
69
|
+
* RandomGenerator.alphabets(5); // e.g. "kxqpw"
|
|
70
|
+
* RandomGenerator.alphabets(3); // e.g. "mzr"
|
|
57
71
|
* RandomGenerator.alphabets(10); // e.g. "qwertasdfg"
|
|
58
72
|
*
|
|
59
73
|
* // Generate random CSS class names
|
|
@@ -61,10 +75,13 @@ var RandomGenerator;
|
|
|
61
75
|
*
|
|
62
76
|
* // Create random variable names for testing
|
|
63
77
|
* const varName = RandomGenerator.alphabets(8);
|
|
64
|
-
* ```
|
|
65
78
|
*
|
|
66
79
|
* @param length - The desired length of the generated alphabetic string
|
|
67
80
|
* @returns A string containing only lowercase letters of the specified length
|
|
81
|
+
* @evidence contracts/common.md#principled-implementation Each requested character maps a Math.random draw to one of 26 lowercase letters. Repeats are possible, and distribution inherits Math.random rather than guaranteeing exact uniformity.
|
|
82
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over the shared integer helper.
|
|
83
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The characters are drawn, not enumerated from a list of known values.
|
|
84
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the character set, the independence of the draws, and examples.
|
|
68
85
|
*/
|
|
69
86
|
RandomGenerator.alphabets = (length) => new Array(length)
|
|
70
87
|
.fill("")
|
|
@@ -79,9 +96,11 @@ var RandomGenerator;
|
|
|
79
96
|
* character set. Ideal for generating random IDs, tokens, passwords, or
|
|
80
97
|
* unique identifiers that need both numeric and alphabetic characters.
|
|
81
98
|
*
|
|
99
|
+
* Processing cost: Constructing L characters costs O(L) time and
|
|
100
|
+
* intermediate/result space.
|
|
101
|
+
*
|
|
82
102
|
* @example
|
|
83
|
-
*
|
|
84
|
-
* RandomGenerator.alphaNumeric(8); // e.g. "a1b2c3d4"
|
|
103
|
+
* RandomGenerator.alphaNumeric(8); // e.g. "a1b2c3d4"
|
|
85
104
|
* RandomGenerator.alphaNumeric(12); // e.g. "x9y8z7w6v5u4"
|
|
86
105
|
*
|
|
87
106
|
* // Generate random API keys
|
|
@@ -92,11 +111,14 @@ var RandomGenerator;
|
|
|
92
111
|
*
|
|
93
112
|
* // Generate test database IDs
|
|
94
113
|
* const testId = RandomGenerator.alphaNumeric(10);
|
|
95
|
-
* ```
|
|
96
114
|
*
|
|
97
115
|
* @param length - The desired length of the generated alphanumeric string
|
|
98
116
|
* @returns A string containing digits and lowercase letters of the specified
|
|
99
117
|
* length
|
|
118
|
+
* @evidence contracts/common.md#principled-implementation Each character maps a Math.random draw to one of ten digits and 26 lowercase letters. Repeated characters are allowed and exact uniformity is not guaranteed.
|
|
119
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over the shared integer helper.
|
|
120
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The characters are drawn, not enumerated from a list of known values.
|
|
121
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the character set and gives examples.
|
|
100
122
|
*/
|
|
101
123
|
RandomGenerator.alphaNumeric = (length) => new Array(length)
|
|
102
124
|
.fill("")
|
|
@@ -110,26 +132,31 @@ var RandomGenerator;
|
|
|
110
132
|
* Each word is between 3-7 characters by default, creating realistic-looking
|
|
111
133
|
* names.
|
|
112
134
|
*
|
|
135
|
+
* Processing cost: The delegated paragraph work scales with the requested
|
|
136
|
+
* word count and total generated characters.
|
|
137
|
+
*
|
|
113
138
|
* @example
|
|
114
|
-
*
|
|
115
|
-
* RandomGenerator.name();
|
|
116
|
-
* RandomGenerator.name(
|
|
117
|
-
* RandomGenerator.name(3); // e.g. "sit amet consectetur" (3 words)
|
|
139
|
+
* RandomGenerator.name(); // e.g. "lorem ipsum" (2-3 words)
|
|
140
|
+
* RandomGenerator.name(1); // e.g. "dolor" (single word)
|
|
141
|
+
* RandomGenerator.name(3); // e.g. "sit amet consectetur" (3 words)
|
|
118
142
|
*
|
|
119
143
|
* // Generate test user names
|
|
120
144
|
* const users = Array.from({ length: 10 }, () => ({
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
145
|
+
* id: RandomGenerator.alphaNumeric(8),
|
|
146
|
+
* name: RandomGenerator.name(),
|
|
147
|
+
* email: `${RandomGenerator.name(1)}@test.com`,
|
|
124
148
|
* }));
|
|
125
149
|
*
|
|
126
150
|
* // Create random author names for blog posts
|
|
127
151
|
* const authorName = RandomGenerator.name();
|
|
128
|
-
* ```
|
|
129
152
|
*
|
|
130
153
|
* @param length - Number of words in the name (default: random between 2-3)
|
|
131
154
|
* @returns A space-separated string of random words (each 3-7 chars by
|
|
132
155
|
* default)
|
|
156
|
+
* @evidence contracts/common.md#principled-implementation A name is a short paragraph of two or three lowercase words by default, so it reads as a person or entity name without an external name list.
|
|
157
|
+
* @evidence contracts/common.md#clear-and-simple-design A one-line delegation to `paragraph` with the sentence count as the word count.
|
|
158
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The words are drawn letters, not a fixed list of names.
|
|
159
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the default length and gives examples.
|
|
133
160
|
*/
|
|
134
161
|
RandomGenerator.name = (length = randint(2, 3)) => RandomGenerator.paragraph({
|
|
135
162
|
sentences: length,
|
|
@@ -142,13 +169,16 @@ var RandomGenerator;
|
|
|
142
169
|
* joined with spaces. Accepts an optional configuration object for fine-tuned
|
|
143
170
|
* control over the paragraph structure.
|
|
144
171
|
*
|
|
172
|
+
* Processing cost: Each requested word is generated once; time and temporary
|
|
173
|
+
* space scale with the total generated character count and the number of
|
|
174
|
+
* words.
|
|
175
|
+
*
|
|
145
176
|
* @example
|
|
146
|
-
* ```typescript
|
|
147
177
|
* // Generate with defaults (random 2-5 words, 3-7 characters each)
|
|
148
|
-
* RandomGenerator.paragraph();
|
|
178
|
+
* RandomGenerator.paragraph(); // e.g. "lorem ipsum dolor"
|
|
149
179
|
*
|
|
150
180
|
* // Specific number of sentences
|
|
151
|
-
* RandomGenerator.paragraph({ sentences: 5 });
|
|
181
|
+
* RandomGenerator.paragraph({ sentences: 5 }); // "lorem ipsum dolor sit amet"
|
|
152
182
|
*
|
|
153
183
|
* // Custom word length ranges
|
|
154
184
|
* RandomGenerator.paragraph({ sentences: 4, wordMin: 2, wordMax: 5 });
|
|
@@ -158,20 +188,23 @@ var RandomGenerator;
|
|
|
158
188
|
* const description = RandomGenerator.paragraph({
|
|
159
189
|
* sentences: 8,
|
|
160
190
|
* wordMin: 4,
|
|
161
|
-
* wordMax: 8
|
|
191
|
+
* wordMax: 8,
|
|
162
192
|
* });
|
|
163
193
|
*
|
|
164
194
|
* // Create test content for forms
|
|
165
195
|
* const placeholder = RandomGenerator.paragraph({
|
|
166
196
|
* sentences: 3,
|
|
167
197
|
* wordMin: 5,
|
|
168
|
-
* wordMax: 10
|
|
198
|
+
* wordMax: 10,
|
|
169
199
|
* });
|
|
170
|
-
* ```;
|
|
171
200
|
*
|
|
172
201
|
* @param props - Optional configuration object with sentences count and word
|
|
173
202
|
* length ranges
|
|
174
203
|
* @returns A string containing the generated paragraph
|
|
204
|
+
* @evidence contracts/common.md#principled-implementation A paragraph is a number of words joined by spaces, each word a random lowercase string of a length between the minimum and maximum, with the defaults of two to five words of three to seven letters.
|
|
205
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over `alphabets`, with three optional numbers.
|
|
206
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The words are drawn letters, not a fixed text.
|
|
207
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the parameters and their defaults, with examples.
|
|
175
208
|
*/
|
|
176
209
|
RandomGenerator.paragraph = (props) => { var _a; return new Array((_a = props === null || props === void 0 ? void 0 : props.sentences) !== null && _a !== void 0 ? _a : randint(2, 5))
|
|
177
210
|
.fill("")
|
|
@@ -186,8 +219,10 @@ var RandomGenerator;
|
|
|
186
219
|
* character lengths. Ideal for generating realistic-looking text content for
|
|
187
220
|
* testing.
|
|
188
221
|
*
|
|
222
|
+
* Processing cost: Every paragraph is generated once; time and temporary
|
|
223
|
+
* space scale with the total output characters and paragraph/word counts.
|
|
224
|
+
*
|
|
189
225
|
* @example
|
|
190
|
-
* ```typescript
|
|
191
226
|
* // Generate with all defaults
|
|
192
227
|
* const article = RandomGenerator.content();
|
|
193
228
|
*
|
|
@@ -197,7 +232,7 @@ var RandomGenerator;
|
|
|
197
232
|
* sentenceMin: 15,
|
|
198
233
|
* sentenceMax: 25,
|
|
199
234
|
* wordMin: 4,
|
|
200
|
-
* wordMax: 8
|
|
235
|
+
* wordMax: 8,
|
|
201
236
|
* });
|
|
202
237
|
*
|
|
203
238
|
* // Short content with brief sentences
|
|
@@ -206,7 +241,7 @@ var RandomGenerator;
|
|
|
206
241
|
* sentenceMin: 5,
|
|
207
242
|
* sentenceMax: 8,
|
|
208
243
|
* wordMin: 2,
|
|
209
|
-
* wordMax: 4
|
|
244
|
+
* wordMax: 4,
|
|
210
245
|
* });
|
|
211
246
|
*
|
|
212
247
|
* // Generate blog post content
|
|
@@ -217,9 +252,9 @@ var RandomGenerator;
|
|
|
217
252
|
* sentenceMin: 10,
|
|
218
253
|
* sentenceMax: 20,
|
|
219
254
|
* wordMin: 3,
|
|
220
|
-
* wordMax: 7
|
|
255
|
+
* wordMax: 7,
|
|
221
256
|
* }),
|
|
222
|
-
* summary: RandomGenerator.paragraph({ sentences: 2 })
|
|
257
|
+
* summary: RandomGenerator.paragraph({ sentences: 2 }),
|
|
223
258
|
* };
|
|
224
259
|
*
|
|
225
260
|
* // Create test data for CMS
|
|
@@ -228,14 +263,17 @@ var RandomGenerator;
|
|
|
228
263
|
* content: RandomGenerator.content({
|
|
229
264
|
* paragraphs: randint(2, 6),
|
|
230
265
|
* sentenceMin: 8,
|
|
231
|
-
* sentenceMax: 15
|
|
232
|
-
* })
|
|
266
|
+
* sentenceMax: 15,
|
|
267
|
+
* }),
|
|
233
268
|
* }));
|
|
234
|
-
* ```;
|
|
235
269
|
*
|
|
236
270
|
* @param props - Optional configuration object with paragraph, sentence, and
|
|
237
271
|
* word parameters
|
|
238
272
|
* @returns A string containing the generated multi-paragraph content
|
|
273
|
+
* @evidence contracts/common.md#principled-implementation The content has three to eight paragraphs by default, each containing ten to forty space-separated words of one to seven lowercase letters, joined by blank lines. The legacy sentence-named options count words, not grammatical sentences.
|
|
274
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over `paragraph`, with five optional numbers.
|
|
275
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The text is drawn, not a fixed corpus.
|
|
276
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the parameters and their defaults, with examples.
|
|
239
277
|
*/
|
|
240
278
|
RandomGenerator.content = (props) => { var _a; return new Array((_a = props === null || props === void 0 ? void 0 : props.paragraphs) !== null && _a !== void 0 ? _a : randint(3, 8))
|
|
241
279
|
.fill("")
|
|
@@ -253,13 +291,15 @@ var RandomGenerator;
|
|
|
253
291
|
* Automatically trims whitespace from the beginning and end of the result.
|
|
254
292
|
* Useful for creating excerpts, search terms, or partial content samples.
|
|
255
293
|
*
|
|
294
|
+
* Processing cost: Two draws choose the slice bounds; substring and trimming
|
|
295
|
+
* cost at most O(N) in the input length.
|
|
296
|
+
*
|
|
256
297
|
* @example
|
|
257
|
-
* ```typescript
|
|
258
298
|
* const text = "The quick brown fox jumps over the lazy dog";
|
|
259
299
|
*
|
|
260
|
-
* RandomGenerator.substring(text);
|
|
261
|
-
* RandomGenerator.substring(text);
|
|
262
|
-
* RandomGenerator.substring(text);
|
|
300
|
+
* RandomGenerator.substring(text); // e.g. "quick brown fox"
|
|
301
|
+
* RandomGenerator.substring(text); // e.g. "jumps over"
|
|
302
|
+
* RandomGenerator.substring(text); // e.g. "fox jumps over the lazy"
|
|
263
303
|
*
|
|
264
304
|
* // Generate search terms from content
|
|
265
305
|
* const searchQuery = RandomGenerator.substring(articleContent);
|
|
@@ -272,10 +312,13 @@ var RandomGenerator;
|
|
|
272
312
|
*
|
|
273
313
|
* // Create random selections for highlight testing
|
|
274
314
|
* const selectedText = RandomGenerator.substring(documentContent);
|
|
275
|
-
* ```;
|
|
276
315
|
*
|
|
277
316
|
* @param content - The source string to extract a substring from
|
|
278
317
|
* @returns A trimmed substring of the original content
|
|
318
|
+
* @evidence contracts/common.md#principled-implementation For nonempty input, the first index is a valid position and the last is strictly later up to the length. Trimming can empty a whitespace slice. Empty input also returns an empty string; substring clamps its drawn bounds to the empty input.
|
|
319
|
+
* @evidence contracts/common.md#clear-and-simple-design Two draws and one slice.
|
|
320
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The slice bounds are drawn, not fixed.
|
|
321
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states that the slice is random and trimmed, with examples.
|
|
279
322
|
*/
|
|
280
323
|
RandomGenerator.substring = (content) => {
|
|
281
324
|
const first = randint(0, content.length - 1);
|
|
@@ -291,31 +334,39 @@ var RandomGenerator;
|
|
|
291
334
|
* if necessary. Commonly used for generating Korean mobile phone numbers or
|
|
292
335
|
* similar formats.
|
|
293
336
|
*
|
|
337
|
+
* Processing cost: Two bounded integer draws and fixed-width decimal
|
|
338
|
+
* formatting use constant work; joining the caller prefix costs O(P) output
|
|
339
|
+
* time and space for P prefix characters.
|
|
340
|
+
*
|
|
294
341
|
* @example
|
|
295
|
-
*
|
|
296
|
-
* RandomGenerator.mobile();
|
|
297
|
-
* RandomGenerator.mobile("
|
|
298
|
-
* RandomGenerator.mobile("+82"); // e.g. "+823341234" or "+8212345678"
|
|
342
|
+
* RandomGenerator.mobile(); // e.g. "0103341234" or "01012345678"
|
|
343
|
+
* RandomGenerator.mobile("011"); // e.g. "0119876543" or "01112345678"
|
|
344
|
+
* RandomGenerator.mobile("+82"); // e.g. "+823341234" or "+8212345678"
|
|
299
345
|
*
|
|
300
346
|
* // Generate test user phone numbers
|
|
301
347
|
* const testUsers = Array.from({ length: 100 }, () => ({
|
|
302
348
|
* name: RandomGenerator.name(),
|
|
303
349
|
* phone: RandomGenerator.mobile(),
|
|
304
|
-
* altPhone: RandomGenerator.mobile("011")
|
|
350
|
+
* altPhone: RandomGenerator.mobile("011"),
|
|
305
351
|
* }));
|
|
306
352
|
*
|
|
307
353
|
* // Create international phone numbers
|
|
308
354
|
* const internationalPhone = RandomGenerator.mobile("+821");
|
|
309
355
|
*
|
|
310
356
|
* // Generate contact list for testing
|
|
311
|
-
* const contacts = ["010", "011", "016", "017", "018", "019"].map(
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
357
|
+
* const contacts = ["010", "011", "016", "017", "018", "019"].map(
|
|
358
|
+
* (prefix) => ({
|
|
359
|
+
* carrier: prefix,
|
|
360
|
+
* number: RandomGenerator.mobile(prefix),
|
|
361
|
+
* }),
|
|
362
|
+
* );
|
|
316
363
|
*
|
|
317
364
|
* @param prefix - The prefix string for the phone number (default: "010")
|
|
318
365
|
* @returns A formatted mobile phone number string
|
|
366
|
+
* @evidence contracts/common.md#principled-implementation A mobile number is the prefix, a middle group of three digits when the drawn value is below 1,000 and four digits otherwise, and a four-digit group, all zero-padded, which matches the 010-XXX-XXXX and 010-XXXX-XXXX Korean formats the default prefix implies.
|
|
367
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression with two draws.
|
|
368
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The prefix is a parameter whose default is the documented Korean one, and the digits are drawn.
|
|
369
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the format, the default prefix, and examples.
|
|
319
370
|
*/
|
|
320
371
|
RandomGenerator.mobile = (prefix = "010") => [
|
|
321
372
|
prefix,
|
|
@@ -333,8 +384,10 @@ var RandomGenerator;
|
|
|
333
384
|
* date. Useful for generating timestamps, creation dates, or scheduling test
|
|
334
385
|
* data.
|
|
335
386
|
*
|
|
387
|
+
* Processing cost: One integer draw and one Date construction use constant
|
|
388
|
+
* work.
|
|
389
|
+
*
|
|
336
390
|
* @example
|
|
337
|
-
* ```typescript
|
|
338
391
|
* const now = new Date();
|
|
339
392
|
* const oneDay = 24 * 60 * 60 * 1000;
|
|
340
393
|
* const oneMonth = 30 * oneDay;
|
|
@@ -348,38 +401,50 @@ var RandomGenerator;
|
|
|
348
401
|
*
|
|
349
402
|
* // Generate random creation dates for test data
|
|
350
403
|
* const startOfYear = new Date(2024, 0, 1);
|
|
351
|
-
* const endOfYear =
|
|
352
|
-
*
|
|
404
|
+
* const endOfYear =
|
|
405
|
+
* new Date(2024, 11, 31).getTime() - startOfYear.getTime();
|
|
406
|
+
* const randomCreationDate = RandomGenerator.date(
|
|
407
|
+
* startOfYear,
|
|
408
|
+
* endOfYear,
|
|
409
|
+
* );
|
|
353
410
|
*
|
|
354
411
|
* // Create test events with random timestamps
|
|
355
412
|
* const events = Array.from({ length: 50 }, () => ({
|
|
356
413
|
* id: RandomGenerator.alphaNumeric(8),
|
|
357
414
|
* title: RandomGenerator.name(2),
|
|
358
415
|
* createdAt: RandomGenerator.date(new Date(), oneMonth),
|
|
359
|
-
* scheduledFor: RandomGenerator.date(new Date(), oneMonth * 3)
|
|
416
|
+
* scheduledFor: RandomGenerator.date(new Date(), oneMonth * 3),
|
|
360
417
|
* }));
|
|
361
|
-
* ```;
|
|
362
418
|
*
|
|
363
419
|
* @param from - The starting date for the random range
|
|
364
420
|
* @param range - The range in milliseconds from the starting date
|
|
365
421
|
* @returns A random date within the specified range
|
|
422
|
+
* @evidence contracts/common.md#principled-implementation For a valid start date and finite nonnegative integer range whose endpoint is Date-representable, the result adds an integer offset from zero through range. Unsupported invalid dates or bounds are not validated and can produce an Invalid Date or an out-of-range result.
|
|
423
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over the shared integer helper.
|
|
424
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The offset is drawn, not fixed.
|
|
425
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the interval and the unit of the range, with examples.
|
|
366
426
|
*/
|
|
367
427
|
RandomGenerator.date = (from, range) => new Date(from.getTime() + randint(0, range));
|
|
368
428
|
/**
|
|
369
|
-
* Randomly samples a specified number of
|
|
429
|
+
* Randomly samples a specified number of positions from an array.
|
|
430
|
+
*
|
|
431
|
+
* Selects input positions without replacement. Equal values at different
|
|
432
|
+
* positions remain separate candidates and can both appear in the result. The
|
|
433
|
+
* sample size is automatically capped at the array length to prevent errors.
|
|
434
|
+
* Uses a partial Fisher-Yates shuffle over a sparse index map, so every draw
|
|
435
|
+
* is final and the cost grows with the sample size, not with the array
|
|
436
|
+
* length. Ideal for creating test datasets or selecting random subsets for
|
|
437
|
+
* validation.
|
|
370
438
|
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* guarantee uniqueness of selected indices. Ideal for creating test datasets
|
|
375
|
-
* or selecting random subsets for validation.
|
|
439
|
+
* Processing cost: For K selected positions, sparse partial Fisher-Yates uses
|
|
440
|
+
* K map lookups/updates and K output entries: expected O(K) time and O(K)
|
|
441
|
+
* space, without copying the N-element input.
|
|
376
442
|
*
|
|
377
443
|
* @example
|
|
378
|
-
* ```typescript
|
|
379
444
|
* const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
380
445
|
*
|
|
381
|
-
* RandomGenerator.sample(numbers, 3);
|
|
382
|
-
* RandomGenerator.sample(numbers, 5);
|
|
446
|
+
* RandomGenerator.sample(numbers, 3); // e.g. [2, 7, 9]
|
|
447
|
+
* RandomGenerator.sample(numbers, 5); // e.g. [1, 4, 6, 8, 10]
|
|
383
448
|
* RandomGenerator.sample(numbers, 15); // returns all 10 elements (capped at array length)
|
|
384
449
|
*
|
|
385
450
|
* // Sample users for testing
|
|
@@ -394,61 +459,80 @@ var RandomGenerator;
|
|
|
394
459
|
*
|
|
395
460
|
* // Random A/B testing groups
|
|
396
461
|
* const groupA = RandomGenerator.sample(allParticipants, 50);
|
|
397
|
-
* const remaining = allParticipants.filter(p => !groupA.includes(p));
|
|
462
|
+
* const remaining = allParticipants.filter((p) => !groupA.includes(p));
|
|
398
463
|
* const groupB = RandomGenerator.sample(remaining, 50);
|
|
399
|
-
* ```;
|
|
400
464
|
*
|
|
401
465
|
* @param array - The source array to sample from
|
|
402
466
|
* @param count - The number of elements to sample
|
|
403
467
|
* @returns An array containing the randomly selected elements
|
|
468
|
+
* @evidence contracts/common.md#principled-implementation A partial Fisher-Yates shuffle over a sparse map of moved positions draws each result element from the not-yet-chosen positions uniformly, so the sample is without replacement, approximately uniform under Math.random, and its cost grows with the sample size; the count is capped at the array length, a positive fractional count rounds upward through the loop condition, and a count that is zero, negative, or NaN yields an empty array.
|
|
469
|
+
* @evidence contracts/common.md#clear-and-simple-design One loop with one map, and no rejection of repeated draws.
|
|
470
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The array is not mutated or copied, and no element is favored or excluded.
|
|
471
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states without-replacement sampling, the cap, and the algorithm, with examples.
|
|
404
472
|
*/
|
|
405
473
|
RandomGenerator.sample = (array, count) => {
|
|
474
|
+
var _a, _b;
|
|
406
475
|
count = Math.min(count, array.length);
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
476
|
+
// `moved` holds the positions whose element differs from the identity, so
|
|
477
|
+
// the shuffle needs no copy of the array
|
|
478
|
+
const moved = new Map();
|
|
479
|
+
const output = [];
|
|
480
|
+
for (let i = 0; i < count; ++i) {
|
|
481
|
+
const j = randint(i, array.length - 1);
|
|
482
|
+
output.push(array[(_a = moved.get(j)) !== null && _a !== void 0 ? _a : j]);
|
|
483
|
+
moved.set(j, (_b = moved.get(i)) !== null && _b !== void 0 ? _b : i);
|
|
484
|
+
}
|
|
485
|
+
return output;
|
|
411
486
|
};
|
|
412
487
|
/**
|
|
413
488
|
* Randomly selects a single element from an array.
|
|
414
489
|
*
|
|
415
|
-
* Chooses one element at random from the provided array using
|
|
416
|
-
* distribution
|
|
417
|
-
*
|
|
418
|
-
*
|
|
490
|
+
* Chooses one element at random from the provided array using approximately
|
|
491
|
+
* uniform distribution inherited from Math.random. This is a convenience
|
|
492
|
+
* function equivalent to sampling with a count of 1, but returns the element
|
|
493
|
+
* directly rather than an array containing one element.
|
|
494
|
+
*
|
|
495
|
+
* Processing cost: One bounded draw and one indexed lookup use constant work.
|
|
419
496
|
*
|
|
420
497
|
* @example
|
|
421
|
-
*
|
|
422
|
-
* const
|
|
423
|
-
* const fruits = ['apple', 'banana', 'orange', 'grape', 'kiwi'];
|
|
498
|
+
* const colors = ["red", "blue", "green", "yellow", "purple"];
|
|
499
|
+
* const fruits = ["apple", "banana", "orange", "grape", "kiwi"];
|
|
424
500
|
*
|
|
425
|
-
* RandomGenerator.pick(colors);
|
|
426
|
-
* RandomGenerator.pick(fruits);
|
|
501
|
+
* RandomGenerator.pick(colors); // e.g. "blue"
|
|
502
|
+
* RandomGenerator.pick(fruits); // e.g. "apple"
|
|
427
503
|
*
|
|
428
504
|
* // Select random configuration options
|
|
429
|
-
* const randomTheme = RandomGenerator.pick([
|
|
430
|
-
* const randomLocale = RandomGenerator.pick([
|
|
505
|
+
* const randomTheme = RandomGenerator.pick(["light", "dark", "auto"]);
|
|
506
|
+
* const randomLocale = RandomGenerator.pick(["en", "ko", "ja", "zh"]);
|
|
431
507
|
*
|
|
432
508
|
* // Choose random test scenarios
|
|
433
509
|
* const testScenario = RandomGenerator.pick([
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
510
|
+
* "happy_path",
|
|
511
|
+
* "edge_case",
|
|
512
|
+
* "error_condition",
|
|
513
|
+
* "boundary_test",
|
|
438
514
|
* ]);
|
|
439
515
|
*
|
|
440
516
|
* // Random user role assignment
|
|
441
|
-
* const userRole = RandomGenerator.pick([
|
|
517
|
+
* const userRole = RandomGenerator.pick(["admin", "user", "moderator"]);
|
|
442
518
|
*
|
|
443
519
|
* // Select random API endpoints for testing
|
|
444
|
-
* const endpoints = [
|
|
520
|
+
* const endpoints = ["/users", "/posts", "/comments", "/categories"];
|
|
445
521
|
* const randomEndpoint = RandomGenerator.pick(endpoints);
|
|
446
|
-
* ```;
|
|
447
522
|
*
|
|
448
523
|
* @param array - The source array to pick an element from
|
|
449
524
|
* @returns A randomly selected element from the array
|
|
525
|
+
* @throws RangeError when the array is empty
|
|
526
|
+
* @evidence contracts/common.md#principled-implementation One index maps a Math.random draw to a valid position, giving approximately uniform selection; an empty array has no element to return, so it raises a `RangeError` instead of returning `undefined` under the element type.
|
|
527
|
+
* @evidence contracts/common.md#clear-and-simple-design One guard and one draw.
|
|
528
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The guard states the contract for the empty array and no default element is invented.
|
|
529
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the approximately uniform selection, the relation to sampling one element, and the `RangeError` for an empty array, with examples.
|
|
450
530
|
*/
|
|
451
|
-
RandomGenerator.pick = (array) =>
|
|
531
|
+
RandomGenerator.pick = (array) => {
|
|
532
|
+
if (array.length === 0)
|
|
533
|
+
throw new RangeError("RandomGenerator.pick(): the array is empty.");
|
|
534
|
+
return array[randint(0, array.length - 1)];
|
|
535
|
+
};
|
|
452
536
|
})(RandomGenerator || (exports.RandomGenerator = RandomGenerator = {}));
|
|
453
537
|
/** @internal */
|
|
454
538
|
const randint = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RandomGenerator.js","sourceRoot":"","sources":["../src/RandomGenerator.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"RandomGenerator.js","sourceRoot":"","sources":["../src/RandomGenerator.ts"],"names":[],"mappings":"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"}
|