@schmock/faker 2.2.3 → 2.3.1
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/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/constants.d.ts +82 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/field-mappings.d.ts.map +1 -1
- package/dist/field-name-matcher.d.ts +19 -0
- package/dist/field-name-matcher.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/jsf-config.d.ts +27 -2
- package/dist/jsf-config.d.ts.map +1 -1
- package/dist/output-limits.d.ts +3 -0
- package/dist/output-limits.d.ts.map +1 -0
- package/dist/overrides.d.ts +2 -1
- package/dist/overrides.d.ts.map +1 -1
- package/dist/schema-children.d.ts +14 -0
- package/dist/schema-children.d.ts.map +1 -0
- package/dist/schema-enhancement.d.ts +1 -0
- package/dist/schema-enhancement.d.ts.map +1 -1
- package/dist/validation.d.ts +24 -5
- package/dist/validation.d.ts.map +1 -1
- package/package.json +19 -9
- package/dist/constants.js +0 -8
- package/dist/field-mappings.js +0 -1107
- package/dist/field-name-matcher.js +0 -149
- package/dist/jsf-config.js +0 -35
- package/dist/overrides.js +0 -131
- package/dist/schema-enhancement.js +0 -89
- package/dist/test-utils.d.ts +0 -57
- package/dist/test-utils.d.ts.map +0 -1
- package/dist/test-utils.js +0 -271
- package/dist/validation.js +0 -300
- package/src/advanced-features.test.ts +0 -912
- package/src/audit-faker-args.test.ts +0 -97
- package/src/constants.d.ts.map +0 -1
- package/src/constants.ts +0 -9
- package/src/data-quality.test.ts +0 -415
- package/src/error-handling.test.ts +0 -504
- package/src/field-mappings.test.ts +0 -351
- package/src/field-mappings.ts +0 -1141
- package/src/field-name-matcher.test.ts +0 -292
- package/src/field-name-matcher.ts +0 -188
- package/src/index.d.ts.map +0 -1
- package/src/index.test.ts +0 -1218
- package/src/index.ts +0 -168
- package/src/integration.test.ts +0 -634
- package/src/jsf-config.d.ts.map +0 -1
- package/src/jsf-config.ts +0 -48
- package/src/overrides.d.ts.map +0 -1
- package/src/overrides.property.test.ts +0 -172
- package/src/overrides.test.ts +0 -38
- package/src/overrides.ts +0 -176
- package/src/performance.test.ts +0 -494
- package/src/plugin-integration.test.ts +0 -575
- package/src/post-process.test.ts +0 -151
- package/src/real-world.test.ts +0 -636
- package/src/schema-enhancement.d.ts.map +0 -1
- package/src/schema-enhancement.test.ts +0 -216
- package/src/schema-enhancement.ts +0 -128
- package/src/steps/deterministic-seeds.steps.ts +0 -35
- package/src/steps/faker-plugin.steps.ts +0 -109
- package/src/test-utils.ts +0 -365
- package/src/validation.d.ts.map +0 -1
- package/src/validation.ts +0 -417
package/src/performance.test.ts
DELETED
|
@@ -1,494 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { fakerPlugin, generateFromSchema } from "./index";
|
|
4
|
-
import { generate, performance as perf, schemas } from "./test-utils";
|
|
5
|
-
|
|
6
|
-
describe("Performance and Memory", () => {
|
|
7
|
-
describe("Generation Speed", () => {
|
|
8
|
-
it("generates simple objects quickly", async () => {
|
|
9
|
-
const schema = schemas.simple.object({
|
|
10
|
-
id: schemas.simple.number(),
|
|
11
|
-
name: schemas.simple.string(),
|
|
12
|
-
active: { type: "boolean" },
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
const times: number[] = [];
|
|
16
|
-
for (let i = 0; i < 10; i++) {
|
|
17
|
-
const { duration } = await perf.measure(
|
|
18
|
-
async () => await generateFromSchema({ schema }),
|
|
19
|
-
);
|
|
20
|
-
times.push(duration);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
|
|
24
|
-
expect(avgTime).toBeLessThan(50); // Should average under 50ms
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("handles nested objects efficiently", async () => {
|
|
28
|
-
const schema = schemas.nested.deep(
|
|
29
|
-
3,
|
|
30
|
-
schemas.simple.object({
|
|
31
|
-
id: schemas.simple.number(),
|
|
32
|
-
value: schemas.simple.string(),
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const { duration } = await perf.measure(
|
|
37
|
-
async () => await generateFromSchema({ schema }),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
expect(duration).toBeLessThan(100); // Reasonable for nested structure
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("generates arrays efficiently", async () => {
|
|
44
|
-
const schema = schemas.simple.array(
|
|
45
|
-
schemas.simple.object({
|
|
46
|
-
id: schemas.simple.number(),
|
|
47
|
-
name: schemas.simple.string(),
|
|
48
|
-
}),
|
|
49
|
-
{ minItems: 50, maxItems: 50 },
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
const { duration } = await perf.measure(
|
|
53
|
-
async () => await generateFromSchema({ schema }),
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
expect(duration).toBeLessThan(200); // Should handle 50 items quickly
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("handles complex schemas with multiple constraints", async () => {
|
|
60
|
-
const schema: JSONSchema7 = {
|
|
61
|
-
type: "object",
|
|
62
|
-
properties: {
|
|
63
|
-
users: {
|
|
64
|
-
type: "array",
|
|
65
|
-
items: {
|
|
66
|
-
type: "object",
|
|
67
|
-
properties: {
|
|
68
|
-
id: { type: "string", format: "uuid" },
|
|
69
|
-
email: { type: "string", format: "email" },
|
|
70
|
-
age: { type: "integer", minimum: 18, maximum: 100 },
|
|
71
|
-
tags: {
|
|
72
|
-
type: "array",
|
|
73
|
-
items: { type: "string", pattern: "^[a-z]+$" },
|
|
74
|
-
maxItems: 5,
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
required: ["id", "email"],
|
|
78
|
-
},
|
|
79
|
-
minItems: 10,
|
|
80
|
-
maxItems: 10,
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const { duration } = await perf.measure(
|
|
86
|
-
async () => await generateFromSchema({ schema }),
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
expect(duration).toBeLessThan(300); // Complex but still reasonable
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe("Scaling Behavior", () => {
|
|
94
|
-
it("scales linearly with array size", async () => {
|
|
95
|
-
const smallSchema = schemas.simple.array(schemas.simple.string(), {
|
|
96
|
-
minItems: 50,
|
|
97
|
-
maxItems: 50,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const largeSchema = schemas.simple.array(schemas.simple.string(), {
|
|
101
|
-
minItems: 500,
|
|
102
|
-
maxItems: 500,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Warmup runs to stabilize JIT
|
|
106
|
-
for (let i = 0; i < 3; i++) {
|
|
107
|
-
await generateFromSchema({ schema: smallSchema });
|
|
108
|
-
await generateFromSchema({ schema: largeSchema });
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Multiple measurement runs for statistical stability
|
|
112
|
-
const smallTimes: number[] = [];
|
|
113
|
-
const largeTimes: number[] = [];
|
|
114
|
-
|
|
115
|
-
for (let i = 0; i < 10; i++) {
|
|
116
|
-
const start1 = performance.now();
|
|
117
|
-
await generateFromSchema({ schema: smallSchema });
|
|
118
|
-
const small = performance.now() - start1;
|
|
119
|
-
smallTimes.push(small);
|
|
120
|
-
|
|
121
|
-
const start2 = performance.now();
|
|
122
|
-
await generateFromSchema({ schema: largeSchema });
|
|
123
|
-
const large = performance.now() - start2;
|
|
124
|
-
largeTimes.push(large);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Remove outliers and calculate medians for stability
|
|
128
|
-
smallTimes.sort((a, b) => a - b);
|
|
129
|
-
largeTimes.sort((a, b) => a - b);
|
|
130
|
-
const medianSmall = smallTimes[Math.floor(smallTimes.length / 2)];
|
|
131
|
-
const medianLarge = largeTimes[Math.floor(largeTimes.length / 2)];
|
|
132
|
-
|
|
133
|
-
// Both should complete in reasonable time (main goal is to ensure it works, not strict timing)
|
|
134
|
-
expect(medianSmall).toBeLessThan(50); // Small arrays should be fast
|
|
135
|
-
expect(medianLarge).toBeLessThan(200); // Large arrays should still be reasonable
|
|
136
|
-
|
|
137
|
-
// Optional: Check scaling if timing is meaningful
|
|
138
|
-
if (medianSmall > 0.1) {
|
|
139
|
-
// Only check scaling if we have measurable timing
|
|
140
|
-
expect(medianLarge).toBeGreaterThan(medianSmall * 0.5); // Should take at least half as long
|
|
141
|
-
expect(medianLarge).toBeLessThan(medianSmall * 50); // But not extremely longer
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("handles wide objects efficiently", async () => {
|
|
146
|
-
const narrowSchema = schemas.nested.wide(20);
|
|
147
|
-
const wideSchema = schemas.nested.wide(100);
|
|
148
|
-
|
|
149
|
-
// Warmup
|
|
150
|
-
for (let i = 0; i < 3; i++) {
|
|
151
|
-
await generateFromSchema({ schema: narrowSchema });
|
|
152
|
-
await generateFromSchema({ schema: wideSchema });
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Measure with multiple runs, dropping outliers
|
|
156
|
-
const narrowTimes: number[] = [];
|
|
157
|
-
const wideTimes: number[] = [];
|
|
158
|
-
|
|
159
|
-
for (let i = 0; i < 10; i++) {
|
|
160
|
-
const start1 = performance.now();
|
|
161
|
-
await generateFromSchema({ schema: narrowSchema });
|
|
162
|
-
narrowTimes.push(performance.now() - start1);
|
|
163
|
-
|
|
164
|
-
const start2 = performance.now();
|
|
165
|
-
await generateFromSchema({ schema: wideSchema });
|
|
166
|
-
wideTimes.push(performance.now() - start2);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Use median instead of average to reduce sensitivity to GC pauses
|
|
170
|
-
const median = (arr: number[]) => {
|
|
171
|
-
const sorted = [...arr].sort((a, b) => a - b);
|
|
172
|
-
const mid = Math.floor(sorted.length / 2);
|
|
173
|
-
return sorted.length % 2
|
|
174
|
-
? sorted[mid]
|
|
175
|
-
: (sorted[mid - 1] + sorted[mid]) / 2;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const medNarrow = median(narrowTimes);
|
|
179
|
-
const medWide = median(wideTimes);
|
|
180
|
-
|
|
181
|
-
// Scale assertion (machine-speed-independent): wide has 5x the
|
|
182
|
-
// properties of narrow, so its generation time should scale roughly
|
|
183
|
-
// with that. Allow 20x headroom for measurement noise + small superlinear
|
|
184
|
-
// behavior; this catches order-of-magnitude regressions without flaking
|
|
185
|
-
// on shared CI runners where absolute wall-clock thresholds are unreliable.
|
|
186
|
-
if (medNarrow > 0.1) {
|
|
187
|
-
// Only check scaling if we have measurable timing
|
|
188
|
-
expect(medWide).toBeGreaterThan(medNarrow * 0.5); // sanity: more work, not less
|
|
189
|
-
expect(medWide).toBeLessThan(medNarrow * 20); // catches >4x-per-property regressions
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
describe("Plugin Performance", () => {
|
|
195
|
-
it("plugin creation is fast", async () => {
|
|
196
|
-
const schema = schemas.complex.user();
|
|
197
|
-
|
|
198
|
-
const { duration } = await perf.measure(() => fakerPlugin({ schema }));
|
|
199
|
-
|
|
200
|
-
expect(duration).toBeLessThan(10); // Plugin creation should be instant
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it("plugin processing adds minimal overhead", async () => {
|
|
204
|
-
const schema = schemas.complex.apiResponse();
|
|
205
|
-
const plugin = fakerPlugin({ schema });
|
|
206
|
-
|
|
207
|
-
const context = {
|
|
208
|
-
method: "GET",
|
|
209
|
-
path: "/test",
|
|
210
|
-
params: {},
|
|
211
|
-
query: {},
|
|
212
|
-
state: {},
|
|
213
|
-
headers: {},
|
|
214
|
-
body: null,
|
|
215
|
-
route: {},
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
const times: number[] = [];
|
|
219
|
-
for (let i = 0; i < 10; i++) {
|
|
220
|
-
const { duration } = await perf.measure(() => plugin.process(context));
|
|
221
|
-
times.push(duration);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
|
|
225
|
-
expect(avgTime).toBeLessThan(100);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it("template processing is efficient", async () => {
|
|
229
|
-
const schema = schemas.simple.object({
|
|
230
|
-
id: schemas.simple.string(),
|
|
231
|
-
userId: schemas.simple.string(),
|
|
232
|
-
timestamp: schemas.simple.string(),
|
|
233
|
-
message: schemas.simple.string(),
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
const overrides = {
|
|
237
|
-
id: "{{params.id}}",
|
|
238
|
-
userId: "{{state.user.id}}",
|
|
239
|
-
timestamp: "{{state.timestamp}}",
|
|
240
|
-
message: "User {{params.id}} at {{state.timestamp}}",
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
const { duration } = await perf.measure(
|
|
244
|
-
async () =>
|
|
245
|
-
await generateFromSchema({
|
|
246
|
-
schema,
|
|
247
|
-
overrides,
|
|
248
|
-
params: { id: "123" },
|
|
249
|
-
state: {
|
|
250
|
-
user: { id: "user-456" },
|
|
251
|
-
timestamp: new Date().toISOString(),
|
|
252
|
-
},
|
|
253
|
-
}),
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
expect(duration).toBeLessThan(50); // Template processing should be fast
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
describe("Concurrent Generation", () => {
|
|
261
|
-
it("handles multiple concurrent generations", async () => {
|
|
262
|
-
const schema = schemas.complex.user();
|
|
263
|
-
|
|
264
|
-
const { duration } = await perf.measure(async () => {
|
|
265
|
-
const promises = Array.from(
|
|
266
|
-
{ length: 20 },
|
|
267
|
-
async () => await generateFromSchema({ schema }),
|
|
268
|
-
);
|
|
269
|
-
await Promise.all(promises);
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
expect(duration).toBeLessThan(500); // Should handle concurrency well
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
it("maintains performance under load", async () => {
|
|
276
|
-
const schema = schemas.simple.object({
|
|
277
|
-
id: schemas.simple.number(),
|
|
278
|
-
data: schemas.simple.string(),
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
// Warm up
|
|
282
|
-
await generateFromSchema({ schema });
|
|
283
|
-
|
|
284
|
-
// Test under load
|
|
285
|
-
const iterations = 100;
|
|
286
|
-
const { duration } = await perf.measure(async () => {
|
|
287
|
-
for (let i = 0; i < iterations; i++) {
|
|
288
|
-
await generateFromSchema({ schema });
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
const avgTime = duration / iterations;
|
|
293
|
-
expect(avgTime).toBeLessThan(10); // Should maintain speed
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
describe("Memory Efficiency", () => {
|
|
298
|
-
it("doesn't leak memory on repeated generation", async () => {
|
|
299
|
-
const schema = schemas.simple.object({
|
|
300
|
-
id: schemas.simple.number(),
|
|
301
|
-
name: schemas.simple.string(),
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
// Generate many times
|
|
305
|
-
for (let i = 0; i < 1000; i++) {
|
|
306
|
-
const result = await generateFromSchema({ schema });
|
|
307
|
-
// Result should be garbage collectable
|
|
308
|
-
expect(result).toBeDefined();
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// If we got here without crashing, memory is managed well
|
|
312
|
-
expect(true).toBe(true);
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
it("handles large data structures without excessive memory", async () => {
|
|
316
|
-
const schema = schemas.simple.array(
|
|
317
|
-
schemas.simple.object({
|
|
318
|
-
id: schemas.simple.string(),
|
|
319
|
-
data: schemas.simple.string(),
|
|
320
|
-
}),
|
|
321
|
-
{ minItems: 1000, maxItems: 1000 },
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
// Should be able to generate without memory issues
|
|
325
|
-
const result = await generateFromSchema({ schema });
|
|
326
|
-
expect(result).toHaveLength(1000);
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it("cleans up after schema validation errors", async () => {
|
|
330
|
-
// Generate errors repeatedly
|
|
331
|
-
for (let i = 0; i < 100; i++) {
|
|
332
|
-
try {
|
|
333
|
-
await generateFromSchema({ schema: { type: "invalid" as any } });
|
|
334
|
-
} catch (_e) {
|
|
335
|
-
// Expected
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Should not have memory leaks from error objects
|
|
340
|
-
expect(true).toBe(true);
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
describe("Optimization Opportunities", () => {
|
|
345
|
-
it("generates data consistently across multiple calls", async () => {
|
|
346
|
-
const schema = schemas.simple.object({
|
|
347
|
-
email: schemas.simple.string(),
|
|
348
|
-
firstName: schemas.simple.string(),
|
|
349
|
-
phone: schemas.simple.string(),
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// Generate multiple times to ensure consistent behavior
|
|
353
|
-
const results: any[] = [];
|
|
354
|
-
for (let i = 0; i < 10; i++) {
|
|
355
|
-
const result = await generateFromSchema({ schema });
|
|
356
|
-
results.push(result);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// Verify all results have the expected structure
|
|
360
|
-
results.forEach((result) => {
|
|
361
|
-
expect(result).toHaveProperty("email");
|
|
362
|
-
expect(result).toHaveProperty("firstName");
|
|
363
|
-
expect(result).toHaveProperty("phone");
|
|
364
|
-
expect(typeof result.email).toBe("string");
|
|
365
|
-
expect(typeof result.firstName).toBe("string");
|
|
366
|
-
expect(typeof result.phone).toBe("string");
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
// Verify that smart field mapping worked across all calls
|
|
370
|
-
const emails = results.map((r) => r.email);
|
|
371
|
-
const firstNames = results.map((r) => r.firstName);
|
|
372
|
-
|
|
373
|
-
// Should have good diversity (no exact duplicates expected)
|
|
374
|
-
const uniqueEmails = new Set(emails);
|
|
375
|
-
const uniqueFirstNames = new Set(firstNames);
|
|
376
|
-
expect(uniqueEmails.size).toBeGreaterThan(1);
|
|
377
|
-
expect(uniqueFirstNames.size).toBeGreaterThan(1);
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it("reuses schema enhancement for repeated generations", async () => {
|
|
381
|
-
const schema = schemas.complex.user();
|
|
382
|
-
const plugin = fakerPlugin({ schema });
|
|
383
|
-
|
|
384
|
-
const context = {
|
|
385
|
-
method: "GET",
|
|
386
|
-
path: "/test",
|
|
387
|
-
params: {},
|
|
388
|
-
query: {},
|
|
389
|
-
state: {},
|
|
390
|
-
headers: {},
|
|
391
|
-
body: null,
|
|
392
|
-
route: {},
|
|
393
|
-
};
|
|
394
|
-
|
|
395
|
-
// Warmup
|
|
396
|
-
for (let i = 0; i < 3; i++) {
|
|
397
|
-
plugin.process(context);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Multiple calls through same plugin with proper timing
|
|
401
|
-
const times: number[] = [];
|
|
402
|
-
for (let i = 0; i < 15; i++) {
|
|
403
|
-
const start = performance.now();
|
|
404
|
-
plugin.process(context);
|
|
405
|
-
times.push(performance.now() - start);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Calculate statistics
|
|
409
|
-
const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
|
|
410
|
-
const maxTime = Math.max(...times);
|
|
411
|
-
const minTime = Math.min(...times);
|
|
412
|
-
|
|
413
|
-
// Performance should be consistent and reasonable
|
|
414
|
-
expect(avgTime).toBeLessThan(50); // Should be reasonably fast
|
|
415
|
-
expect(maxTime).toBeLessThan(100); // No extreme outliers
|
|
416
|
-
expect(minTime).toBeGreaterThanOrEqual(0); // Valid timing
|
|
417
|
-
|
|
418
|
-
// All measurements should be reasonable - no extreme variance
|
|
419
|
-
const reasonableMaxTime = Math.max(avgTime * 5, 10); // At least 10ms tolerance
|
|
420
|
-
expect(maxTime).toBeLessThan(reasonableMaxTime);
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
describe("Edge Case Performance", () => {
|
|
425
|
-
it("handles empty schemas efficiently", async () => {
|
|
426
|
-
const schema = schemas.simple.object({});
|
|
427
|
-
|
|
428
|
-
const { duration } = await perf.measure(
|
|
429
|
-
async () => await generateFromSchema({ schema }),
|
|
430
|
-
);
|
|
431
|
-
|
|
432
|
-
expect(duration).toBeLessThan(10); // Empty should be instant
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
it("handles schemas with many enum values", async () => {
|
|
436
|
-
const schema = schemas.simple.object({
|
|
437
|
-
country: {
|
|
438
|
-
type: "string",
|
|
439
|
-
enum: Array.from({ length: 200 }, (_, i) => `country-${i}`),
|
|
440
|
-
},
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
const { duration } = await perf.measure(
|
|
444
|
-
async () => await generateFromSchema({ schema }),
|
|
445
|
-
);
|
|
446
|
-
|
|
447
|
-
expect(duration).toBeLessThan(50); // Large enum shouldn't be slow
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
it("handles complex regex patterns efficiently", async () => {
|
|
451
|
-
const schema = schemas.simple.object({
|
|
452
|
-
code: {
|
|
453
|
-
type: "string",
|
|
454
|
-
pattern: "^[A-Z]{2}-[0-9]{4}-[a-z]{2}-[0-9A-F]{8}$",
|
|
455
|
-
},
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
const { duration } = await perf.measure(() =>
|
|
459
|
-
generate.samples(schema, 10),
|
|
460
|
-
);
|
|
461
|
-
|
|
462
|
-
expect(duration).toBeLessThan(100); // Complex patterns OK
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it("handles mixed constraint schemas", async () => {
|
|
466
|
-
const schema: JSONSchema7 = {
|
|
467
|
-
anyOf: [
|
|
468
|
-
{
|
|
469
|
-
type: "object",
|
|
470
|
-
properties: {
|
|
471
|
-
type: { const: "A" },
|
|
472
|
-
data: { type: "string", minLength: 100 },
|
|
473
|
-
},
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
type: "array",
|
|
477
|
-
items: { type: "number", minimum: 0, maximum: 1000 },
|
|
478
|
-
minItems: 50,
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
type: "string",
|
|
482
|
-
pattern: "^[A-Za-z0-9+/]{100,}={0,2}$",
|
|
483
|
-
},
|
|
484
|
-
],
|
|
485
|
-
};
|
|
486
|
-
|
|
487
|
-
const { duration } = await perf.measure(
|
|
488
|
-
async () => await generateFromSchema({ schema }),
|
|
489
|
-
);
|
|
490
|
-
|
|
491
|
-
expect(duration).toBeLessThan(200); // Complex but manageable
|
|
492
|
-
});
|
|
493
|
-
});
|
|
494
|
-
});
|