@@ -68,44 +68,119 @@ describe('mongodb types', () => {
68
68
69
69
describe ( 'PaprFilter' , ( ) => {
70
70
describe ( 'existing top-level keys' , ( ) => {
71
- test ( 'valid types' , ( ) => {
72
- expect ( true ) . toBeTruthy ( ) ;
71
+ describe ( 'valid types' , ( ) => {
72
+ test ( 'ObjectId' , ( ) => {
73
+ const filter = { _id : new ObjectId ( ) } as const ;
74
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
75
+ } ) ;
73
76
74
- expectType < PaprFilter < TestDocument > > ( { _id : new ObjectId ( ) } ) ;
77
+ test ( 'string' , ( ) => {
78
+ const filter = { foo : 'foo' } as const ;
79
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
80
+ } ) ;
75
81
76
- expectType < PaprFilter < TestDocument > > ( { foo : 'foo' } ) ;
77
- // string fields can be queried by regexp
78
- expectType < PaprFilter < TestDocument > > ( { foo : / f o o / } ) ;
82
+ test ( 'string queried by regexp' , ( ) => {
83
+ const filter = { foo : / f o o / } as const ;
84
+ // string fields can be queried by regexp
85
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
86
+ } ) ;
79
87
80
- expectType < PaprFilter < TestDocument > > ( { bar : 123 } ) ;
88
+ test ( 'number' , ( ) => {
89
+ const filter = { bar : 123 } as const ;
90
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
91
+ } ) ;
81
92
82
- expectType < PaprFilter < TestDocument > > ( { ham : new Date ( ) } ) ;
93
+ test ( 'Date' , ( ) => {
94
+ const filter = { ham : new Date ( ) } as const ;
95
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
96
+ } ) ;
83
97
84
- // array fields can be queried by exact match
85
- expectType < PaprFilter < TestDocument > > ( { tags : [ 'foo' ] } ) ;
86
- // array fields can be queried by element type
87
- expectType < PaprFilter < TestDocument > > ( { tags : 'foo' } ) ;
88
- expectType < PaprFilter < TestDocument > > ( { tags : / f o o / } ) ;
98
+ test ( ' array-of-strings queried by exact match' , ( ) => {
99
+ // array fields can be queried by exact match
100
+ const filter = { tags : [ 'foo' ] } as const ;
101
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
102
+ } ) ;
89
103
90
- expectType < PaprFilter < TestDocument > > ( {
91
- nestedObject : {
92
- deep : { deeper : 'foo' } ,
93
- direct : true ,
94
- } ,
104
+ test ( 'array-of-strings queried by string' , ( ) => {
105
+ // array fields can be queried by element type
106
+ const filter = { tags : 'foo' } as const ;
107
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
108
+ } ) ;
109
+
110
+ test ( 'array-of-strings queried by regexp' , ( ) => {
111
+ const filter = { tags : / f o o / } as const ;
112
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
95
113
} ) ;
96
114
97
- // all BSON types can be used as query values
98
- expectType < PaprFilter < TestDocument > > ( { binary : new Binary ( [ ] , 2 ) } ) ;
99
- expectType < PaprFilter < TestDocument > > ( { bsonSymbol : new BSONSymbol ( 'hi' ) } ) ;
100
- expectType < PaprFilter < TestDocument > > ( { code : new Code ( ( ) => true ) } ) ;
101
- expectType < PaprFilter < TestDocument > > ( { double : new Double ( 123.45 ) } ) ;
102
- expectType < PaprFilter < TestDocument > > ( { dbRef : new DBRef ( 'collection' , new ObjectId ( ) ) } ) ;
103
- expectType < PaprFilter < TestDocument > > ( { decimal : new Decimal128 ( '123.45' ) } ) ;
104
- expectType < PaprFilter < TestDocument > > ( { int32 : new Int32 ( '123' ) } ) ;
105
- expectType < PaprFilter < TestDocument > > ( { long : new Long ( '123' , 45 ) } ) ;
106
- expectType < PaprFilter < TestDocument > > ( { maxKey : new MaxKey ( ) } ) ;
107
- expectType < PaprFilter < TestDocument > > ( { minKey : new MinKey ( ) } ) ;
108
- expectType < PaprFilter < TestDocument > > ( { regexp : / f o o / } ) ;
115
+ test ( 'nested object' , ( ) => {
116
+ const filter = {
117
+ nestedObject : {
118
+ deep : { deeper : 'foo' } ,
119
+ direct : true ,
120
+ } ,
121
+ } as const ;
122
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
123
+ } ) ;
124
+
125
+ describe ( 'BSON types' , ( ) => {
126
+ // all BSON types can be used as query values
127
+ test ( 'binary' , ( ) => {
128
+ const filter = { binary : new Binary ( [ ] , 2 ) } as const ;
129
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
130
+ } ) ;
131
+
132
+ test ( 'BSONSymbol' , ( ) => {
133
+ const filter = { bsonSymbol : new BSONSymbol ( 'hi' ) } as const ;
134
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
135
+ } ) ;
136
+
137
+ test ( 'Code' , ( ) => {
138
+ const filter = { code : new Code ( ( ) => true ) } as const ;
139
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
140
+ } ) ;
141
+
142
+ test ( 'Double' , ( ) => {
143
+ const filter = { double : new Double ( 123.45 ) } as const ;
144
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
145
+ } ) ;
146
+
147
+ test ( 'DBRef' , ( ) => {
148
+ const filter = {
149
+ dbRef : new DBRef ( 'collection' , new ObjectId ( ) ) ,
150
+ } as const ;
151
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
152
+ } ) ;
153
+
154
+ test ( 'Decimal128' , ( ) => {
155
+ const filter = { decimal : new Decimal128 ( '123.45' ) } as const ;
156
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
157
+ } ) ;
158
+
159
+ test ( 'Int32' , ( ) => {
160
+ const filter = { int32 : new Int32 ( '123' ) } as const ;
161
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
162
+ } ) ;
163
+
164
+ test ( 'Long' , ( ) => {
165
+ const filter = { long : new Long ( '123' , 45 ) } as const ;
166
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
167
+ } ) ;
168
+
169
+ test ( 'MaxKey' , ( ) => {
170
+ const filter = { maxKey : new MaxKey ( ) } as const ;
171
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
172
+ } ) ;
173
+
174
+ test ( 'MinKey' , ( ) => {
175
+ const filter = { minKey : new MinKey ( ) } as const ;
176
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
177
+ } ) ;
178
+
179
+ test ( 'regexp' , ( ) => {
180
+ const filter = { regexp : / f o o / } as const ;
181
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
182
+ } ) ;
183
+ } ) ;
109
184
} ) ;
110
185
111
186
test ( 'invalid types' , ( ) => {
@@ -148,68 +223,143 @@ describe('mongodb types', () => {
148
223
} ) ;
149
224
150
225
describe ( 'existing nested keys using dot notation' , ( ) => {
151
- test ( 'valid types' , ( ) => {
152
- // https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/#query-on-nested-field
153
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.direct' : true } ) ;
154
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.other' : 123 } ) ;
155
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.deeper' : 'foo' } ) ;
156
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.other' : 123 } ) ;
157
- expectType < PaprFilter < TestDocument > > ( {
158
- 'nestedObject.level2.level3.level4.level5.level6ID' : 'foo' ,
226
+ describe ( 'valid types' , ( ) => {
227
+ describe ( 'nested object' , ( ) => {
228
+ test ( 'boolean addressed by name' , ( ) => {
229
+ const filter = { 'nestedObject.direct' : true } as const ;
230
+ // https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/#query-on-nested-field
231
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
232
+ } ) ;
233
+
234
+ test ( 'number addressed by name' , ( ) => {
235
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.other' : 123 } ) ;
236
+ } ) ;
237
+
238
+ test ( 'string addressed by nested name' , ( ) => {
239
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.deeper' : 'foo' } ) ;
240
+ } ) ;
241
+
242
+ test ( 'number addressed by nested name' , ( ) => {
243
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.other' : 123 } ) ;
244
+ } ) ;
245
+
246
+ test ( 'string addressed by deeply-nested name' , ( ) => {
247
+ expectType < PaprFilter < TestDocument > > ( {
248
+ 'nestedObject.level2.level3.level4.level5.level6ID' : 'foo' ,
249
+ } ) ;
250
+ } ) ;
251
+ } ) ;
252
+
253
+ describe ( 'generic object' , ( ) => {
254
+ test ( 'number addressed by arbitrary nested name' , ( ) => {
255
+ expectType < PaprFilter < TestDocument > > ( { 'genericObject.foo.id' : 123 } ) ;
256
+ expectType < PaprFilter < TestDocument > > ( { 'genericObject.bar.id' : 123 } ) ;
257
+ } ) ;
258
+
259
+ test ( 'number addressed by nested object with valid property' , ( ) => {
260
+ expectType < PaprFilter < TestDocument > > ( { 'genericObject.foo' : { id : 123 } } ) ;
261
+ } ) ;
262
+ } ) ;
263
+
264
+ test ( 'string addressed by index + property in array-of-objects' , ( ) => {
265
+ // https://www.mongodb.com/docs/manual/tutorial/query-array-of-documents/#use-the-array-index-to-query-for-a-field-in-the-embedded-document
266
+ expectType < PaprFilter < TestDocument > > ( { 'list.0.direct' : 'foo' } ) ;
159
267
} ) ;
160
268
161
- expectType < PaprFilter < TestDocument > > ( { 'genericObject.foo.id' : 123 } ) ;
162
- expectType < PaprFilter < TestDocument > > ( { 'genericObject.bar.id' : 123 } ) ;
269
+ test ( 'number addressed by index + property in array-of-objects' , ( ) => {
270
+ expectType < PaprFilter < TestDocument > > ( { 'list.1.other' : 123 } ) ;
271
+ } ) ;
163
272
164
- expectType < PaprFilter < TestDocument > > ( { 'genericObject.foo' : { id : 123 } } ) ;
273
+ test ( 'number addressed by large index + property in array-of-objects' , ( ) => {
274
+ // it works with some extreme indexes
275
+ expectType < PaprFilter < TestDocument > > ( { 'list.4294967295.other' : 123 } ) ;
276
+ } ) ;
165
277
166
- // https://www.mongodb.com/docs/manual/tutorial/query-array-of-documents/#use-the-array-index-to-query-for-a-field-in-the-embedded-document
167
- expectType < PaprFilter < TestDocument > > ( { 'list.0.direct' : 'foo' } ) ;
168
- expectType < PaprFilter < TestDocument > > ( { 'list.1.other' : 123 } ) ;
169
- // it works with some extreme indexes
170
- expectType < PaprFilter < TestDocument > > ( { 'list.4294967295.other' : 123 } ) ;
171
- expectType < PaprFilter < TestDocument > > ( { 'list.9999999999999999999.other' : 123 } ) ;
278
+ test ( 'number addressed by super-large index + property in array-of-objects' , ( ) => {
279
+ expectType < PaprFilter < TestDocument > > ( { 'list.9999999999999999999.other' : 123 } ) ;
280
+ } ) ;
172
281
173
- expectType < PaprFilter < TestDocument > > ( { 'tags.0' : 'foo' } ) ;
282
+ test ( 'string addressed by property in array-of-objects' , ( ) => {
283
+ // https://www.mongodb.com/docs/manual/tutorial/query-array-of-documents/#specify-a-query-condition-on-a-field-embedded-in-an-array-of-documents
284
+ expectType < PaprFilter < TestDocument > > ( { 'list.direct' : 'foo' } ) ;
285
+ } ) ;
174
286
175
- // https://www.mongodb.com/docs/manual/tutorial/query-array-of-documents/#specify-a-query-condition-on-a-field-embedded-in-an-array-of-documents
176
- expectType < PaprFilter < TestDocument > > ( { 'list.direct' : 'foo' } ) ;
177
- expectType < PaprFilter < TestDocument > > ( { 'list.other' : 123 } ) ;
178
- } ) ;
287
+ test ( 'number addressed by property in array-of-objects' , ( ) => {
288
+ expectType < PaprFilter < TestDocument > > ( { 'list.other' : 123 } ) ;
289
+ } ) ;
179
290
180
- test ( 'invalid types' , ( ) => {
181
- // @ts -expect-error Type mismatch
182
- expectType < PaprFilter < TestDocument > > ( { 'tags.0' : 123 } ) ;
291
+ test ( 'string addressed by index in array-of-strings' , ( ) => {
292
+ expectType < PaprFilter < TestDocument > > ( { 'tags.0' : 'foo' } ) ;
293
+ } ) ;
294
+ } ) ;
183
295
184
- // @ts -expect-error Type mismatch
185
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.direct' : 'foo' } ) ;
186
- // @ts -expect-error Type mismatch
187
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.other' : 'foo' } ) ;
188
- // @ts -expect-error Type mismatch
189
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.deeper' : 123 } ) ;
190
- // @ts -expect-error Type mismatch
191
- expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.other' : 'foo' } ) ;
192
- expectType < PaprFilter < TestDocument > > ( {
296
+ describe ( 'invalid types' , ( ) => {
297
+ test ( 'number substituted for string at array numeric index' , ( ) => {
193
298
// @ts -expect-error Type mismatch
194
- 'nestedObject.level2.level3.level4.level5.level6 ' : 123 ,
299
+ expectType < PaprFilter < TestDocument > > ( { 'tags.0 ' : 123 } ) ;
195
300
} ) ;
196
- expectType < PaprFilter < TestDocument > > ( {
197
- // @ts -expect-error Nesting level too deep
198
- 'nestedObject.level2.level3.level4.level5.level6.level7ID' : 'foo' ,
301
+
302
+ describe ( 'nested objects' , ( ) => {
303
+ test ( 'string substituted for object at nested object property' , ( ) => {
304
+ // @ts -expect-error Type mismatch
305
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.direct' : 'foo' } ) ;
306
+ } ) ;
307
+
308
+ test ( 'string substituted for number at shallow nested object property' , ( ) => {
309
+ // @ts -expect-error Type mismatch
310
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.other' : 'foo' } ) ;
311
+ } ) ;
312
+
313
+ test ( 'number substituted for string at nested object property' , ( ) => {
314
+ // @ts -expect-error Type mismatch
315
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.deeper' : 123 } ) ;
316
+ } ) ;
317
+
318
+ test ( 'string substituted for number at deep nested object property' , ( ) => {
319
+ // @ts -expect-error Type mismatch
320
+ expectType < PaprFilter < TestDocument > > ( { 'nestedObject.deep.other' : 'foo' } ) ;
321
+ } ) ;
322
+
323
+ test ( 'number substituted for object at deeply nested property (level6)' , ( ) => {
324
+ const filter = {
325
+ 'nestedObject.level2.level3.level4.level5.level6' : 123 ,
326
+ } as const ;
327
+ // @ts -expect-error Type mismatch
328
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
329
+ } ) ;
330
+
331
+ test ( 'number substituted for string at deeply nested property (level7) nesting error, not type error' , ( ) => {
332
+ const filter = {
333
+ 'nestedObject.level2.level3.level4.level5.level6.level7ID' : 123 ,
334
+ } as const ;
335
+ expectType < PaprFilter < TestDocument > > ( filter ) ;
336
+ } ) ;
199
337
} ) ;
200
338
201
- // @ts -expect-error Type mismatch
202
- expectType < PaprFilter < TestDocument > > ( { 'genericObject.foo.id' : 'foo' } ) ;
203
- // @ts -expect-error Type mismatch
204
- expectType < PaprFilter < TestDocument > > ( { 'genericObject.bar.id' : true } ) ;
339
+ describe ( 'generic objects' , ( ) => {
340
+ test ( 'string substituted for number on generic object field' , ( ) => {
341
+ // @ts -expect-error Type mismatch
342
+ expectType < PaprFilter < TestDocument > > ( { 'genericObject.bar.id' : '123' } ) ;
343
+ } ) ;
205
344
206
- // Support for this type-check is not available yet
207
- // expectType<PaprFilter<TestDocument>>({ 'genericObject.foo': { id: 'foo' } });
345
+ test ( 'boolean substituted for number on generic object field' , ( ) => {
346
+ // @ts -expect-error Type mismatch
347
+ expectType < PaprFilter < TestDocument > > ( { 'genericObject.bar.id' : true } ) ;
348
+ } ) ;
349
+ } ) ;
208
350
209
- // @ts -expect-error Type mismatch
210
- expectType < PaprFilter < TestDocument > > ( { 'list.0.direct' : 123 } ) ;
211
- // @ts -expect-error Type mismatch
212
- expectType < PaprFilter < TestDocument > > ( { 'list.1.other' : 'foo' } ) ;
351
+ test ( 'number substituted for required string on array-of-objects' , ( ) => {
352
+ // Support for this type-check is not available yet
353
+ // expectType<PaprFilter<TestDocument>>({ 'genericObject.foo': { id: 'foo' } });
354
+
355
+ // @ts -expect-error Type mismatch
356
+ expectType < PaprFilter < TestDocument > > ( { 'list.0.direct' : 123 } ) ;
357
+ } ) ;
358
+
359
+ test ( 'string substituted for optional number on array-of-objects' , ( ) => {
360
+ // @ts -expect-error Type mismatch
361
+ expectType < PaprFilter < TestDocument > > ( { 'list.1.other' : 'foo' } ) ;
362
+ } ) ;
213
363
} ) ;
214
364
} ) ;
215
365
@@ -429,11 +579,22 @@ describe('mongodb types', () => {
429
579
430
580
describe ( 'PaprUpdateFilter' , ( ) => {
431
581
describe ( '$currentDate' , ( ) => {
432
- test ( 'valid types' , ( ) => {
433
- expectType < PaprUpdateFilter < TestDocument > > ( { $currentDate : { ham : true } } ) ;
434
- expectType < PaprUpdateFilter < TestDocument > > ( { $currentDate : { ham : { $type : 'date' } } } ) ;
435
- expectType < PaprUpdateFilter < TestDocument > > ( {
436
- $currentDate : { ham : { $type : 'timestamp' } } ,
582
+ describe ( 'valid types' , ( ) => {
583
+ test ( 'object' , ( ) => {
584
+ const filter = { $currentDate : { ham : true } } as const ;
585
+ expectType < PaprUpdateFilter < TestDocument > > ( filter ) ;
586
+ } ) ;
587
+
588
+ test ( 'object with $type date' , ( ) => {
589
+ const filter = { $currentDate : { ham : { $type : 'date' } } } as const ;
590
+ expectType < PaprUpdateFilter < TestDocument > > ( filter ) ;
591
+ } ) ;
592
+
593
+ test ( 'object with $type timestamp' , ( ) => {
594
+ const filter = {
595
+ $currentDate : { ham : { $type : 'timestamp' } } ,
596
+ } as const ;
597
+ expectType < PaprUpdateFilter < TestDocument > > ( filter ) ;
437
598
} ) ;
438
599
} ) ;
439
600
0 commit comments