@@ -11,6 +11,7 @@ import (
1111
1212 "go.mongodb.org/mongo-driver/bson/bsonrw"
1313 "go.mongodb.org/mongo-driver/bson/bsontype"
14+ "go.mongodb.org/mongo-driver/bson/primitive"
1415)
1516
1617type unmarshalingTestCase struct {
@@ -114,6 +115,26 @@ func unmarshalingTestCases() []unmarshalingTestCase {
114115 },
115116 data : docToBytes (D {{"fooBar" , int32 (10 )}}),
116117 },
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+ },
117138 // GODRIVER-2252
118139 // Test that a struct of pointer types with UnmarshalBSON functions defined marshal and
119140 // unmarshal to the same Go values when the pointer values are "nil".
@@ -174,6 +195,50 @@ func unmarshalingTestCases() []unmarshalingTestCase {
174195 want : & valNonPtrStruct ,
175196 data : docToBytes (valNonPtrStruct ),
176197 },
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+ },
177242 }
178243}
179244
@@ -250,3 +315,39 @@ func (ms *myString) UnmarshalBSON(bytes []byte) error {
250315 * ms = myString (s )
251316 return nil
252317}
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