@schmock/faker 1.12.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/field-name-matcher.d.ts.map +1 -1
- package/dist/field-name-matcher.js +9 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/jsf-config.d.ts +8 -5
- package/dist/jsf-config.d.ts.map +1 -1
- package/dist/jsf-config.js +19 -42
- package/dist/schema-enhancement.js +4 -0
- package/dist/test-utils.d.ts +5 -5
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +25 -13
- package/package.json +4 -4
- package/src/advanced-features.test.ts +72 -71
- package/src/data-quality.test.ts +38 -38
- package/src/error-handling.test.ts +54 -56
- package/src/field-mappings.test.ts +74 -63
- package/src/field-name-matcher.ts +12 -2
- package/src/index.test.ts +145 -135
- package/src/index.ts +8 -6
- package/src/integration.test.ts +30 -28
- package/src/jsf-config.ts +21 -37
- package/src/performance.test.ts +45 -43
- package/src/plugin-integration.test.ts +46 -46
- package/src/real-world.test.ts +22 -22
- package/src/schema-enhancement.ts +5 -0
- package/src/steps/deterministic-seeds.steps.ts +24 -21
- package/src/steps/faker-plugin.steps.ts +190 -142
- package/src/test-utils.ts +38 -22
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "@schmock/core";
|
|
8
8
|
import type { JSONSchema7 } from "json-schema";
|
|
9
9
|
import { MAX_ARRAY_SIZE, NULLABLE_NULL_PROBABILITY } from "./constants.js";
|
|
10
|
-
import {
|
|
10
|
+
import { generateWithJsf } from "./jsf-config.js";
|
|
11
11
|
import { applyOverrides, determineArrayCount } from "./overrides.js";
|
|
12
12
|
import { enhanceSchemaWithSmartMapping } from "./schema-enhancement.js";
|
|
13
13
|
import { isJSONSchema7, validateSchema } from "./validation.js";
|
|
@@ -37,14 +37,14 @@ export function fakerPlugin(options: FakerPluginOptions): Schmock.Plugin {
|
|
|
37
37
|
name: "faker",
|
|
38
38
|
version: "1.0.1",
|
|
39
39
|
|
|
40
|
-
process(context: Schmock.PluginContext, response?: any) {
|
|
40
|
+
async process(context: Schmock.PluginContext, response?: any) {
|
|
41
41
|
// If response already exists, pass it through
|
|
42
42
|
if (response !== undefined && response !== null) {
|
|
43
43
|
return { context, response };
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
try {
|
|
47
|
-
const generatedResponse = generateFromSchema({
|
|
47
|
+
const generatedResponse = await generateFromSchema({
|
|
48
48
|
schema: options.schema,
|
|
49
49
|
count: options.count,
|
|
50
50
|
overrides: options.overrides,
|
|
@@ -78,7 +78,9 @@ export function fakerPlugin(options: FakerPluginOptions): Schmock.Plugin {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
export function generateFromSchema(
|
|
81
|
+
export async function generateFromSchema(
|
|
82
|
+
options: SchemaGenerationContext,
|
|
83
|
+
): Promise<any> {
|
|
82
84
|
const { schema, count, overrides, params, state, query, seed } = options;
|
|
83
85
|
|
|
84
86
|
validateSchema(schema);
|
|
@@ -110,7 +112,7 @@ export function generateFromSchema(options: SchemaGenerationContext): any {
|
|
|
110
112
|
|
|
111
113
|
generated = [];
|
|
112
114
|
for (let i = 0; i < itemCount; i++) {
|
|
113
|
-
let item =
|
|
115
|
+
let item = await generateWithJsf(enhancedItemSchema, seed);
|
|
114
116
|
item = postProcessGenerated(item, enhancedItemSchema);
|
|
115
117
|
item = applyOverrides(item, overrides, params, state, query);
|
|
116
118
|
generated.push(item);
|
|
@@ -118,7 +120,7 @@ export function generateFromSchema(options: SchemaGenerationContext): any {
|
|
|
118
120
|
} else {
|
|
119
121
|
// Handle object schemas
|
|
120
122
|
const enhancedSchema = enhanceSchemaWithSmartMapping(schema);
|
|
121
|
-
generated =
|
|
123
|
+
generated = await generateWithJsf(enhancedSchema, seed);
|
|
122
124
|
generated = postProcessGenerated(generated, enhancedSchema);
|
|
123
125
|
generated = applyOverrides(generated, overrides, params, state, query);
|
|
124
126
|
}
|
package/src/integration.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { generate, schemas, validators } from "./test-utils";
|
|
|
6
6
|
|
|
7
7
|
describe("Schema Generator Integration Tests", () => {
|
|
8
8
|
describe("End-to-End Scenarios", () => {
|
|
9
|
-
it("generates complete mock API response with relationships", () => {
|
|
9
|
+
it("generates complete mock API response with relationships", async () => {
|
|
10
10
|
const schema: JSONSchema7 = {
|
|
11
11
|
type: "object",
|
|
12
12
|
properties: {
|
|
@@ -59,7 +59,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
59
59
|
},
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
const result = generateFromSchema({ schema });
|
|
62
|
+
const result = await generateFromSchema({ schema });
|
|
63
63
|
|
|
64
64
|
// Verify complete structure
|
|
65
65
|
expect(result.user).toBeDefined();
|
|
@@ -87,7 +87,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
87
87
|
}
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
-
it("generates consistent data across related fields", () => {
|
|
90
|
+
it("generates consistent data across related fields", async () => {
|
|
91
91
|
const plugin = fakerPlugin({
|
|
92
92
|
schema: {
|
|
93
93
|
type: "object",
|
|
@@ -137,7 +137,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
137
137
|
route: {},
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
const result = plugin.process(context);
|
|
140
|
+
const result = await plugin.process(context);
|
|
141
141
|
|
|
142
142
|
expect(result.response.order.customerId).toBe("customer-456");
|
|
143
143
|
expect(result.response.order.createdAt).toBe("2024-01-01T10:00:00Z");
|
|
@@ -164,7 +164,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
describe("Cross-Package Integration", () => {
|
|
167
|
-
it("works with complex nested schemas from multiple sources", () => {
|
|
167
|
+
it("works with complex nested schemas from multiple sources", async () => {
|
|
168
168
|
const addressSchema: JSONSchema7 = {
|
|
169
169
|
type: "object",
|
|
170
170
|
properties: {
|
|
@@ -190,7 +190,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
190
190
|
},
|
|
191
191
|
};
|
|
192
192
|
|
|
193
|
-
const result = generateFromSchema({ schema: customerSchema });
|
|
193
|
+
const result = await generateFromSchema({ schema: customerSchema });
|
|
194
194
|
|
|
195
195
|
// Both addresses should be valid structures
|
|
196
196
|
expect(result.billingAddress.street).toBeDefined();
|
|
@@ -203,7 +203,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
203
203
|
expect(["US", "CA", "MX"]).toContain(result.shippingAddress.country);
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
it("handles schema composition with allOf, anyOf, oneOf", () => {
|
|
206
|
+
it("handles schema composition with allOf, anyOf, oneOf", async () => {
|
|
207
207
|
const baseSchema: JSONSchema7 = {
|
|
208
208
|
type: "object",
|
|
209
209
|
properties: {
|
|
@@ -245,7 +245,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
245
245
|
],
|
|
246
246
|
};
|
|
247
247
|
|
|
248
|
-
const results = generate.samples<any>(documentSchema, 10);
|
|
248
|
+
const results = await generate.samples<any>(documentSchema, 10);
|
|
249
249
|
|
|
250
250
|
results.forEach((result) => {
|
|
251
251
|
// Should have base properties
|
|
@@ -265,7 +265,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
265
265
|
});
|
|
266
266
|
|
|
267
267
|
describe("State Management Integration", () => {
|
|
268
|
-
it("maintains state across multiple generations", () => {
|
|
268
|
+
it("maintains state across multiple generations", async () => {
|
|
269
269
|
const _callCount = 0;
|
|
270
270
|
const plugin = fakerPlugin({
|
|
271
271
|
schema: {
|
|
@@ -293,7 +293,8 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
293
293
|
};
|
|
294
294
|
|
|
295
295
|
// Simulate multiple requests with evolving state
|
|
296
|
-
const results
|
|
296
|
+
const results: any[] = [];
|
|
297
|
+
for (let i = 0; i < 5; i++) {
|
|
297
298
|
const context = {
|
|
298
299
|
...baseContext,
|
|
299
300
|
state: new Map(),
|
|
@@ -302,8 +303,9 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
302
303
|
sessionId: "session-123",
|
|
303
304
|
},
|
|
304
305
|
};
|
|
305
|
-
|
|
306
|
-
|
|
306
|
+
const r = await plugin.process(context);
|
|
307
|
+
results.push(r.response);
|
|
308
|
+
}
|
|
307
309
|
|
|
308
310
|
// Request numbers should increment
|
|
309
311
|
results.forEach((result, i) => {
|
|
@@ -312,7 +314,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
312
314
|
});
|
|
313
315
|
});
|
|
314
316
|
|
|
315
|
-
it("generates stateful mock data", () => {
|
|
317
|
+
it("generates stateful mock data", async () => {
|
|
316
318
|
const cartSchema: JSONSchema7 = {
|
|
317
319
|
type: "object",
|
|
318
320
|
properties: {
|
|
@@ -334,10 +336,10 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
334
336
|
};
|
|
335
337
|
|
|
336
338
|
// Generate initial cart
|
|
337
|
-
const cart1 = generateFromSchema({ schema: cartSchema });
|
|
339
|
+
const cart1 = await generateFromSchema({ schema: cartSchema });
|
|
338
340
|
|
|
339
341
|
// Simulate adding items (would be done through state in real usage)
|
|
340
|
-
const cart2 = generateFromSchema({
|
|
342
|
+
const cart2 = await generateFromSchema({
|
|
341
343
|
schema: cartSchema,
|
|
342
344
|
overrides: {
|
|
343
345
|
id: cart1.id, // Keep same cart ID
|
|
@@ -352,7 +354,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
352
354
|
});
|
|
353
355
|
|
|
354
356
|
describe("Performance at Scale", () => {
|
|
355
|
-
it("generates large datasets efficiently", () => {
|
|
357
|
+
it("generates large datasets efficiently", async () => {
|
|
356
358
|
const schema: JSONSchema7 = {
|
|
357
359
|
type: "array",
|
|
358
360
|
items: {
|
|
@@ -374,7 +376,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
374
376
|
};
|
|
375
377
|
|
|
376
378
|
const startTime = Date.now();
|
|
377
|
-
const result = generateFromSchema({ schema, count: 100 });
|
|
379
|
+
const result = await generateFromSchema({ schema, count: 100 });
|
|
378
380
|
const duration = Date.now() - startTime;
|
|
379
381
|
|
|
380
382
|
expect(result).toHaveLength(100);
|
|
@@ -404,7 +406,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
404
406
|
|
|
405
407
|
// Simulate concurrent requests
|
|
406
408
|
const promises = Array.from({ length: 20 }, () =>
|
|
407
|
-
|
|
409
|
+
plugin.process(context),
|
|
408
410
|
);
|
|
409
411
|
|
|
410
412
|
const results = await Promise.all(promises);
|
|
@@ -420,10 +422,10 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
420
422
|
});
|
|
421
423
|
|
|
422
424
|
describe("Error Recovery and Resilience", () => {
|
|
423
|
-
it("recovers from validation errors gracefully", () => {
|
|
425
|
+
it("recovers from validation errors gracefully", async () => {
|
|
424
426
|
// First, try invalid schema
|
|
425
427
|
try {
|
|
426
|
-
generateFromSchema({
|
|
428
|
+
await generateFromSchema({
|
|
427
429
|
schema: {
|
|
428
430
|
type: "object",
|
|
429
431
|
properties: {
|
|
@@ -436,14 +438,14 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
436
438
|
}
|
|
437
439
|
|
|
438
440
|
// Should still work with valid schema
|
|
439
|
-
const result = generateFromSchema({
|
|
441
|
+
const result = await generateFromSchema({
|
|
440
442
|
schema: schemas.simple.object({ id: schemas.simple.number() }),
|
|
441
443
|
});
|
|
442
444
|
|
|
443
445
|
expect(result).toHaveProperty("id");
|
|
444
446
|
});
|
|
445
447
|
|
|
446
|
-
it("handles partial template failures", () => {
|
|
448
|
+
it("handles partial template failures", async () => {
|
|
447
449
|
const plugin = fakerPlugin({
|
|
448
450
|
schema: {
|
|
449
451
|
type: "object",
|
|
@@ -462,7 +464,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
462
464
|
},
|
|
463
465
|
});
|
|
464
466
|
|
|
465
|
-
const result = plugin.process({
|
|
467
|
+
const result = await plugin.process({
|
|
466
468
|
method: "GET",
|
|
467
469
|
path: "/test",
|
|
468
470
|
params: { value1: "success" },
|
|
@@ -485,7 +487,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
485
487
|
});
|
|
486
488
|
|
|
487
489
|
describe("Advanced Integration Patterns", () => {
|
|
488
|
-
it("supports pagination patterns", () => {
|
|
490
|
+
it("supports pagination patterns", async () => {
|
|
489
491
|
const paginatedSchema: JSONSchema7 = {
|
|
490
492
|
type: "object",
|
|
491
493
|
properties: {
|
|
@@ -523,7 +525,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
523
525
|
},
|
|
524
526
|
});
|
|
525
527
|
|
|
526
|
-
const result = plugin.process({
|
|
528
|
+
const result = await plugin.process({
|
|
527
529
|
method: "GET",
|
|
528
530
|
path: "/api/items",
|
|
529
531
|
params: {},
|
|
@@ -541,7 +543,7 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
541
543
|
expect(result.response.pagination.hasNext).toBe(true);
|
|
542
544
|
});
|
|
543
545
|
|
|
544
|
-
it("supports versioned API responses", () => {
|
|
546
|
+
it("supports versioned API responses", async () => {
|
|
545
547
|
const v1Schema: JSONSchema7 = {
|
|
546
548
|
type: "object",
|
|
547
549
|
properties: {
|
|
@@ -571,8 +573,8 @@ describe("Schema Generator Integration Tests", () => {
|
|
|
571
573
|
},
|
|
572
574
|
};
|
|
573
575
|
|
|
574
|
-
const v1Result = generateFromSchema({ schema: v1Schema });
|
|
575
|
-
const v2Result = generateFromSchema({ schema: v2Schema });
|
|
576
|
+
const v1Result = await generateFromSchema({ schema: v1Schema });
|
|
577
|
+
const v2Result = await generateFromSchema({ schema: v2Schema });
|
|
576
578
|
|
|
577
579
|
expect(v1Result.version).toBe("1.0");
|
|
578
580
|
expect(typeof v1Result.data.id).toBe("number");
|
package/src/jsf-config.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { base, en, Faker } from "@faker-js/faker";
|
|
2
|
-
import
|
|
2
|
+
import type { JSONSchema7 } from "json-schema";
|
|
3
|
+
import { generate } from "json-schema-faker";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
|
-
* Create isolated faker instance to avoid race conditions
|
|
6
|
-
* Each generation gets its own faker instance to ensure thread-safety
|
|
7
|
-
* @returns Fresh Faker instance with English locale
|
|
6
|
+
* Create isolated faker instance to avoid race conditions.
|
|
7
|
+
* Each generation gets its own faker instance to ensure thread-safety.
|
|
8
8
|
*/
|
|
9
9
|
export function createFakerInstance(seed?: number) {
|
|
10
10
|
const faker = new Faker({ locale: [en, base] });
|
|
@@ -14,45 +14,29 @@ export function createFakerInstance(seed?: number) {
|
|
|
14
14
|
return faker;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
let jsfConfigured = false;
|
|
18
|
-
let currentSeed: number | undefined;
|
|
19
|
-
|
|
20
17
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
18
|
+
* Generate data from a JSON schema using json-schema-faker 0.6.0 async API.
|
|
19
|
+
* Stateless — each call is self-contained with its own faker instance and options.
|
|
23
20
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
21
|
+
export async function generateWithJsf(
|
|
22
|
+
schema: JSONSchema7,
|
|
23
|
+
seed?: number,
|
|
24
|
+
): Promise<unknown> {
|
|
25
|
+
// When no seed is specified, generate a random seed to ensure different
|
|
26
|
+
// results on each call. JSF 0.6.0 treats seed=undefined as deterministic.
|
|
27
|
+
const effectiveSeed = seed ?? Math.floor(Math.random() * 2147483647);
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
jsf.option({
|
|
41
|
-
requiredOnly: false,
|
|
29
|
+
return generate(
|
|
30
|
+
schema as any,
|
|
31
|
+
{
|
|
32
|
+
seed: effectiveSeed,
|
|
33
|
+
optionalsProbability: 1.0,
|
|
42
34
|
alwaysFakeOptionals: true,
|
|
43
35
|
useDefaultValue: true,
|
|
44
36
|
ignoreMissingRefs: true,
|
|
45
37
|
failOnInvalidTypes: false,
|
|
46
38
|
failOnInvalidFormat: false,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// Always reset PRNG for deterministic output per call
|
|
51
|
-
if (seed !== undefined) {
|
|
52
|
-
jsf.option({ random: createSeededRandom(seed) });
|
|
53
|
-
jsf.extend("faker", () => createFakerInstance(seed));
|
|
54
|
-
} else {
|
|
55
|
-
jsf.option({ random: Math.random });
|
|
56
|
-
}
|
|
57
|
-
return jsf;
|
|
39
|
+
extensions: { faker: createFakerInstance(seed) },
|
|
40
|
+
} as any,
|
|
41
|
+
);
|
|
58
42
|
}
|
package/src/performance.test.ts
CHANGED
|
@@ -14,8 +14,8 @@ describe("Performance and Memory", () => {
|
|
|
14
14
|
|
|
15
15
|
const times: number[] = [];
|
|
16
16
|
for (let i = 0; i < 10; i++) {
|
|
17
|
-
const { duration } = await perf.measure(
|
|
18
|
-
generateFromSchema({ schema }),
|
|
17
|
+
const { duration } = await perf.measure(
|
|
18
|
+
async () => await generateFromSchema({ schema }),
|
|
19
19
|
);
|
|
20
20
|
times.push(duration);
|
|
21
21
|
}
|
|
@@ -33,8 +33,8 @@ describe("Performance and Memory", () => {
|
|
|
33
33
|
}),
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
const { duration } = await perf.measure(
|
|
37
|
-
generateFromSchema({ schema }),
|
|
36
|
+
const { duration } = await perf.measure(
|
|
37
|
+
async () => await generateFromSchema({ schema }),
|
|
38
38
|
);
|
|
39
39
|
|
|
40
40
|
expect(duration).toBeLessThan(100); // Reasonable for nested structure
|
|
@@ -49,8 +49,8 @@ describe("Performance and Memory", () => {
|
|
|
49
49
|
{ minItems: 50, maxItems: 50 },
|
|
50
50
|
);
|
|
51
51
|
|
|
52
|
-
const { duration } = await perf.measure(
|
|
53
|
-
generateFromSchema({ schema }),
|
|
52
|
+
const { duration } = await perf.measure(
|
|
53
|
+
async () => await generateFromSchema({ schema }),
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
expect(duration).toBeLessThan(200); // Should handle 50 items quickly
|
|
@@ -82,8 +82,8 @@ describe("Performance and Memory", () => {
|
|
|
82
82
|
},
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
const { duration } = await perf.measure(
|
|
86
|
-
generateFromSchema({ schema }),
|
|
85
|
+
const { duration } = await perf.measure(
|
|
86
|
+
async () => await generateFromSchema({ schema }),
|
|
87
87
|
);
|
|
88
88
|
|
|
89
89
|
expect(duration).toBeLessThan(300); // Complex but still reasonable
|
|
@@ -104,8 +104,8 @@ describe("Performance and Memory", () => {
|
|
|
104
104
|
|
|
105
105
|
// Warmup runs to stabilize JIT
|
|
106
106
|
for (let i = 0; i < 3; i++) {
|
|
107
|
-
generateFromSchema({ schema: smallSchema });
|
|
108
|
-
generateFromSchema({ schema: largeSchema });
|
|
107
|
+
await generateFromSchema({ schema: smallSchema });
|
|
108
|
+
await generateFromSchema({ schema: largeSchema });
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// Multiple measurement runs for statistical stability
|
|
@@ -114,12 +114,12 @@ describe("Performance and Memory", () => {
|
|
|
114
114
|
|
|
115
115
|
for (let i = 0; i < 10; i++) {
|
|
116
116
|
const start1 = performance.now();
|
|
117
|
-
generateFromSchema({ schema: smallSchema });
|
|
117
|
+
await generateFromSchema({ schema: smallSchema });
|
|
118
118
|
const small = performance.now() - start1;
|
|
119
119
|
smallTimes.push(small);
|
|
120
120
|
|
|
121
121
|
const start2 = performance.now();
|
|
122
|
-
generateFromSchema({ schema: largeSchema });
|
|
122
|
+
await generateFromSchema({ schema: largeSchema });
|
|
123
123
|
const large = performance.now() - start2;
|
|
124
124
|
largeTimes.push(large);
|
|
125
125
|
}
|
|
@@ -148,8 +148,8 @@ describe("Performance and Memory", () => {
|
|
|
148
148
|
|
|
149
149
|
// Warmup
|
|
150
150
|
for (let i = 0; i < 3; i++) {
|
|
151
|
-
generateFromSchema({ schema: narrowSchema });
|
|
152
|
-
generateFromSchema({ schema: wideSchema });
|
|
151
|
+
await generateFromSchema({ schema: narrowSchema });
|
|
152
|
+
await generateFromSchema({ schema: wideSchema });
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// Measure with multiple runs, dropping outliers
|
|
@@ -158,11 +158,11 @@ describe("Performance and Memory", () => {
|
|
|
158
158
|
|
|
159
159
|
for (let i = 0; i < 10; i++) {
|
|
160
160
|
const start1 = performance.now();
|
|
161
|
-
generateFromSchema({ schema: narrowSchema });
|
|
161
|
+
await generateFromSchema({ schema: narrowSchema });
|
|
162
162
|
narrowTimes.push(performance.now() - start1);
|
|
163
163
|
|
|
164
164
|
const start2 = performance.now();
|
|
165
|
-
generateFromSchema({ schema: wideSchema });
|
|
165
|
+
await generateFromSchema({ schema: wideSchema });
|
|
166
166
|
wideTimes.push(performance.now() - start2);
|
|
167
167
|
}
|
|
168
168
|
|
|
@@ -231,16 +231,17 @@ describe("Performance and Memory", () => {
|
|
|
231
231
|
message: "User {{params.id}} at {{state.timestamp}}",
|
|
232
232
|
};
|
|
233
233
|
|
|
234
|
-
const { duration } = await perf.measure(
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
234
|
+
const { duration } = await perf.measure(
|
|
235
|
+
async () =>
|
|
236
|
+
await generateFromSchema({
|
|
237
|
+
schema,
|
|
238
|
+
overrides,
|
|
239
|
+
params: { id: "123" },
|
|
240
|
+
state: {
|
|
241
|
+
user: { id: "user-456" },
|
|
242
|
+
timestamp: new Date().toISOString(),
|
|
243
|
+
},
|
|
244
|
+
}),
|
|
244
245
|
);
|
|
245
246
|
|
|
246
247
|
expect(duration).toBeLessThan(50); // Template processing should be fast
|
|
@@ -252,8 +253,9 @@ describe("Performance and Memory", () => {
|
|
|
252
253
|
const schema = schemas.complex.user();
|
|
253
254
|
|
|
254
255
|
const { duration } = await perf.measure(async () => {
|
|
255
|
-
const promises = Array.from(
|
|
256
|
-
|
|
256
|
+
const promises = Array.from(
|
|
257
|
+
{ length: 20 },
|
|
258
|
+
async () => await generateFromSchema({ schema }),
|
|
257
259
|
);
|
|
258
260
|
await Promise.all(promises);
|
|
259
261
|
});
|
|
@@ -268,13 +270,13 @@ describe("Performance and Memory", () => {
|
|
|
268
270
|
});
|
|
269
271
|
|
|
270
272
|
// Warm up
|
|
271
|
-
generateFromSchema({ schema });
|
|
273
|
+
await generateFromSchema({ schema });
|
|
272
274
|
|
|
273
275
|
// Test under load
|
|
274
276
|
const iterations = 100;
|
|
275
277
|
const { duration } = await perf.measure(async () => {
|
|
276
278
|
for (let i = 0; i < iterations; i++) {
|
|
277
|
-
generateFromSchema({ schema });
|
|
279
|
+
await generateFromSchema({ schema });
|
|
278
280
|
}
|
|
279
281
|
});
|
|
280
282
|
|
|
@@ -284,7 +286,7 @@ describe("Performance and Memory", () => {
|
|
|
284
286
|
});
|
|
285
287
|
|
|
286
288
|
describe("Memory Efficiency", () => {
|
|
287
|
-
it("doesn't leak memory on repeated generation", () => {
|
|
289
|
+
it("doesn't leak memory on repeated generation", async () => {
|
|
288
290
|
const schema = schemas.simple.object({
|
|
289
291
|
id: schemas.simple.number(),
|
|
290
292
|
name: schemas.simple.string(),
|
|
@@ -292,7 +294,7 @@ describe("Performance and Memory", () => {
|
|
|
292
294
|
|
|
293
295
|
// Generate many times
|
|
294
296
|
for (let i = 0; i < 1000; i++) {
|
|
295
|
-
const result = generateFromSchema({ schema });
|
|
297
|
+
const result = await generateFromSchema({ schema });
|
|
296
298
|
// Result should be garbage collectable
|
|
297
299
|
expect(result).toBeDefined();
|
|
298
300
|
}
|
|
@@ -301,7 +303,7 @@ describe("Performance and Memory", () => {
|
|
|
301
303
|
expect(true).toBe(true);
|
|
302
304
|
});
|
|
303
305
|
|
|
304
|
-
it("handles large data structures without excessive memory", () => {
|
|
306
|
+
it("handles large data structures without excessive memory", async () => {
|
|
305
307
|
const schema = schemas.simple.array(
|
|
306
308
|
schemas.simple.object({
|
|
307
309
|
id: schemas.simple.string(),
|
|
@@ -311,15 +313,15 @@ describe("Performance and Memory", () => {
|
|
|
311
313
|
);
|
|
312
314
|
|
|
313
315
|
// Should be able to generate without memory issues
|
|
314
|
-
const result = generateFromSchema({ schema });
|
|
316
|
+
const result = await generateFromSchema({ schema });
|
|
315
317
|
expect(result).toHaveLength(1000);
|
|
316
318
|
});
|
|
317
319
|
|
|
318
|
-
it("cleans up after schema validation errors", () => {
|
|
320
|
+
it("cleans up after schema validation errors", async () => {
|
|
319
321
|
// Generate errors repeatedly
|
|
320
322
|
for (let i = 0; i < 100; i++) {
|
|
321
323
|
try {
|
|
322
|
-
generateFromSchema({ schema: { type: "invalid" as any } });
|
|
324
|
+
await generateFromSchema({ schema: { type: "invalid" as any } });
|
|
323
325
|
} catch (_e) {
|
|
324
326
|
// Expected
|
|
325
327
|
}
|
|
@@ -341,7 +343,7 @@ describe("Performance and Memory", () => {
|
|
|
341
343
|
// Generate multiple times to ensure consistent behavior
|
|
342
344
|
const results: any[] = [];
|
|
343
345
|
for (let i = 0; i < 10; i++) {
|
|
344
|
-
const result = generateFromSchema({ schema });
|
|
346
|
+
const result = await generateFromSchema({ schema });
|
|
345
347
|
results.push(result);
|
|
346
348
|
}
|
|
347
349
|
|
|
@@ -414,8 +416,8 @@ describe("Performance and Memory", () => {
|
|
|
414
416
|
it("handles empty schemas efficiently", async () => {
|
|
415
417
|
const schema = schemas.simple.object({});
|
|
416
418
|
|
|
417
|
-
const { duration } = await perf.measure(
|
|
418
|
-
generateFromSchema({ schema }),
|
|
419
|
+
const { duration } = await perf.measure(
|
|
420
|
+
async () => await generateFromSchema({ schema }),
|
|
419
421
|
);
|
|
420
422
|
|
|
421
423
|
expect(duration).toBeLessThan(10); // Empty should be instant
|
|
@@ -429,8 +431,8 @@ describe("Performance and Memory", () => {
|
|
|
429
431
|
},
|
|
430
432
|
});
|
|
431
433
|
|
|
432
|
-
const { duration } = await perf.measure(
|
|
433
|
-
generateFromSchema({ schema }),
|
|
434
|
+
const { duration } = await perf.measure(
|
|
435
|
+
async () => await generateFromSchema({ schema }),
|
|
434
436
|
);
|
|
435
437
|
|
|
436
438
|
expect(duration).toBeLessThan(50); // Large enum shouldn't be slow
|
|
@@ -473,8 +475,8 @@ describe("Performance and Memory", () => {
|
|
|
473
475
|
],
|
|
474
476
|
};
|
|
475
477
|
|
|
476
|
-
const { duration } = await perf.measure(
|
|
477
|
-
generateFromSchema({ schema }),
|
|
478
|
+
const { duration } = await perf.measure(
|
|
479
|
+
async () => await generateFromSchema({ schema }),
|
|
478
480
|
);
|
|
479
481
|
|
|
480
482
|
expect(duration).toBeLessThan(200); // Complex but manageable
|