@schmock/faker 2.3.0 → 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-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 +19 -4
- 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 +17 -7
- package/dist/constants.js +0 -8
- package/dist/field-mappings.js +0 -1114
- package/dist/field-name-matcher.js +0 -148
- package/dist/jsf-config.js +0 -117
- package/dist/overrides.js +0 -137
- package/dist/schema-enhancement.js +0 -104
- package/dist/test-utils.d.ts +0 -57
- package/dist/test-utils.d.ts.map +0 -1
- package/dist/test-utils.js +0 -284
- 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 -1148
- package/src/field-name-matcher.test.ts +0 -292
- package/src/field-name-matcher.ts +0 -187
- package/src/index.d.ts.map +0 -1
- package/src/index.test.ts +0 -1320
- package/src/index.ts +0 -185
- package/src/integration.test.ts +0 -634
- package/src/jsf-config.d.ts.map +0 -1
- package/src/jsf-config.test.ts +0 -65
- package/src/jsf-config.ts +0 -156
- 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 -179
- package/src/performance.test.ts +0 -441
- package/src/plugin-integration.test.ts +0 -575
- package/src/post-process.test.ts +0 -177
- package/src/real-world.test.ts +0 -636
- package/src/schema-enhancement.d.ts.map +0 -1
- package/src/schema-enhancement.test.ts +0 -222
- package/src/schema-enhancement.ts +0 -144
- package/src/steps/deterministic-seeds.steps.ts +0 -112
- package/src/steps/faker-plugin.steps.ts +0 -301
- package/src/test-utils.ts +0 -385
- package/src/validation.d.ts.map +0 -1
- package/src/validation.ts +0 -417
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { enhanceSchemaWithSmartMapping } from "./schema-enhancement";
|
|
4
|
-
|
|
5
|
-
describe("enhanceSchemaWithSmartMapping", () => {
|
|
6
|
-
it("does NOT mutate the original schema", () => {
|
|
7
|
-
const original: JSONSchema7 = {
|
|
8
|
-
type: "object",
|
|
9
|
-
properties: {
|
|
10
|
-
email: { type: "string" },
|
|
11
|
-
firstName: { type: "string" },
|
|
12
|
-
createdAt: { type: "string" },
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// Deep snapshot before enhancement
|
|
17
|
-
const snapshot = JSON.parse(JSON.stringify(original));
|
|
18
|
-
|
|
19
|
-
enhanceSchemaWithSmartMapping(original);
|
|
20
|
-
|
|
21
|
-
// Original should be unchanged
|
|
22
|
-
expect(original).toEqual(snapshot);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("enhancement of object with properties adds faker methods to appropriate fields", () => {
|
|
26
|
-
const schema: JSONSchema7 = {
|
|
27
|
-
type: "object",
|
|
28
|
-
properties: {
|
|
29
|
-
email: { type: "string" },
|
|
30
|
-
firstName: { type: "string" },
|
|
31
|
-
lastName: { type: "string" },
|
|
32
|
-
phone: { type: "string" },
|
|
33
|
-
uuid: { type: "string" },
|
|
34
|
-
},
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema) as Record<
|
|
38
|
-
string,
|
|
39
|
-
unknown
|
|
40
|
-
>;
|
|
41
|
-
const props = enhanced.properties as Record<
|
|
42
|
-
string,
|
|
43
|
-
JSONSchema7 & { faker?: string }
|
|
44
|
-
>;
|
|
45
|
-
|
|
46
|
-
// Well-known fields should receive faker methods
|
|
47
|
-
expect(props.email.faker).toBeDefined();
|
|
48
|
-
expect(props.firstName.faker).toBeDefined();
|
|
49
|
-
expect(props.lastName.faker).toBeDefined();
|
|
50
|
-
expect(props.phone.faker).toBeDefined();
|
|
51
|
-
expect(props.uuid.faker).toBeDefined();
|
|
52
|
-
|
|
53
|
-
// Verify they are plausible faker method strings (namespace.method format)
|
|
54
|
-
for (const field of ["email", "firstName", "lastName", "phone", "uuid"]) {
|
|
55
|
-
const fakerMethod = props[field].faker as string;
|
|
56
|
-
expect(fakerMethod).toContain(".");
|
|
57
|
-
expect(fakerMethod.split(".").length).toBeGreaterThanOrEqual(2);
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("enhancement recurses into allOf branches", () => {
|
|
62
|
-
const schema: JSONSchema7 = {
|
|
63
|
-
allOf: [
|
|
64
|
-
{
|
|
65
|
-
type: "object",
|
|
66
|
-
properties: {
|
|
67
|
-
email: { type: "string" },
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
type: "object",
|
|
72
|
-
properties: {
|
|
73
|
-
phone: { type: "string" },
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
],
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
80
|
-
const allOf = enhanced.allOf as Array<
|
|
81
|
-
JSONSchema7 & { properties: Record<string, { faker?: string }> }
|
|
82
|
-
>;
|
|
83
|
-
|
|
84
|
-
expect(allOf).toHaveLength(2);
|
|
85
|
-
expect(allOf[0].properties.email.faker).toBeDefined();
|
|
86
|
-
expect(allOf[1].properties.phone.faker).toBeDefined();
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("enhancement recurses into anyOf branches", () => {
|
|
90
|
-
const schema: JSONSchema7 = {
|
|
91
|
-
anyOf: [
|
|
92
|
-
{
|
|
93
|
-
type: "object",
|
|
94
|
-
properties: {
|
|
95
|
-
email: { type: "string" },
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
102
|
-
const anyOf = enhanced.anyOf as Array<
|
|
103
|
-
JSONSchema7 & { properties: Record<string, { faker?: string }> }
|
|
104
|
-
>;
|
|
105
|
-
|
|
106
|
-
expect(anyOf).toHaveLength(1);
|
|
107
|
-
expect(anyOf[0].properties.email.faker).toBeDefined();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("enhancement recurses into oneOf branches", () => {
|
|
111
|
-
const schema: JSONSchema7 = {
|
|
112
|
-
oneOf: [
|
|
113
|
-
{
|
|
114
|
-
type: "object",
|
|
115
|
-
properties: {
|
|
116
|
-
firstName: { type: "string" },
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
],
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
123
|
-
const oneOf = enhanced.oneOf as Array<
|
|
124
|
-
JSONSchema7 & { properties: Record<string, { faker?: string }> }
|
|
125
|
-
>;
|
|
126
|
-
|
|
127
|
-
expect(oneOf).toHaveLength(1);
|
|
128
|
-
expect(oneOf[0].properties.firstName.faker).toBeDefined();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("enhancement recurses into array items", () => {
|
|
132
|
-
const schema: JSONSchema7 = {
|
|
133
|
-
type: "array",
|
|
134
|
-
items: {
|
|
135
|
-
type: "object",
|
|
136
|
-
properties: {
|
|
137
|
-
email: { type: "string" },
|
|
138
|
-
createdAt: { type: "string" },
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
144
|
-
const items = enhanced.items as JSONSchema7 & {
|
|
145
|
-
properties: Record<string, { faker?: string }>;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
expect(items.properties.email.faker).toBeDefined();
|
|
149
|
-
expect(items.properties.createdAt.faker).toBeDefined();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("fields with existing faker property are not overridden", () => {
|
|
153
|
-
const schema: JSONSchema7 = {
|
|
154
|
-
type: "object",
|
|
155
|
-
properties: {
|
|
156
|
-
email: {
|
|
157
|
-
type: "string",
|
|
158
|
-
faker: "lorem.word",
|
|
159
|
-
} as JSONSchema7 & { faker: string },
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
164
|
-
const props = enhanced.properties as Record<
|
|
165
|
-
string,
|
|
166
|
-
JSONSchema7 & { faker?: string }
|
|
167
|
-
>;
|
|
168
|
-
|
|
169
|
-
// Should keep the explicit faker method, not replace with email generator
|
|
170
|
-
expect(props.email.faker).toBe("lorem.word");
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
it("adds useful text generation to an unconstrained root string", () => {
|
|
174
|
-
const schema: JSONSchema7 = { type: "string" };
|
|
175
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
176
|
-
expect(enhanced).toEqual({ type: "string", faker: "lorem.word" });
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it("preserves an explicit zero minimum length", () => {
|
|
180
|
-
const schema: JSONSchema7 = { type: "string", minLength: 0 };
|
|
181
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
182
|
-
expect(enhanced).toEqual(schema);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it("handles null/undefined schema gracefully", () => {
|
|
186
|
-
expect(enhanceSchemaWithSmartMapping(null as unknown as JSONSchema7)).toBe(
|
|
187
|
-
null,
|
|
188
|
-
);
|
|
189
|
-
expect(
|
|
190
|
-
enhanceSchemaWithSmartMapping(undefined as unknown as JSONSchema7),
|
|
191
|
-
).toBe(undefined);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it("enhancement recurses into array items when items is a tuple (array)", () => {
|
|
195
|
-
const schema: JSONSchema7 = {
|
|
196
|
-
type: "array",
|
|
197
|
-
items: [
|
|
198
|
-
{
|
|
199
|
-
type: "object",
|
|
200
|
-
properties: {
|
|
201
|
-
email: { type: "string" },
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
type: "object",
|
|
206
|
-
properties: {
|
|
207
|
-
phone: { type: "string" },
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
],
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const enhanced = enhanceSchemaWithSmartMapping(schema);
|
|
214
|
-
const items = enhanced.items as Array<
|
|
215
|
-
JSONSchema7 & { properties: Record<string, { faker?: string }> }
|
|
216
|
-
>;
|
|
217
|
-
|
|
218
|
-
expect(Array.isArray(items)).toBe(true);
|
|
219
|
-
expect(items[0].properties.email.faker).toBeDefined();
|
|
220
|
-
expect(items[1].properties.phone.faker).toBeDefined();
|
|
221
|
-
});
|
|
222
|
-
});
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
import { findBestMapping } from "./field-name-matcher.js";
|
|
3
|
-
import { isJSONSchema7, validateFakerMethod } from "./validation.js";
|
|
4
|
-
|
|
5
|
-
/** JSONSchema7 extended with json-schema-faker's `faker` property and schmock markers */
|
|
6
|
-
interface FakerSchema extends JSONSchema7 {
|
|
7
|
-
faker?: string | Record<string, unknown>;
|
|
8
|
-
schmockNullable?: boolean;
|
|
9
|
-
schmockTrueProbability?: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function needsStringFallback(schema: FakerSchema): boolean {
|
|
13
|
-
return (
|
|
14
|
-
schema.type === "string" &&
|
|
15
|
-
schema.faker === undefined &&
|
|
16
|
-
schema.format === undefined &&
|
|
17
|
-
schema.pattern === undefined &&
|
|
18
|
-
schema.enum === undefined &&
|
|
19
|
-
schema.const === undefined &&
|
|
20
|
-
schema.$ref === undefined &&
|
|
21
|
-
schema.minLength === undefined &&
|
|
22
|
-
schema.maxLength === undefined
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function enhanceSchemaWithSmartMapping(
|
|
27
|
-
schema: JSONSchema7,
|
|
28
|
-
): JSONSchema7 {
|
|
29
|
-
if (!schema || typeof schema !== "object") {
|
|
30
|
-
return schema;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const enhanced: FakerSchema = { ...schema };
|
|
34
|
-
|
|
35
|
-
// Handle object properties
|
|
36
|
-
if (enhanced.properties) {
|
|
37
|
-
enhanced.properties = { ...enhanced.properties };
|
|
38
|
-
|
|
39
|
-
for (const [fieldName, fieldSchema] of Object.entries(
|
|
40
|
-
enhanced.properties,
|
|
41
|
-
)) {
|
|
42
|
-
if (isJSONSchema7(fieldSchema)) {
|
|
43
|
-
enhanced.properties[fieldName] = enhanceFieldSchema(
|
|
44
|
-
fieldName,
|
|
45
|
-
fieldSchema,
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Recurse into composition keywords
|
|
52
|
-
for (const keyword of ["allOf", "anyOf", "oneOf"] as const) {
|
|
53
|
-
const branches = enhanced[keyword];
|
|
54
|
-
if (Array.isArray(branches)) {
|
|
55
|
-
enhanced[keyword] = branches.map((branch) =>
|
|
56
|
-
isJSONSchema7(branch) ? enhanceSchemaWithSmartMapping(branch) : branch,
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Recurse into array items
|
|
62
|
-
if (enhanced.items) {
|
|
63
|
-
if (Array.isArray(enhanced.items)) {
|
|
64
|
-
enhanced.items = enhanced.items.map((item) =>
|
|
65
|
-
isJSONSchema7(item) ? enhanceSchemaWithSmartMapping(item) : item,
|
|
66
|
-
);
|
|
67
|
-
} else if (isJSONSchema7(enhanced.items)) {
|
|
68
|
-
enhanced.items = enhanceSchemaWithSmartMapping(enhanced.items);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Recurse into additionalProperties
|
|
73
|
-
if (isJSONSchema7(enhanced.additionalProperties)) {
|
|
74
|
-
enhanced.additionalProperties = enhanceSchemaWithSmartMapping(
|
|
75
|
-
enhanced.additionalProperties,
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (needsStringFallback(enhanced)) {
|
|
80
|
-
enhanced.faker = "lorem.word";
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return enhanced;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function enhanceFieldSchema(
|
|
87
|
-
fieldName: string,
|
|
88
|
-
fieldSchema: JSONSchema7,
|
|
89
|
-
): FakerSchema {
|
|
90
|
-
const enhanced: FakerSchema = { ...fieldSchema };
|
|
91
|
-
|
|
92
|
-
// If already has faker extension, validate it and don't override.
|
|
93
|
-
// User-supplied faker values are always strings; the object form is only
|
|
94
|
-
// produced internally by this function when fakerArgs are present.
|
|
95
|
-
if (enhanced.faker) {
|
|
96
|
-
if (typeof enhanced.faker === "string") {
|
|
97
|
-
validateFakerMethod(enhanced.faker);
|
|
98
|
-
}
|
|
99
|
-
return enhanced;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Recursively enhance nested schemas first
|
|
103
|
-
const hasComposition = enhanced.allOf || enhanced.anyOf || enhanced.oneOf;
|
|
104
|
-
if (enhanced.properties || hasComposition || enhanced.items) {
|
|
105
|
-
const recursed = enhanceSchemaWithSmartMapping(enhanced);
|
|
106
|
-
Object.assign(enhanced, recursed);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Don't apply field-level faker mapping to composition schemas — the branches define their own types
|
|
110
|
-
if (hasComposition) {
|
|
111
|
-
return enhanced;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Don't apply smart mapping when const or enum is defined — these have fixed values
|
|
115
|
-
if (enhanced.const !== undefined || enhanced.enum) {
|
|
116
|
-
return enhanced;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Apply smart field name mapping via the scoring matcher
|
|
120
|
-
const match = findBestMapping(fieldName, enhanced);
|
|
121
|
-
if (match) {
|
|
122
|
-
const { fakerMethod, format, trueProbability, fakerArgs } = match.mapping;
|
|
123
|
-
// Use the JSF object form when fakerArgs are present so the options object
|
|
124
|
-
// is forwarded to the faker method (e.g. number.int({ min, max })).
|
|
125
|
-
// JSF calls Q(...J) where J is the value, so we must wrap fakerArgs in an
|
|
126
|
-
// array: { "number.int": [{ min, max }] } → faker.number.int({ min, max }).
|
|
127
|
-
// Fall back to the plain string form when there are no args.
|
|
128
|
-
if (fakerArgs) {
|
|
129
|
-
enhanced.faker = { [fakerMethod]: [fakerArgs] };
|
|
130
|
-
} else {
|
|
131
|
-
enhanced.faker = fakerMethod;
|
|
132
|
-
}
|
|
133
|
-
if (format) {
|
|
134
|
-
enhanced.format = format;
|
|
135
|
-
}
|
|
136
|
-
if (trueProbability !== undefined) {
|
|
137
|
-
enhanced.schmockTrueProbability = trueProbability;
|
|
138
|
-
}
|
|
139
|
-
} else if (needsStringFallback(enhanced)) {
|
|
140
|
-
enhanced.faker = "lorem.word";
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return enhanced;
|
|
144
|
-
}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describeFeature, loadFeature } from "@amiceli/vitest-cucumber";
|
|
2
|
-
import { expect } from "vitest";
|
|
3
|
-
import { generateFromSchema } from "../index";
|
|
4
|
-
|
|
5
|
-
const feature = await loadFeature("../../features/deterministic-seeds.feature");
|
|
6
|
-
|
|
7
|
-
const testSchema = {
|
|
8
|
-
type: "object" as const,
|
|
9
|
-
properties: {
|
|
10
|
-
name: { type: "string" as const },
|
|
11
|
-
age: { type: "integer" as const, minimum: 1, maximum: 100 },
|
|
12
|
-
},
|
|
13
|
-
required: ["name", "age"],
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
describeFeature(feature, ({ Scenario }) => {
|
|
17
|
-
let result1: unknown;
|
|
18
|
-
let result2: unknown;
|
|
19
|
-
let seededArray1: unknown;
|
|
20
|
-
let seededArray2: unknown;
|
|
21
|
-
let differentSeedResult1: unknown;
|
|
22
|
-
let differentSeedResult2: unknown;
|
|
23
|
-
|
|
24
|
-
Scenario("Same seed produces same output", ({ Given, When, Then }) => {
|
|
25
|
-
Given("a schema plugin with seed 42", () => {
|
|
26
|
-
// seed will be passed during generation
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
When("I generate data twice with the same seed", async () => {
|
|
30
|
-
result1 = await generateFromSchema({ schema: testSchema, seed: 42 });
|
|
31
|
-
result2 = await generateFromSchema({ schema: testSchema, seed: 42 });
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
Then("both outputs are identical", () => {
|
|
35
|
-
expect(result1).toEqual(result2);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
Scenario(
|
|
40
|
-
"Different seeds produce different output",
|
|
41
|
-
({ Given, When, Then }) => {
|
|
42
|
-
let firstSeed = 0;
|
|
43
|
-
let secondSeed = 0;
|
|
44
|
-
|
|
45
|
-
Given(
|
|
46
|
-
"a schema plugin using seeds {int} and {int}",
|
|
47
|
-
(_, seedA: number, seedB: number) => {
|
|
48
|
-
firstSeed = seedA;
|
|
49
|
-
secondSeed = seedB;
|
|
50
|
-
},
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
When("I generate data once with each seed", async () => {
|
|
54
|
-
differentSeedResult1 = await generateFromSchema({
|
|
55
|
-
schema: testSchema,
|
|
56
|
-
seed: firstSeed,
|
|
57
|
-
});
|
|
58
|
-
differentSeedResult2 = await generateFromSchema({
|
|
59
|
-
schema: testSchema,
|
|
60
|
-
seed: secondSeed,
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
Then("the differently seeded outputs are distinct", () => {
|
|
65
|
-
expect(differentSeedResult1).not.toEqual(differentSeedResult2);
|
|
66
|
-
});
|
|
67
|
-
},
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
Scenario(
|
|
71
|
-
"Seeded arrays are reproducible without repeating every item",
|
|
72
|
-
({ Given, When, Then, And }) => {
|
|
73
|
-
let count = 0;
|
|
74
|
-
|
|
75
|
-
Given(
|
|
76
|
-
"an array schema plugin with seed 42 and count {int}",
|
|
77
|
-
(_, requestedCount: number) => {
|
|
78
|
-
count = requestedCount;
|
|
79
|
-
},
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
When("I generate the seeded array twice", async () => {
|
|
83
|
-
const schema = {
|
|
84
|
-
type: "array" as const,
|
|
85
|
-
items: {
|
|
86
|
-
type: "object" as const,
|
|
87
|
-
properties: {
|
|
88
|
-
id: { type: "integer" as const },
|
|
89
|
-
name: { type: "string" as const },
|
|
90
|
-
},
|
|
91
|
-
required: ["id", "name"],
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
seededArray1 = await generateFromSchema({ schema, count, seed: 42 });
|
|
95
|
-
seededArray2 = await generateFromSchema({ schema, count, seed: 42 });
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
Then("both seeded arrays are identical", () => {
|
|
99
|
-
expect(seededArray1).toEqual(seededArray2);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
And("the seeded array contains varied items", () => {
|
|
103
|
-
expect(Array.isArray(seededArray1)).toBe(true);
|
|
104
|
-
if (!Array.isArray(seededArray1)) {
|
|
105
|
-
throw new Error("Expected seeded output to be an array");
|
|
106
|
-
}
|
|
107
|
-
const serialized = seededArray1.map((item) => JSON.stringify(item));
|
|
108
|
-
expect(new Set(serialized).size).toBeGreaterThan(1);
|
|
109
|
-
});
|
|
110
|
-
},
|
|
111
|
-
);
|
|
112
|
-
});
|