@@ -11,6 +11,7 @@ import (
11
11
12
12
"go.mongodb.org/mongo-driver/bson/bsonrw"
13
13
"go.mongodb.org/mongo-driver/bson/bsontype"
14
+ "go.mongodb.org/mongo-driver/bson/primitive"
14
15
)
15
16
16
17
type unmarshalingTestCase struct {
@@ -114,6 +115,26 @@ func unmarshalingTestCases() []unmarshalingTestCase {
114
115
},
115
116
data : docToBytes (D {{"fooBar" , int32 (10 )}}),
116
117
},
118
+ {
119
+ name : "nil pointer and non-pointer type with literal null BSON" ,
120
+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
121
+ want : & unmarshalBehaviorTestCase {
122
+ BSONValueTracker : unmarshalBSONValueCallTracker {
123
+ called : true ,
124
+ },
125
+ BSONValuePtrTracker : nil ,
126
+ BSONTracker : unmarshalBSONCallTracker {
127
+ called : true ,
128
+ },
129
+ BSONPtrTracker : nil ,
130
+ },
131
+ data : docToBytes (D {
132
+ {Key : "bv_tracker" , Value : nil },
133
+ {Key : "bv_ptr_tracker" , Value : nil },
134
+ {Key : "b_tracker" , Value : nil },
135
+ {Key : "b_ptr_tracker" , Value : nil },
136
+ }),
137
+ },
117
138
// GODRIVER-2252
118
139
// Test that a struct of pointer types with UnmarshalBSON functions defined marshal and
119
140
// unmarshal to the same Go values when the pointer values are "nil".
@@ -174,6 +195,50 @@ func unmarshalingTestCases() []unmarshalingTestCase {
174
195
want : & valNonPtrStruct ,
175
196
data : docToBytes (valNonPtrStruct ),
176
197
},
198
+ {
199
+ name : "nil pointer and non-pointer type with BSON minkey" ,
200
+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
201
+ want : & unmarshalBehaviorTestCase {
202
+ BSONValueTracker : unmarshalBSONValueCallTracker {
203
+ called : true ,
204
+ },
205
+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
206
+ called : true ,
207
+ },
208
+ BSONTracker : unmarshalBSONCallTracker {
209
+ called : true ,
210
+ },
211
+ BSONPtrTracker : nil ,
212
+ },
213
+ data : docToBytes (D {
214
+ {Key : "bv_tracker" , Value : primitive.MinKey {}},
215
+ {Key : "bv_ptr_tracker" , Value : primitive.MinKey {}},
216
+ {Key : "b_tracker" , Value : primitive.MinKey {}},
217
+ {Key : "b_ptr_tracker" , Value : primitive.MinKey {}},
218
+ }),
219
+ },
220
+ {
221
+ name : "nil pointer and non-pointer type with BSON maxkey" ,
222
+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
223
+ want : & unmarshalBehaviorTestCase {
224
+ BSONValueTracker : unmarshalBSONValueCallTracker {
225
+ called : true ,
226
+ },
227
+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
228
+ called : true ,
229
+ },
230
+ BSONTracker : unmarshalBSONCallTracker {
231
+ called : true ,
232
+ },
233
+ BSONPtrTracker : nil ,
234
+ },
235
+ data : docToBytes (D {
236
+ {Key : "bv_tracker" , Value : primitive.MaxKey {}},
237
+ {Key : "bv_ptr_tracker" , Value : primitive.MaxKey {}},
238
+ {Key : "b_tracker" , Value : primitive.MaxKey {}},
239
+ {Key : "b_ptr_tracker" , Value : primitive.MaxKey {}},
240
+ }),
241
+ },
177
242
}
178
243
}
179
244
@@ -269,3 +334,39 @@ func (ms *myString) UnmarshalBSON(bytes []byte) error {
269
334
* ms = myString (s )
270
335
return nil
271
336
}
337
+
338
+ // unmarshalBSONValueCallTracker is a test struct that tracks whether the
339
+ // UnmarshalBSONValue method has been called.
340
+ type unmarshalBSONValueCallTracker struct {
341
+ called bool // called is set to true when UnmarshalBSONValue is invoked.
342
+ }
343
+
344
+ var _ ValueUnmarshaler = & unmarshalBSONValueCallTracker {}
345
+
346
+ // unmarshalBSONCallTracker is a test struct that tracks whether the
347
+ // UnmarshalBSON method has been called.
348
+ type unmarshalBSONCallTracker struct {
349
+ called bool // called is set to true when UnmarshalBSON is invoked.
350
+ }
351
+
352
+ // Ensure unmarshalBSONCallTracker implements the Unmarshaler interface.
353
+ var _ Unmarshaler = & unmarshalBSONCallTracker {}
354
+
355
+ // unmarshalBehaviorTestCase holds instances of call trackers for testing BSON
356
+ // unmarshaling behavior.
357
+ type unmarshalBehaviorTestCase struct {
358
+ BSONValueTracker unmarshalBSONValueCallTracker `bson:"bv_tracker"` // BSON value unmarshaling by value.
359
+ BSONValuePtrTracker * unmarshalBSONValueCallTracker `bson:"bv_ptr_tracker"` // BSON value unmarshaling by pointer.
360
+ BSONTracker unmarshalBSONCallTracker `bson:"b_tracker"` // BSON unmarshaling by value.
361
+ BSONPtrTracker * unmarshalBSONCallTracker `bson:"b_ptr_tracker"` // BSON unmarshaling by pointer.
362
+ }
363
+
364
+ func (tracker * unmarshalBSONValueCallTracker ) UnmarshalBSONValue (bsontype.Type , []byte ) error {
365
+ tracker .called = true
366
+ return nil
367
+ }
368
+
369
+ func (tracker * unmarshalBSONCallTracker ) UnmarshalBSON ([]byte ) error {
370
+ tracker .called = true
371
+ return nil
372
+ }
0 commit comments