@@ -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
@@ -250,3 +315,39 @@ func (ms *myString) UnmarshalBSON(bytes []byte) error {
250
315
* ms = myString (s )
251
316
return nil
252
317
}
318
+
319
+ // unmarshalBSONValueCallTracker is a test struct that tracks whether the
320
+ // UnmarshalBSONValue method has been called.
321
+ type unmarshalBSONValueCallTracker struct {
322
+ called bool // called is set to true when UnmarshalBSONValue is invoked.
323
+ }
324
+
325
+ var _ ValueUnmarshaler = & unmarshalBSONValueCallTracker {}
326
+
327
+ // unmarshalBSONCallTracker is a test struct that tracks whether the
328
+ // UnmarshalBSON method has been called.
329
+ type unmarshalBSONCallTracker struct {
330
+ called bool // called is set to true when UnmarshalBSON is invoked.
331
+ }
332
+
333
+ // Ensure unmarshalBSONCallTracker implements the Unmarshaler interface.
334
+ var _ Unmarshaler = & unmarshalBSONCallTracker {}
335
+
336
+ // unmarshalBehaviorTestCase holds instances of call trackers for testing BSON
337
+ // unmarshaling behavior.
338
+ type unmarshalBehaviorTestCase struct {
339
+ BSONValueTracker unmarshalBSONValueCallTracker `bson:"bv_tracker"` // BSON value unmarshaling by value.
340
+ BSONValuePtrTracker * unmarshalBSONValueCallTracker `bson:"bv_ptr_tracker"` // BSON value unmarshaling by pointer.
341
+ BSONTracker unmarshalBSONCallTracker `bson:"b_tracker"` // BSON unmarshaling by value.
342
+ BSONPtrTracker * unmarshalBSONCallTracker `bson:"b_ptr_tracker"` // BSON unmarshaling by pointer.
343
+ }
344
+
345
+ func (tracker * unmarshalBSONValueCallTracker ) UnmarshalBSONValue (bsontype.Type , []byte ) error {
346
+ tracker .called = true
347
+ return nil
348
+ }
349
+
350
+ func (tracker * unmarshalBSONCallTracker ) UnmarshalBSON ([]byte ) error {
351
+ tracker .called = true
352
+ return nil
353
+ }
0 commit comments