@@ -172,6 +172,70 @@ func unmarshalingTestCases() []unmarshalingTestCase {
172172 want : & valNonPtrStruct ,
173173 data : docToBytes (valNonPtrStruct ),
174174 },
175+ {
176+ name : "nil pointer and non-pointer type with literal null BSON" ,
177+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
178+ want : & unmarshalBehaviorTestCase {
179+ BSONValueTracker : unmarshalBSONValueCallTracker {
180+ called : true ,
181+ },
182+ BSONValuePtrTracker : nil ,
183+ BSONTracker : unmarshalBSONCallTracker {
184+ called : true ,
185+ },
186+ BSONPtrTracker : nil ,
187+ },
188+ data : docToBytes (D {
189+ {Key : "bv_tracker" , Value : nil },
190+ {Key : "bv_ptr_tracker" , Value : nil },
191+ {Key : "b_tracker" , Value : nil },
192+ {Key : "b_ptr_tracker" , Value : nil },
193+ }),
194+ },
195+ {
196+ name : "nil pointer and non-pointer type with BSON minkey" ,
197+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
198+ want : & unmarshalBehaviorTestCase {
199+ BSONValueTracker : unmarshalBSONValueCallTracker {
200+ called : true ,
201+ },
202+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
203+ called : true ,
204+ },
205+ BSONTracker : unmarshalBSONCallTracker {
206+ called : true ,
207+ },
208+ BSONPtrTracker : nil ,
209+ },
210+ data : docToBytes (D {
211+ {Key : "bv_tracker" , Value : MinKey {}},
212+ {Key : "bv_ptr_tracker" , Value : MinKey {}},
213+ {Key : "b_tracker" , Value : MinKey {}},
214+ {Key : "b_ptr_tracker" , Value : MinKey {}},
215+ }),
216+ },
217+ {
218+ name : "nil pointer and non-pointer type with BSON maxkey" ,
219+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
220+ want : & unmarshalBehaviorTestCase {
221+ BSONValueTracker : unmarshalBSONValueCallTracker {
222+ called : true ,
223+ },
224+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
225+ called : true ,
226+ },
227+ BSONTracker : unmarshalBSONCallTracker {
228+ called : true ,
229+ },
230+ BSONPtrTracker : nil ,
231+ },
232+ data : docToBytes (D {
233+ {Key : "bv_tracker" , Value : MaxKey {}},
234+ {Key : "bv_ptr_tracker" , Value : MaxKey {}},
235+ {Key : "b_tracker" , Value : MaxKey {}},
236+ {Key : "b_ptr_tracker" , Value : MaxKey {}},
237+ }),
238+ },
175239 }
176240}
177241
@@ -267,3 +331,39 @@ func (ms *myString) UnmarshalBSON(b []byte) error {
267331 * ms = myString (s )
268332 return nil
269333}
334+
335+ // unmarshalBSONValueCallTracker is a test struct that tracks whether the
336+ // UnmarshalBSONValue method has been called.
337+ type unmarshalBSONValueCallTracker struct {
338+ called bool // called is set to true when UnmarshalBSONValue is invoked.
339+ }
340+
341+ var _ ValueUnmarshaler = & unmarshalBSONValueCallTracker {}
342+
343+ // unmarshalBSONCallTracker is a test struct that tracks whether the
344+ // UnmarshalBSON method has been called.
345+ type unmarshalBSONCallTracker struct {
346+ called bool // called is set to true when UnmarshalBSON is invoked.
347+ }
348+
349+ // Ensure unmarshalBSONCallTracker implements the Unmarshaler interface.
350+ var _ Unmarshaler = & unmarshalBSONCallTracker {}
351+
352+ // unmarshalBehaviorTestCase holds instances of call trackers for testing BSON
353+ // unmarshaling behavior.
354+ type unmarshalBehaviorTestCase struct {
355+ BSONValueTracker unmarshalBSONValueCallTracker `bson:"bv_tracker"` // BSON value unmarshaling by value.
356+ BSONValuePtrTracker * unmarshalBSONValueCallTracker `bson:"bv_ptr_tracker"` // BSON value unmarshaling by pointer.
357+ BSONTracker unmarshalBSONCallTracker `bson:"b_tracker"` // BSON unmarshaling by value.
358+ BSONPtrTracker * unmarshalBSONCallTracker `bson:"b_ptr_tracker"` // BSON unmarshaling by pointer.
359+ }
360+
361+ func (tracker * unmarshalBSONValueCallTracker ) UnmarshalBSONValue (byte , []byte ) error {
362+ tracker .called = true
363+ return nil
364+ }
365+
366+ func (tracker * unmarshalBSONCallTracker ) UnmarshalBSON ([]byte ) error {
367+ tracker .called = true
368+ return nil
369+ }
0 commit comments