prisma-mock 0.0.21 → 0.0.24
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 +183 -0
- package/lib/index.js +32 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1 +1,184 @@
|
|
|
1
1
|
|
|
2
|
+
# Prisma Mock
|
|
3
|
+
|
|
4
|
+
This is a mock of the Prisma API intended for unit testing. All the data is stored in memory.
|
|
5
|
+
|
|
6
|
+
The library `jest-mock-extended` is used, which means that if functionality you need is not implemented yet, you can mock it yourself.
|
|
7
|
+
|
|
8
|
+
# Usage
|
|
9
|
+
|
|
10
|
+
Simple example how to create a prisma mock instance:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import createPrismaMock from "prisma-mock"
|
|
14
|
+
|
|
15
|
+
let client
|
|
16
|
+
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
client = await createPrismaMock()
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
An example how to mock a global prisma instance inside and schema a "db" directory (like blitzjs):
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
import createPrismaMock from "prisma-mock"
|
|
27
|
+
import { mockDeep, mockReset } from "jest-mock-extended"
|
|
28
|
+
|
|
29
|
+
jest.mock("db", () => ({
|
|
30
|
+
__esModule: true,
|
|
31
|
+
...jest.requireActual('db'),
|
|
32
|
+
default: mockDeep()
|
|
33
|
+
}))
|
|
34
|
+
|
|
35
|
+
import db from "db"
|
|
36
|
+
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
mockReset(db)
|
|
39
|
+
return createPrismaMock({}, "db/schema.prisma", db)
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# API
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
createPrismaMock(
|
|
48
|
+
data: PrismaMockData<P> = {},
|
|
49
|
+
pathToSchema?: string,
|
|
50
|
+
client = mockDeep<P>()
|
|
51
|
+
): Promise<P>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## data
|
|
55
|
+
|
|
56
|
+
Object with an array per table of default data (using `create` is preferred). Example:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
createPrismaMock({
|
|
60
|
+
users: [
|
|
61
|
+
{
|
|
62
|
+
id: 1,
|
|
63
|
+
name: "John Doe",
|
|
64
|
+
accountId: 1
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
account: [
|
|
68
|
+
{
|
|
69
|
+
id: 1,
|
|
70
|
+
name: "Company",
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## pathToSchema
|
|
78
|
+
Path to the schema file. If not provided, the schema is `prisma/schema.prisma`.
|
|
79
|
+
|
|
80
|
+
## client
|
|
81
|
+
`jest-mock-extended` instance used. If not provided, a new instance is created.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# Supported features
|
|
85
|
+
Alot of the functionality is implemented, but parts are missing. Here is a list of the (missing) features:
|
|
86
|
+
|
|
87
|
+
## Model queries
|
|
88
|
+
- findUnique,
|
|
89
|
+
- findMany,
|
|
90
|
+
- findFirst,
|
|
91
|
+
- create,
|
|
92
|
+
- createMany
|
|
93
|
+
- delete,
|
|
94
|
+
- update,
|
|
95
|
+
- deleteMany,
|
|
96
|
+
- updateMany
|
|
97
|
+
- upsert
|
|
98
|
+
- count
|
|
99
|
+
- TODO: aggregate
|
|
100
|
+
- TODO: groupBy
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Model query options
|
|
104
|
+
- distinct
|
|
105
|
+
- include
|
|
106
|
+
- where
|
|
107
|
+
- TODO: select
|
|
108
|
+
- TODO: orderBy
|
|
109
|
+
- TODO: select: _count
|
|
110
|
+
|
|
111
|
+
## Nested queries
|
|
112
|
+
- create
|
|
113
|
+
- createMany
|
|
114
|
+
- update
|
|
115
|
+
- updateMany
|
|
116
|
+
- connect
|
|
117
|
+
- TODO: set
|
|
118
|
+
- TODO: disconnect
|
|
119
|
+
- TODO: connectOrCreate
|
|
120
|
+
- TODO: upsert
|
|
121
|
+
- TODO: delete
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## Filter conditions and operators
|
|
125
|
+
- equals
|
|
126
|
+
- gt
|
|
127
|
+
- gte
|
|
128
|
+
- lt
|
|
129
|
+
- lte
|
|
130
|
+
- not
|
|
131
|
+
- in
|
|
132
|
+
- notIn
|
|
133
|
+
- contains
|
|
134
|
+
- startWith
|
|
135
|
+
- endsWith
|
|
136
|
+
- AND
|
|
137
|
+
- OR
|
|
138
|
+
- NOT
|
|
139
|
+
- TODO: search
|
|
140
|
+
- TODO: mode
|
|
141
|
+
|
|
142
|
+
## Relation filters
|
|
143
|
+
- some
|
|
144
|
+
- every
|
|
145
|
+
- none
|
|
146
|
+
- TODO: is
|
|
147
|
+
|
|
148
|
+
## Scalar list methods
|
|
149
|
+
TODO (set, push)
|
|
150
|
+
|
|
151
|
+
## Scalar list filters
|
|
152
|
+
TODO (has, hasEvery, hasSome, isEmpty, equals)
|
|
153
|
+
|
|
154
|
+
## Atomic number operations
|
|
155
|
+
- increment
|
|
156
|
+
- decrement
|
|
157
|
+
- multiply
|
|
158
|
+
- divide
|
|
159
|
+
- set
|
|
160
|
+
|
|
161
|
+
## JSON filters
|
|
162
|
+
TODO (path, string_contains, string_starts_with, string_ends_with, array_contains, array_starts_with, array_ends_with)
|
|
163
|
+
|
|
164
|
+
## Attributes
|
|
165
|
+
- @@id
|
|
166
|
+
- @default
|
|
167
|
+
- @unique (TODO: no error if duplicate)
|
|
168
|
+
- @@unique (TODO: no error if duplicate)
|
|
169
|
+
- @relation
|
|
170
|
+
- TODO: @updatedAt
|
|
171
|
+
|
|
172
|
+
## Attribute functions
|
|
173
|
+
- autoincrement()
|
|
174
|
+
- TODO: auto()
|
|
175
|
+
- TODO: cuid()
|
|
176
|
+
- TODO: uuid()
|
|
177
|
+
- TODO: now()
|
|
178
|
+
- TODO: dbgenerated()
|
|
179
|
+
|
|
180
|
+
## Referential actions
|
|
181
|
+
- onDelete (SetNull, Cascade)
|
|
182
|
+
- TODO: onDelete: Restrict, NoAction, SetDefault
|
|
183
|
+
- TODO: onUpdate
|
|
184
|
+
|
package/lib/index.js
CHANGED
|
@@ -17,11 +17,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
const sdk_1 = require("@prisma/sdk");
|
|
18
18
|
const jest_mock_extended_1 = require("jest-mock-extended");
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
20
|
-
// TODO:
|
|
21
|
-
// - groupBy
|
|
22
20
|
let cachedSchema;
|
|
23
|
-
// type Key = Uncapitalize<ModelName>
|
|
24
21
|
const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_extended_1.mockDeep)()) => {
|
|
22
|
+
let autoincrement = {};
|
|
25
23
|
const getCamelCase = (name) => {
|
|
26
24
|
return name.substr(0, 1).toLowerCase() + name.substr(1);
|
|
27
25
|
};
|
|
@@ -40,12 +38,11 @@ const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_
|
|
|
40
38
|
const id = ids.join('_');
|
|
41
39
|
data = Object.assign(Object.assign({}, data), { [c]: data[c].map(item => {
|
|
42
40
|
const _a = item, _b = id, idVal = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
|
|
43
|
-
return Object.assign(Object.assign(
|
|
41
|
+
return Object.assign(Object.assign({ [id]: ids.reduce((prev, field) => {
|
|
44
42
|
return Object.assign(Object.assign({}, prev), { [field]: item[field] });
|
|
45
|
-
}, {}) }
|
|
43
|
+
}, {}) }, item), idVal);
|
|
46
44
|
}) });
|
|
47
45
|
};
|
|
48
|
-
// console.log("model.name", model.name)
|
|
49
46
|
if ((idFields === null || idFields === void 0 ? void 0 : idFields.length) > 1) {
|
|
50
47
|
checkId(idFields);
|
|
51
48
|
}
|
|
@@ -85,8 +82,10 @@ const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_
|
|
|
85
82
|
});
|
|
86
83
|
}
|
|
87
84
|
// @ts-ignore
|
|
88
|
-
client["$transaction"].mockImplementation((actions) => {
|
|
89
|
-
|
|
85
|
+
client["$transaction"].mockImplementation(async (actions) => {
|
|
86
|
+
for (const action of actions) {
|
|
87
|
+
await action;
|
|
88
|
+
}
|
|
90
89
|
});
|
|
91
90
|
const Delegate = (prop, model) => {
|
|
92
91
|
const nestedUpdate = (args, isCreating, item) => {
|
|
@@ -181,18 +180,32 @@ const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_
|
|
|
181
180
|
d = Object.assign(Object.assign({}, d), { [field.name]: c.set });
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
|
-
if (isCreating
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
if ((isCreating || d[field.name] === null) &&
|
|
184
|
+
(d[field.name] === null || d[field.name] === undefined)) {
|
|
185
|
+
if (field.hasDefaultValue) {
|
|
186
|
+
if (typeof field.default === 'object') {
|
|
187
|
+
if (field.default.name === 'autoincrement') {
|
|
188
|
+
const key = `${prop}_${field.name}`;
|
|
189
|
+
let m = autoincrement === null || autoincrement === void 0 ? void 0 : autoincrement[key];
|
|
190
|
+
if (m === undefined) {
|
|
191
|
+
m = 0;
|
|
192
|
+
data[prop].forEach(item => {
|
|
193
|
+
m = Math.max(m, item[field.name]);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
m += 1;
|
|
197
|
+
d = Object.assign(Object.assign({}, d), { [field.name]: m });
|
|
198
|
+
autoincrement = Object.assign(Object.assign({}, autoincrement), { [key]: m });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
d = Object.assign(Object.assign({}, d), { [field.name]: field.default });
|
|
192
203
|
}
|
|
193
204
|
}
|
|
194
205
|
else {
|
|
195
|
-
|
|
206
|
+
if (field.kind !== "object") {
|
|
207
|
+
d = Object.assign(Object.assign({}, d), { [field.name]: null });
|
|
208
|
+
}
|
|
196
209
|
}
|
|
197
210
|
}
|
|
198
211
|
// return field.name === key
|
|
@@ -212,7 +225,7 @@ const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_
|
|
|
212
225
|
if (child === "NOT") {
|
|
213
226
|
return !matchOr(item, filter);
|
|
214
227
|
}
|
|
215
|
-
if (
|
|
228
|
+
if (filter == null || filter === undefined) {
|
|
216
229
|
if (filter === null) {
|
|
217
230
|
return val === null || val === undefined;
|
|
218
231
|
}
|
|
@@ -395,11 +408,10 @@ const createPrismaMock = async (data = {}, pathToSchema, client = (0, jest_mock_
|
|
|
395
408
|
const d = nestedUpdate(args, true, null);
|
|
396
409
|
data = Object.assign(Object.assign({}, data), { [prop]: [...data[prop], d] });
|
|
397
410
|
data = checkIds(model, data);
|
|
398
|
-
// TODO:
|
|
411
|
+
// TODO: multi field ids
|
|
399
412
|
return findOne(Object.assign({ where: { id: d.id } }, args));
|
|
400
413
|
};
|
|
401
414
|
const deleteMany = args => {
|
|
402
|
-
const relations = [];
|
|
403
415
|
const model = cachedSchema.datamodel.models.find(model => {
|
|
404
416
|
return getCamelCase(model.name) === prop;
|
|
405
417
|
});
|