pqb 0.2.2 → 0.2.3
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/index.d.ts +58 -47
- package/dist/index.esm.js +197 -150
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +197 -150
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/columnSchema/columnsSchema.ts +15 -4
- package/src/columnSchema/number.ts +3 -0
- package/src/queryMethods/aggregate.test.ts +2 -2
- package/src/queryMethods/insert.test.ts +217 -205
- package/src/queryMethods/insert.ts +354 -274
- package/src/queryMethods/update.test.ts +3 -3
- package/src/queryMethods/upsert.test.ts +1 -1
- package/src/queryMethods/window.test.ts +2 -2
- package/src/utils.test.ts +37 -0
- package/src/utils.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ColumnInput, ColumnOutput, ColumnType } from './columnType';
|
|
2
2
|
import { Operators } from '../columnsOperators';
|
|
3
|
-
import { UnionToIntersection } from '../utils';
|
|
3
|
+
import { SetOptional, SomeIsTrue, UnionToIntersection } from '../utils';
|
|
4
4
|
|
|
5
5
|
export type ColumnsShape = Record<string, ColumnType>;
|
|
6
6
|
|
|
@@ -8,9 +8,20 @@ export type ColumnShapeOutput<Shape extends ColumnsShape> = {
|
|
|
8
8
|
[K in keyof Shape]: ColumnOutput<Shape[K]>;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
[K in keyof Shape]:
|
|
13
|
-
|
|
11
|
+
type OptionalColumnsForInput<Shape extends ColumnsShape> = {
|
|
12
|
+
[K in keyof Shape]: SomeIsTrue<
|
|
13
|
+
[Shape[K]['isNullable'], Shape[K]['hasDefault']]
|
|
14
|
+
> extends true
|
|
15
|
+
? K
|
|
16
|
+
: never;
|
|
17
|
+
}[keyof Shape];
|
|
18
|
+
|
|
19
|
+
export type ColumnShapeInput<Shape extends ColumnsShape> = SetOptional<
|
|
20
|
+
{
|
|
21
|
+
[K in keyof Shape]: ColumnInput<Shape[K]>;
|
|
22
|
+
},
|
|
23
|
+
OptionalColumnsForInput<Shape>
|
|
24
|
+
>;
|
|
14
25
|
|
|
15
26
|
export class ColumnsObject<Shape extends ColumnsShape> extends ColumnType<
|
|
16
27
|
{ [K in keyof Shape]: Shape[K]['type'] },
|
|
@@ -119,15 +119,18 @@ export class DoublePrecisionColumn extends NumberAsStringBaseColumn {
|
|
|
119
119
|
export class SmallSerialColumn extends IntegerBaseColumn {
|
|
120
120
|
dataType = 'smallserial' as const;
|
|
121
121
|
parseItem = parseInt;
|
|
122
|
+
hasDefault = true as const;
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
// autoincrementing four-byte integer
|
|
125
126
|
export class SerialColumn extends IntegerBaseColumn {
|
|
126
127
|
dataType = 'serial' as const;
|
|
127
128
|
parseItem = parseInt;
|
|
129
|
+
hasDefault = true as const;
|
|
128
130
|
}
|
|
129
131
|
|
|
130
132
|
// autoincrementing eight-byte integer
|
|
131
133
|
export class BigSerialColumn extends NumberAsStringBaseColumn {
|
|
132
134
|
dataType = 'bigserial' as const;
|
|
135
|
+
hasDefault = true as const;
|
|
133
136
|
}
|
|
@@ -504,7 +504,7 @@ describe('aggregate', () => {
|
|
|
504
504
|
});
|
|
505
505
|
|
|
506
506
|
it('should return json object when have records', async () => {
|
|
507
|
-
await User.
|
|
507
|
+
await User.insertMany([userData, userData]);
|
|
508
508
|
|
|
509
509
|
const value = await User.stringAgg('name', ', ');
|
|
510
510
|
|
|
@@ -526,7 +526,7 @@ describe('aggregate', () => {
|
|
|
526
526
|
});
|
|
527
527
|
|
|
528
528
|
it('should return json object when have records', async () => {
|
|
529
|
-
await User.
|
|
529
|
+
await User.insertMany([userData, userData]);
|
|
530
530
|
|
|
531
531
|
const value = await User.selectStringAgg('name', ', ').take();
|
|
532
532
|
|
|
@@ -9,260 +9,267 @@ import {
|
|
|
9
9
|
import { raw } from '../common';
|
|
10
10
|
import { OnConflictQueryBuilder } from './insert';
|
|
11
11
|
|
|
12
|
-
describe('insert', () => {
|
|
12
|
+
describe('insert functions', () => {
|
|
13
13
|
useTestDatabase();
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
describe('insertRaw', () => {
|
|
16
|
+
it('should insert with raw sql and list of columns', () => {
|
|
17
|
+
const q = User.all();
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
const query = q.insertRaw({
|
|
20
|
+
columns: ['name', 'password'],
|
|
21
|
+
values: raw('raw sql'),
|
|
22
|
+
});
|
|
23
|
+
expectSql(
|
|
24
|
+
query.toSql(),
|
|
25
|
+
`
|
|
25
26
|
INSERT INTO "user"("name", "password")
|
|
26
27
|
VALUES raw sql
|
|
27
28
|
`,
|
|
28
|
-
|
|
29
|
+
);
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const eq: AssertEqual<Awaited<typeof query>, number> = true;
|
|
32
|
+
expect(eq).toBe(true);
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
expectQueryNotMutated(q);
|
|
35
|
+
});
|
|
34
36
|
});
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
describe('insert', () => {
|
|
39
|
+
it('should insert one record, returning rows count', async () => {
|
|
40
|
+
const q = User.all();
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
const query = q.insert(userData);
|
|
43
|
+
expectSql(
|
|
44
|
+
query.toSql(),
|
|
45
|
+
`
|
|
43
46
|
INSERT INTO "user"("name", "password")
|
|
44
47
|
VALUES ($1, $2)
|
|
45
48
|
`,
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
['name', 'password'],
|
|
50
|
+
);
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
const result = await query;
|
|
53
|
+
expect(result).toBe(1);
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
56
|
+
expect(eq).toBe(true);
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
const inserted = await User.take();
|
|
59
|
+
expect(inserted).toMatchObject(userData);
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
expectQueryNotMutated(q);
|
|
62
|
+
});
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
it('should insert one record, returning value', async () => {
|
|
65
|
+
const q = User.all();
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
const query = q.get('id').insert(userData);
|
|
68
|
+
expectSql(
|
|
69
|
+
query.toSql(),
|
|
70
|
+
`
|
|
68
71
|
INSERT INTO "user"("name", "password")
|
|
69
72
|
VALUES ($1, $2)
|
|
70
73
|
RETURNING "user"."id"
|
|
71
74
|
`,
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
['name', 'password'],
|
|
76
|
+
);
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
const result = await query;
|
|
79
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
80
|
+
expect(eq).toBe(true);
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
expect(typeof result).toBe('number');
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
expectQueryNotMutated(q);
|
|
85
|
+
});
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
it('should insert one record, returning columns', async () => {
|
|
88
|
+
const q = User.all();
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
const query = q.select('id', 'name').insert(userData);
|
|
91
|
+
expectSql(
|
|
92
|
+
query.toSql(),
|
|
93
|
+
`
|
|
91
94
|
INSERT INTO "user"("name", "password")
|
|
92
95
|
VALUES ($1, $2)
|
|
93
96
|
RETURNING "user"."id", "user"."name"
|
|
94
97
|
`,
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
['name', 'password'],
|
|
99
|
+
);
|
|
97
100
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
const result = await query;
|
|
102
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }> = true;
|
|
103
|
+
expect(eq).toBe(true);
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
106
|
+
const { password, ...other } = userData;
|
|
107
|
+
expect(result).toMatchObject(other);
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
expectQueryNotMutated(q);
|
|
110
|
+
});
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
|
|
112
|
+
it('should insert one record, returning all columns', async () => {
|
|
113
|
+
const q = User.all();
|
|
111
114
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
const query = q.selectAll().insert(userData);
|
|
116
|
+
expectSql(
|
|
117
|
+
query.toSql(),
|
|
118
|
+
`
|
|
116
119
|
INSERT INTO "user"("name", "password")
|
|
117
120
|
VALUES ($1, $2)
|
|
118
121
|
RETURNING *
|
|
119
122
|
`,
|
|
120
|
-
|
|
121
|
-
|
|
123
|
+
['name', 'password'],
|
|
124
|
+
);
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
const result = await query;
|
|
127
|
+
const eq: AssertEqual<typeof result, typeof User['type']> = true;
|
|
128
|
+
expect(eq).toBe(true);
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
131
|
+
const { password, ...other } = userData;
|
|
132
|
+
expect(result).toMatchObject(other);
|
|
130
133
|
|
|
131
|
-
|
|
134
|
+
expectQueryNotMutated(q);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should insert record with provided defaults', () => {
|
|
138
|
+
const query = User.defaults({
|
|
139
|
+
name: 'name',
|
|
140
|
+
password: 'password',
|
|
141
|
+
}).insert({
|
|
142
|
+
password: 'override',
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expectSql(
|
|
146
|
+
query.toSql(),
|
|
147
|
+
`
|
|
148
|
+
INSERT INTO "user"("name", "password")
|
|
149
|
+
VALUES ($1, $2)
|
|
150
|
+
`,
|
|
151
|
+
['name', 'override'],
|
|
152
|
+
);
|
|
153
|
+
});
|
|
132
154
|
});
|
|
133
155
|
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
describe('insertMany', () => {
|
|
157
|
+
it('should insert many records, returning void', async () => {
|
|
158
|
+
const q = User.all();
|
|
136
159
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
160
|
+
const arr = [
|
|
161
|
+
{
|
|
162
|
+
...userData,
|
|
163
|
+
picture: null,
|
|
164
|
+
},
|
|
165
|
+
userData,
|
|
166
|
+
];
|
|
144
167
|
|
|
145
|
-
|
|
168
|
+
const query = q.insertMany(arr);
|
|
146
169
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
170
|
+
expectSql(
|
|
171
|
+
query.toSql(),
|
|
172
|
+
`
|
|
150
173
|
INSERT INTO "user"("name", "password", "picture")
|
|
151
174
|
VALUES
|
|
152
175
|
($1, $2, $3),
|
|
153
176
|
($4, $5, DEFAULT)
|
|
154
177
|
`,
|
|
155
|
-
|
|
156
|
-
|
|
178
|
+
['name', 'password', null, 'name', 'password'],
|
|
179
|
+
);
|
|
157
180
|
|
|
158
|
-
|
|
159
|
-
|
|
181
|
+
const result = await query;
|
|
182
|
+
expect(result).toBe(2);
|
|
160
183
|
|
|
161
|
-
|
|
162
|
-
|
|
184
|
+
const eq: AssertEqual<typeof result, number> = true;
|
|
185
|
+
expect(eq).toBe(true);
|
|
163
186
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
187
|
+
const inserted = await User.all();
|
|
188
|
+
inserted.forEach((item, i) => {
|
|
189
|
+
expect(item).toMatchObject(arr[i]);
|
|
190
|
+
});
|
|
168
191
|
|
|
169
|
-
|
|
170
|
-
|
|
192
|
+
expectQueryNotMutated(q);
|
|
193
|
+
});
|
|
171
194
|
|
|
172
|
-
|
|
173
|
-
|
|
195
|
+
it('should insert many records, returning columns', async () => {
|
|
196
|
+
const q = User.all();
|
|
174
197
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
198
|
+
const arr = [
|
|
199
|
+
{
|
|
200
|
+
...userData,
|
|
201
|
+
picture: null,
|
|
202
|
+
},
|
|
203
|
+
userData,
|
|
204
|
+
];
|
|
182
205
|
|
|
183
|
-
|
|
206
|
+
const query = q.select('id', 'name').insertMany(arr);
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
208
|
+
expectSql(
|
|
209
|
+
query.toSql(),
|
|
210
|
+
`
|
|
188
211
|
INSERT INTO "user"("name", "password", "picture")
|
|
189
212
|
VALUES
|
|
190
213
|
($1, $2, $3),
|
|
191
214
|
($4, $5, DEFAULT)
|
|
192
215
|
RETURNING "user"."id", "user"."name"
|
|
193
216
|
`,
|
|
194
|
-
|
|
195
|
-
|
|
217
|
+
['name', 'password', null, 'name', 'password'],
|
|
218
|
+
);
|
|
196
219
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
220
|
+
const result = await query;
|
|
221
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
|
|
222
|
+
true;
|
|
223
|
+
expect(eq).toBe(true);
|
|
200
224
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
225
|
+
const inserted = await User.all();
|
|
226
|
+
inserted.forEach((item, i) => {
|
|
227
|
+
expect(item).toMatchObject(arr[i]);
|
|
228
|
+
});
|
|
205
229
|
|
|
206
|
-
|
|
207
|
-
|
|
230
|
+
expectQueryNotMutated(q);
|
|
231
|
+
});
|
|
208
232
|
|
|
209
|
-
|
|
210
|
-
|
|
233
|
+
it('should insert many records, returning all columns', async () => {
|
|
234
|
+
const q = User.all();
|
|
211
235
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
const arr = [
|
|
237
|
+
{
|
|
238
|
+
...userData,
|
|
239
|
+
picture: null,
|
|
240
|
+
},
|
|
241
|
+
userData,
|
|
242
|
+
];
|
|
219
243
|
|
|
220
|
-
|
|
244
|
+
const query = q.selectAll().insertMany(arr);
|
|
221
245
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
246
|
+
expectSql(
|
|
247
|
+
query.toSql(),
|
|
248
|
+
`
|
|
225
249
|
INSERT INTO "user"("name", "password", "picture")
|
|
226
250
|
VALUES
|
|
227
251
|
($1, $2, $3),
|
|
228
252
|
($4, $5, DEFAULT)
|
|
229
253
|
RETURNING *
|
|
230
254
|
`,
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const result = await query;
|
|
235
|
-
result.forEach((item, i) => {
|
|
236
|
-
expect(item).toMatchObject(arr[i]);
|
|
237
|
-
});
|
|
255
|
+
['name', 'password', null, 'name', 'password'],
|
|
256
|
+
);
|
|
238
257
|
|
|
239
|
-
|
|
240
|
-
|
|
258
|
+
const result = await query;
|
|
259
|
+
result.forEach((item, i) => {
|
|
260
|
+
expect(item).toMatchObject(arr[i]);
|
|
261
|
+
});
|
|
241
262
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
expect(item).toMatchObject(arr[i]);
|
|
245
|
-
});
|
|
263
|
+
const eq: AssertEqual<typeof result, typeof User['type'][]> = true;
|
|
264
|
+
expect(eq).toBe(true);
|
|
246
265
|
|
|
247
|
-
|
|
248
|
-
|
|
266
|
+
const inserted = await User.all();
|
|
267
|
+
inserted.forEach((item, i) => {
|
|
268
|
+
expect(item).toMatchObject(arr[i]);
|
|
269
|
+
});
|
|
249
270
|
|
|
250
|
-
|
|
251
|
-
const query = User.defaults({
|
|
252
|
-
name: 'name',
|
|
253
|
-
password: 'password',
|
|
254
|
-
}).insert({
|
|
255
|
-
password: 'override',
|
|
271
|
+
expectQueryNotMutated(q);
|
|
256
272
|
});
|
|
257
|
-
|
|
258
|
-
expectSql(
|
|
259
|
-
query.toSql(),
|
|
260
|
-
`
|
|
261
|
-
INSERT INTO "user"("name", "password")
|
|
262
|
-
VALUES ($1, $2)
|
|
263
|
-
`,
|
|
264
|
-
['name', 'override'],
|
|
265
|
-
);
|
|
266
273
|
});
|
|
267
274
|
|
|
268
275
|
describe('onConflict', () => {
|
|
@@ -490,52 +497,57 @@ describe('insert', () => {
|
|
|
490
497
|
});
|
|
491
498
|
});
|
|
492
499
|
|
|
493
|
-
describe('create', () => {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const eq: AssertEqual<typeof result, typeof User.type> = true;
|
|
499
|
-
expect(eq).toBe(true);
|
|
500
|
-
});
|
|
500
|
+
describe('create functions', () => {
|
|
501
|
+
describe('create', () => {
|
|
502
|
+
it('should return full record', async () => {
|
|
503
|
+
const result = await User.create(userData);
|
|
504
|
+
expect(result).toMatchObject(userData);
|
|
501
505
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
expect(result).toEqual({
|
|
505
|
-
id: result.id,
|
|
506
|
-
name: userData.name,
|
|
506
|
+
const eq: AssertEqual<typeof result, typeof User.type> = true;
|
|
507
|
+
expect(eq).toBe(true);
|
|
507
508
|
});
|
|
508
509
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
expect(result[0]).toMatchObject(userData);
|
|
516
|
-
expect(result[1]).toMatchObject(userData);
|
|
510
|
+
it('should return columns from select', async () => {
|
|
511
|
+
const result = await User.select('id', 'name').create(userData);
|
|
512
|
+
expect(result).toEqual({
|
|
513
|
+
id: result.id,
|
|
514
|
+
name: userData.name,
|
|
515
|
+
});
|
|
517
516
|
|
|
518
|
-
|
|
519
|
-
|
|
517
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }> =
|
|
518
|
+
true;
|
|
519
|
+
expect(eq).toBe(true);
|
|
520
|
+
});
|
|
520
521
|
});
|
|
521
522
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
userData,
|
|
525
|
-
userData
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
});
|
|
531
|
-
expect(result[1]).toEqual({
|
|
532
|
-
id: result[1].id,
|
|
533
|
-
name: userData.name,
|
|
523
|
+
describe('createMany', () => {
|
|
524
|
+
it('should return full records', async () => {
|
|
525
|
+
const result = await User.createMany([userData, userData]);
|
|
526
|
+
expect(result[0]).toMatchObject(userData);
|
|
527
|
+
expect(result[1]).toMatchObject(userData);
|
|
528
|
+
|
|
529
|
+
const eq: AssertEqual<typeof result, typeof User.type[]> = true;
|
|
530
|
+
expect(eq).toBe(true);
|
|
534
531
|
});
|
|
535
532
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
533
|
+
it('should return columns from select', async () => {
|
|
534
|
+
const result = await User.select('id', 'name').createMany([
|
|
535
|
+
userData,
|
|
536
|
+
userData,
|
|
537
|
+
]);
|
|
538
|
+
expect(result[0]).toEqual({
|
|
539
|
+
id: result[0].id,
|
|
540
|
+
name: userData.name,
|
|
541
|
+
});
|
|
542
|
+
expect(result[1]).toEqual({
|
|
543
|
+
id: result[1].id,
|
|
544
|
+
name: userData.name,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
const eq: AssertEqual<typeof result, { id: number; name: string }[]> =
|
|
548
|
+
true;
|
|
549
|
+
expect(eq).toBe(true);
|
|
550
|
+
});
|
|
539
551
|
});
|
|
540
552
|
});
|
|
541
553
|
});
|