@casekit/orm2-testing 0.0.1 → 1.0.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/build/factory.d.ts +6 -0
- package/build/factory.js +30 -0
- package/build/generate.d.ts +2 -0
- package/{src/generate.ts → build/generate.js} +30 -21
- package/build/generate.test.d.ts +1 -0
- package/{src/generate.test.ts → build/generate.test.js} +11 -49
- package/build/index.js +1 -0
- package/package.json +10 -10
- package/src/factory.ts +0 -47
- /package/{src/index.ts → build/index.d.ts} +0 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { NormalizedConfig } from "@casekit/orm2-config";
|
|
2
|
+
import { ModelDefinitions, ModelName, ModelType } from "@casekit/orm2-schema";
|
|
3
|
+
export type Factory<Models extends ModelDefinitions> = {
|
|
4
|
+
[M in ModelName<Models>]: (overrides?: Partial<ModelType<Models[M]>>) => ModelType<Models[M]>;
|
|
5
|
+
};
|
|
6
|
+
export declare const makeFactory: <Models extends ModelDefinitions>(config: NormalizedConfig) => Factory<Models>;
|
package/build/factory.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { mapValues, uniq } from "es-toolkit";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { generate } from "./generate.js";
|
|
4
|
+
export const makeFactory = (config) => {
|
|
5
|
+
return mapValues(config.models, (model) => {
|
|
6
|
+
// We never want to generate foreign key values
|
|
7
|
+
// as there's no way for us to know how to generate
|
|
8
|
+
// valid ones. This is up to the user to provide.
|
|
9
|
+
const fkOverrides = Object.fromEntries(uniq(model.foreignKeys.flatMap((fk) => fk.fields)).map((fk) => [
|
|
10
|
+
fk,
|
|
11
|
+
null,
|
|
12
|
+
]));
|
|
13
|
+
const fields = Object.entries(model.fields)
|
|
14
|
+
.filter(([_, f]) => !f.provided)
|
|
15
|
+
.map(([name, f]) => [
|
|
16
|
+
name,
|
|
17
|
+
f.default
|
|
18
|
+
? f.zodSchema.optional()
|
|
19
|
+
: f.nullable
|
|
20
|
+
? f.zodSchema.nullable()
|
|
21
|
+
: f.zodSchema,
|
|
22
|
+
]);
|
|
23
|
+
const schema = z.object(Object.fromEntries(fields));
|
|
24
|
+
return (overrides) => ({
|
|
25
|
+
...generate(schema),
|
|
26
|
+
...fkOverrides,
|
|
27
|
+
...overrides,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -1,49 +1,58 @@
|
|
|
1
1
|
import { faker } from "@faker-js/faker";
|
|
2
|
-
import z, { ZodObject
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const generateInner = <T>(schema: $ZodType<T>): unknown => {
|
|
2
|
+
import z, { ZodObject } from "zod";
|
|
3
|
+
const generateInner = (schema) => {
|
|
6
4
|
if (schema instanceof ZodObject) {
|
|
7
5
|
const shape = schema.shape;
|
|
8
|
-
const result
|
|
6
|
+
const result = {};
|
|
9
7
|
for (const key in shape) {
|
|
10
8
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
11
9
|
result[key] = generateInner(shape[key]);
|
|
12
10
|
}
|
|
13
|
-
return result
|
|
14
|
-
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
else if (schema instanceof z.ZodOptional) {
|
|
15
14
|
return generateInner(schema.def.innerType);
|
|
16
|
-
}
|
|
15
|
+
}
|
|
16
|
+
else if (schema instanceof z.ZodRecord) {
|
|
17
17
|
return {
|
|
18
18
|
a: generateInner(schema.valueType),
|
|
19
19
|
b: generateInner(schema.valueType),
|
|
20
20
|
c: generateInner(schema.valueType),
|
|
21
21
|
};
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
|
+
else if (schema instanceof z.ZodEnum) {
|
|
23
24
|
return faker.helpers.arrayElement(Object.values(schema.def.entries));
|
|
24
|
-
}
|
|
25
|
+
}
|
|
26
|
+
else if (schema instanceof z.ZodArray) {
|
|
25
27
|
return faker.helpers.multiple(() => generateInner(schema.element), {
|
|
26
28
|
count: { min: 1, max: 3 },
|
|
27
29
|
});
|
|
28
|
-
}
|
|
30
|
+
}
|
|
31
|
+
else if (schema instanceof z.ZodDate) {
|
|
29
32
|
return faker.date.past();
|
|
30
|
-
}
|
|
33
|
+
}
|
|
34
|
+
else if (schema instanceof z.ZodBoolean) {
|
|
31
35
|
return faker.datatype.boolean();
|
|
32
|
-
}
|
|
36
|
+
}
|
|
37
|
+
else if (schema instanceof z.ZodUUID) {
|
|
33
38
|
return faker.string.uuid();
|
|
34
|
-
}
|
|
39
|
+
}
|
|
40
|
+
else if (schema instanceof z.ZodString) {
|
|
35
41
|
return faker.lorem.word();
|
|
36
|
-
}
|
|
42
|
+
}
|
|
43
|
+
else if (schema instanceof z.ZodEmail) {
|
|
37
44
|
return faker.internet.exampleEmail();
|
|
38
|
-
}
|
|
45
|
+
}
|
|
46
|
+
else if (schema instanceof z.ZodBigInt) {
|
|
39
47
|
return faker.number.int({ min: 1, max: 100 });
|
|
40
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else if (schema instanceof z.ZodNumber) {
|
|
41
50
|
return faker.number.int({ min: 1, max: 100 });
|
|
42
|
-
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
43
53
|
return undefined;
|
|
44
54
|
}
|
|
45
55
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return { ...(generateInner(schema) as T), ...overrides };
|
|
56
|
+
export const generate = (schema, overrides) => {
|
|
57
|
+
return { ...generateInner(schema), ...overrides };
|
|
49
58
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
|
|
4
3
|
import { generate } from "./generate.js";
|
|
5
|
-
|
|
6
4
|
describe("generate", () => {
|
|
7
5
|
it("generates a simple object with string fields", () => {
|
|
8
6
|
const schema = z.object({
|
|
9
7
|
name: z.string(),
|
|
10
8
|
description: z.string(),
|
|
11
9
|
});
|
|
12
|
-
|
|
13
10
|
const result = generate(schema);
|
|
14
|
-
|
|
15
11
|
expect(result).toEqual({
|
|
16
12
|
name: expect.any(String),
|
|
17
13
|
description: expect.any(String),
|
|
18
14
|
});
|
|
19
15
|
});
|
|
20
|
-
|
|
21
16
|
it("generates an object with various field types", () => {
|
|
22
17
|
const schema = z.object({
|
|
23
18
|
id: z.uuid(),
|
|
@@ -27,9 +22,7 @@ describe("generate", () => {
|
|
|
27
22
|
createdAt: z.date(),
|
|
28
23
|
balance: z.bigint(),
|
|
29
24
|
});
|
|
30
|
-
|
|
31
25
|
const result = generate(schema);
|
|
32
|
-
|
|
33
26
|
expect(result).toEqual({
|
|
34
27
|
id: expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),
|
|
35
28
|
name: expect.any(String),
|
|
@@ -39,7 +32,6 @@ describe("generate", () => {
|
|
|
39
32
|
balance: expect.any(Number),
|
|
40
33
|
});
|
|
41
34
|
});
|
|
42
|
-
|
|
43
35
|
it("generates nested objects", () => {
|
|
44
36
|
const schema = z.object({
|
|
45
37
|
user: z.object({
|
|
@@ -51,9 +43,7 @@ describe("generate", () => {
|
|
|
51
43
|
theme: z.string(),
|
|
52
44
|
}),
|
|
53
45
|
});
|
|
54
|
-
|
|
55
46
|
const result = generate(schema);
|
|
56
|
-
|
|
57
47
|
expect(result).toEqual({
|
|
58
48
|
user: {
|
|
59
49
|
name: expect.any(String),
|
|
@@ -65,27 +55,21 @@ describe("generate", () => {
|
|
|
65
55
|
},
|
|
66
56
|
});
|
|
67
57
|
});
|
|
68
|
-
|
|
69
58
|
it("generates arrays", () => {
|
|
70
59
|
const schema = z.object({
|
|
71
60
|
tags: z.array(z.string()),
|
|
72
61
|
scores: z.array(z.number()),
|
|
73
62
|
});
|
|
74
|
-
|
|
75
63
|
const result = generate(schema);
|
|
76
|
-
|
|
77
64
|
expect(result.tags).toEqual(expect.arrayContaining([expect.any(String)]));
|
|
78
65
|
expect(result.scores).toEqual(expect.arrayContaining([expect.any(Number)]));
|
|
79
66
|
});
|
|
80
|
-
|
|
81
67
|
it("generates records", () => {
|
|
82
68
|
const schema = z.object({
|
|
83
69
|
metadata: z.record(z.string(), z.string()),
|
|
84
70
|
counts: z.record(z.number(), z.string()),
|
|
85
71
|
});
|
|
86
|
-
|
|
87
72
|
const result = generate(schema);
|
|
88
|
-
|
|
89
73
|
expect(result).toEqual({
|
|
90
74
|
metadata: {
|
|
91
75
|
a: expect.any(String),
|
|
@@ -99,19 +83,14 @@ describe("generate", () => {
|
|
|
99
83
|
},
|
|
100
84
|
});
|
|
101
85
|
});
|
|
102
|
-
|
|
103
86
|
it("generates arrays of objects", () => {
|
|
104
87
|
const schema = z.object({
|
|
105
|
-
users: z.array(
|
|
106
|
-
z.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}),
|
|
110
|
-
),
|
|
88
|
+
users: z.array(z.object({
|
|
89
|
+
id: z.string().uuid(),
|
|
90
|
+
name: z.string(),
|
|
91
|
+
})),
|
|
111
92
|
});
|
|
112
|
-
|
|
113
93
|
const result = generate(schema);
|
|
114
|
-
|
|
115
94
|
expect(result).toEqual({
|
|
116
95
|
users: expect.arrayContaining([
|
|
117
96
|
expect.objectContaining({
|
|
@@ -121,44 +100,37 @@ describe("generate", () => {
|
|
|
121
100
|
]),
|
|
122
101
|
});
|
|
123
102
|
});
|
|
124
|
-
|
|
125
103
|
it("applies overrides to generated data", () => {
|
|
126
104
|
const schema = z.object({
|
|
127
105
|
name: z.string(),
|
|
128
106
|
age: z.number(),
|
|
129
107
|
isActive: z.boolean(),
|
|
130
108
|
});
|
|
131
|
-
|
|
132
109
|
const result = generate(schema, {
|
|
133
110
|
name: "John Doe",
|
|
134
111
|
age: 30,
|
|
135
112
|
});
|
|
136
|
-
|
|
137
113
|
expect(result).toEqual({
|
|
138
114
|
name: "John Doe",
|
|
139
115
|
age: 30,
|
|
140
116
|
isActive: expect.any(Boolean),
|
|
141
117
|
});
|
|
142
118
|
});
|
|
143
|
-
|
|
144
119
|
it("handles partial overrides", () => {
|
|
145
120
|
const schema = z.object({
|
|
146
121
|
id: z.string().uuid(),
|
|
147
122
|
name: z.string(),
|
|
148
123
|
email: z.string(),
|
|
149
124
|
});
|
|
150
|
-
|
|
151
125
|
const result = generate(schema, {
|
|
152
126
|
name: "Jane Smith",
|
|
153
127
|
});
|
|
154
|
-
|
|
155
128
|
expect(result).toEqual({
|
|
156
129
|
id: expect.stringMatching(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/),
|
|
157
130
|
name: "Jane Smith",
|
|
158
131
|
email: expect.any(String),
|
|
159
132
|
});
|
|
160
133
|
});
|
|
161
|
-
|
|
162
134
|
it("generates deeply nested structures", () => {
|
|
163
135
|
const schema = z.object({
|
|
164
136
|
level1: z.object({
|
|
@@ -169,9 +141,7 @@ describe("generate", () => {
|
|
|
169
141
|
}),
|
|
170
142
|
}),
|
|
171
143
|
});
|
|
172
|
-
|
|
173
144
|
const result = generate(schema);
|
|
174
|
-
|
|
175
145
|
expect(result).toEqual({
|
|
176
146
|
level1: {
|
|
177
147
|
level2: {
|
|
@@ -182,39 +152,31 @@ describe("generate", () => {
|
|
|
182
152
|
},
|
|
183
153
|
});
|
|
184
154
|
});
|
|
185
|
-
|
|
186
155
|
it("handles unknown schema types by returning undefined", () => {
|
|
187
|
-
const customSchema = z.custom
|
|
156
|
+
const customSchema = z.custom((val) => typeof val === "string");
|
|
188
157
|
const schema = z.object({
|
|
189
158
|
custom: customSchema,
|
|
190
159
|
});
|
|
191
|
-
|
|
192
160
|
const result = generate(schema);
|
|
193
|
-
|
|
194
161
|
expect(result).toEqual({
|
|
195
162
|
custom: undefined,
|
|
196
163
|
});
|
|
197
164
|
});
|
|
198
|
-
|
|
199
165
|
it("generates complex mixed structures", () => {
|
|
200
166
|
const schema = z.object({
|
|
201
167
|
company: z.object({
|
|
202
168
|
name: z.string(),
|
|
203
169
|
founded: z.date(),
|
|
204
|
-
employees: z.array(
|
|
205
|
-
z.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}),
|
|
211
|
-
),
|
|
170
|
+
employees: z.array(z.object({
|
|
171
|
+
id: z.uuid(),
|
|
172
|
+
name: z.string(),
|
|
173
|
+
email: z.string(),
|
|
174
|
+
active: z.boolean(),
|
|
175
|
+
})),
|
|
212
176
|
metadata: z.record(z.string(), z.string()),
|
|
213
177
|
}),
|
|
214
178
|
});
|
|
215
|
-
|
|
216
179
|
const result = generate(schema);
|
|
217
|
-
|
|
218
180
|
expect(result).toEqual({
|
|
219
181
|
company: {
|
|
220
182
|
name: expect.any(String),
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { makeFactory } from "./factory.js";
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@casekit/orm2-testing",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"author": "",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@faker-js/faker": "^9.8.0",
|
|
8
8
|
"es-toolkit": "^1.39.3",
|
|
9
|
-
"@casekit/orm2-config": "
|
|
10
|
-
"@casekit/
|
|
11
|
-
"@casekit/
|
|
12
|
-
"@casekit/
|
|
9
|
+
"@casekit/orm2-config": "1.0.1",
|
|
10
|
+
"@casekit/toolbox": "1.0.1",
|
|
11
|
+
"@casekit/orm2-schema": "1.0.1",
|
|
12
|
+
"@casekit/sql": "1.0.1"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"prettier-plugin-svelte": "^3.4.0",
|
|
20
20
|
"vite-tsconfig-paths": "^5.1.4",
|
|
21
21
|
"vitest": "^3.2.4",
|
|
22
|
-
"@casekit/
|
|
23
|
-
"@casekit/
|
|
22
|
+
"@casekit/tsconfig": "1.0.1",
|
|
23
|
+
"@casekit/prettier-config": "1.0.1"
|
|
24
24
|
},
|
|
25
25
|
"exports": {
|
|
26
|
-
".": "./
|
|
26
|
+
".": "./build/index.js"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
|
-
"/
|
|
29
|
+
"/build"
|
|
30
30
|
],
|
|
31
31
|
"imports": {
|
|
32
|
-
"#*": "./
|
|
32
|
+
"#*": "./build/*"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [],
|
|
35
35
|
"license": "ISC",
|
package/src/factory.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { mapValues, uniq } from "es-toolkit";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
import { NormalizedConfig } from "@casekit/orm2-config";
|
|
5
|
-
import { ModelDefinitions, ModelName, ModelType } from "@casekit/orm2-schema";
|
|
6
|
-
|
|
7
|
-
import { generate } from "./generate.js";
|
|
8
|
-
|
|
9
|
-
export type Factory<Models extends ModelDefinitions> = {
|
|
10
|
-
[M in ModelName<Models>]: (
|
|
11
|
-
overrides?: Partial<ModelType<Models[M]>>,
|
|
12
|
-
) => ModelType<Models[M]>;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const makeFactory = <Models extends ModelDefinitions>(
|
|
16
|
-
config: NormalizedConfig,
|
|
17
|
-
): Factory<Models> => {
|
|
18
|
-
return mapValues(config.models, (model) => {
|
|
19
|
-
// We never want to generate foreign key values
|
|
20
|
-
// as there's no way for us to know how to generate
|
|
21
|
-
// valid ones. This is up to the user to provide.
|
|
22
|
-
const fkOverrides = Object.fromEntries(
|
|
23
|
-
uniq(model.foreignKeys.flatMap((fk) => fk.fields)).map((fk) => [
|
|
24
|
-
fk,
|
|
25
|
-
null,
|
|
26
|
-
]),
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
const fields = Object.entries(model.fields)
|
|
30
|
-
.filter(([_, f]) => !f.provided)
|
|
31
|
-
.map(([name, f]) => [
|
|
32
|
-
name,
|
|
33
|
-
f.default
|
|
34
|
-
? f.zodSchema.optional()
|
|
35
|
-
: f.nullable
|
|
36
|
-
? f.zodSchema.nullable()
|
|
37
|
-
: f.zodSchema,
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
const schema = z.object(Object.fromEntries(fields));
|
|
41
|
-
return (overrides: Record<string, unknown>) => ({
|
|
42
|
-
...generate(schema),
|
|
43
|
-
...fkOverrides,
|
|
44
|
-
...overrides,
|
|
45
|
-
});
|
|
46
|
-
}) as Factory<Models>;
|
|
47
|
-
};
|
|
File without changes
|