@@ -168,7 +168,7 @@ func TestCachingDecodersNotSharedAcrossRegistries(t *testing.T) {
168
168
}
169
169
170
170
func TestUnmarshalExtJSONWithUndefinedField (t * testing.T ) {
171
- // When unmarshalling, fields that are undefined in the destination struct are skipped.
171
+ // When unmarshalling extJSON , fields that are undefined in the destination struct are skipped.
172
172
// This process must not skip other, defined fields and must not raise errors.
173
173
type expectedResponse struct {
174
174
DefinedField string
@@ -278,3 +278,154 @@ func TestUnmarshalExtJSONWithUndefinedField(t *testing.T) {
278
278
})
279
279
}
280
280
}
281
+
282
+ func TestUnmarshalBSONWithUndefinedField (t * testing.T ) {
283
+ // When unmarshalling BSON, fields that are undefined in the destination struct are skipped.
284
+ // This process must not skip other, defined fields and must not raise errors.
285
+ type expectedResponse struct {
286
+ DefinedField string `bson:"DefinedField"`
287
+ }
288
+
289
+ createExpectedResponse := func (t * testing.T , doc D ) * expectedResponse {
290
+ t .Helper ()
291
+
292
+ marshalledBSON , err := Marshal (doc )
293
+ assert .Nil (t , err , "error marshalling BSON: %v" , err )
294
+
295
+ responseDoc := expectedResponse {}
296
+ err = Unmarshal (marshalledBSON , & responseDoc )
297
+ assert .Nil (t , err , "error unmarshalling BSON: %v" , err )
298
+ return & responseDoc
299
+ }
300
+
301
+ testCases := []struct {
302
+ name string
303
+ testBSON D
304
+ }{
305
+ {
306
+ "no array" ,
307
+ D {
308
+ {"UndefinedField" , D {
309
+ {"key" , 1 },
310
+ }},
311
+ {"DefinedField" , "value" },
312
+ },
313
+ },
314
+ {
315
+ "outer array" ,
316
+ D {
317
+ {"UndefinedField" , A {D {
318
+ {"key" , 1 },
319
+ }}},
320
+ {"DefinedField" , "value" },
321
+ },
322
+ },
323
+ {
324
+ "embedded array" ,
325
+ D {
326
+ {"UndefinedField" , D {
327
+ {"key" , A {1 }},
328
+ }},
329
+ {"DefinedField" , "value" },
330
+ },
331
+ },
332
+ {
333
+ "outer array and embedded array" ,
334
+ D {
335
+ {"UndefinedField" , A {D {
336
+ {"key" , A {1 }},
337
+ }}},
338
+ {"DefinedField" , "value" },
339
+ },
340
+ },
341
+ {
342
+ "embedded document" ,
343
+ D {
344
+ {"UndefinedField" , D {
345
+ {"key" , D {
346
+ {"one" , "two" },
347
+ }},
348
+ }},
349
+ {"DefinedField" , "value" },
350
+ },
351
+ },
352
+ {
353
+ "doubly embedded document" ,
354
+ D {
355
+ {"UndefinedField" , D {
356
+ {"key" , D {
357
+ {"one" , D {
358
+ {"two" , "three" },
359
+ }},
360
+ }},
361
+ }},
362
+ {"DefinedField" , "value" },
363
+ },
364
+ },
365
+ {
366
+ "embedded document and embedded array" ,
367
+ D {
368
+ {"UndefinedField" , D {
369
+ {"key" , D {
370
+ {"one" , D {
371
+ {"two" , A {3 }},
372
+ }},
373
+ }},
374
+ }},
375
+ {"DefinedField" , "value" },
376
+ },
377
+ },
378
+ {
379
+ "embedded document and embedded array in outer array" ,
380
+ D {
381
+ {"UndefinedField" , A {D {
382
+ {"key" , D {
383
+ {"one" , A {3 }},
384
+ }},
385
+ }}},
386
+ {"DefinedField" , "value" },
387
+ },
388
+ },
389
+ {
390
+ "code with scope" ,
391
+ D {
392
+ {"UndefinedField" , D {
393
+ {"logic" , D {
394
+ {"$code" , "foo" },
395
+ {"$scope" , D {
396
+ {"bar" , 1 },
397
+ }},
398
+ }},
399
+ }},
400
+ {"DefinedField" , "value" },
401
+ },
402
+ },
403
+ {
404
+ "embedded array of code with scope" ,
405
+ D {
406
+ {"UndefinedField" , D {
407
+ {"logic" , A {D {
408
+ {"$code" , "foo" },
409
+ {"$scope" , D {
410
+ {"bar" , 1 },
411
+ }},
412
+ }}},
413
+ }},
414
+ {"DefinedField" , "value" },
415
+ },
416
+ },
417
+ {
418
+ "empty embedded document" ,
419
+ D {
420
+ {"UndefinedField" , D {}},
421
+ {"DefinedField" , "value" },
422
+ },
423
+ },
424
+ }
425
+ for _ , tc := range testCases {
426
+ t .Run (tc .name , func (t * testing.T ) {
427
+ responseDoc := createExpectedResponse (t , tc .testBSON )
428
+ assert .Equal (t , "value" , responseDoc .DefinedField , "expected DefinedField to be 'value', got %q" , responseDoc .DefinedField )
429
+ })
430
+ }
431
+ }
0 commit comments