@@ -172,6 +172,50 @@ func unmarshalingTestCases() []unmarshalingTestCase {
172172 want : & valNonPtrStruct ,
173173 data : docToBytes (valNonPtrStruct ),
174174 },
175+ {
176+ name : "nil pointer and non-pointer type with BSON minkey" ,
177+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
178+ want : & unmarshalBehaviorTestCase {
179+ BSONValueTracker : unmarshalBSONValueCallTracker {
180+ called : true ,
181+ },
182+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
183+ called : true ,
184+ },
185+ BSONTracker : unmarshalBSONCallTracker {
186+ called : true ,
187+ },
188+ BSONPtrTracker : nil ,
189+ },
190+ data : docToBytes (D {
191+ {Key : "bv_tracker" , Value : MinKey {}},
192+ {Key : "bv_ptr_tracker" , Value : MinKey {}},
193+ {Key : "b_tracker" , Value : MinKey {}},
194+ {Key : "b_ptr_tracker" , Value : MinKey {}},
195+ }),
196+ },
197+ {
198+ name : "nil pointer and non-pointer type with BSON maxkey" ,
199+ sType : reflect .TypeOf (unmarshalBehaviorTestCase {}),
200+ want : & unmarshalBehaviorTestCase {
201+ BSONValueTracker : unmarshalBSONValueCallTracker {
202+ called : true ,
203+ },
204+ BSONValuePtrTracker : & unmarshalBSONValueCallTracker {
205+ called : true ,
206+ },
207+ BSONTracker : unmarshalBSONCallTracker {
208+ called : true ,
209+ },
210+ BSONPtrTracker : nil ,
211+ },
212+ data : docToBytes (D {
213+ {Key : "bv_tracker" , Value : MaxKey {}},
214+ {Key : "bv_ptr_tracker" , Value : MaxKey {}},
215+ {Key : "b_tracker" , Value : MaxKey {}},
216+ {Key : "b_ptr_tracker" , Value : MaxKey {}},
217+ }),
218+ },
175219 }
176220}
177221
@@ -267,3 +311,38 @@ func (ms *myString) UnmarshalBSON(b []byte) error {
267311 * ms = myString (s )
268312 return nil
269313}
314+
315+ // unmarshalBSONValueCallTracker is a test struct that tracks whether the
316+ // UnmarshalBSONValue method has been called.
317+ type unmarshalBSONValueCallTracker struct {
318+ called bool // called is set to true when UnmarshalBSONValue is invoked.
319+ }
320+
321+ var _ ValueUnmarshaler = & unmarshalBSONValueCallTracker {}
322+
323+ // unmarshalBSONCallTracker is a test struct that tracks whether the
324+ // UnmarshalBSON method has been called.
325+ type unmarshalBSONCallTracker struct {
326+ called bool // called is set to true when UnmarshalBSON is invoked.
327+ }
328+
329+ // Ensure unmarshalBSONCallTracker implements the Unmarshaler interface.
330+ var _ Unmarshaler = & unmarshalBSONCallTracker {}
331+
332+ // unmarshalBehaviorTestCase holds instances of call trackers for testing BSON
333+ // unmarshaling behavior.
334+ type unmarshalBehaviorTestCase struct {
335+ BSONValueTracker unmarshalBSONValueCallTracker `bson:"bv_tracker"` // BSON value unmarshaling by value.
336+ BSONValuePtrTracker * unmarshalBSONValueCallTracker `bson:"bv_ptr_tracker"` // BSON value unmarshaling by pointer.
337+ BSONTracker unmarshalBSONCallTracker `bson:"b_tracker"` // BSON unmarshaling by value.
338+ BSONPtrTracker * unmarshalBSONCallTracker `bson:"b_ptr_tracker"` // BSON unmarshaling by pointer.
339+ }
340+
341+ func (tracker * unmarshalBSONValueCallTracker ) UnmarshalBSONValue (byte , []byte ) error {
342+ tracker .called = true
343+ return nil
344+ }
345+ func (tracker * unmarshalBSONCallTracker ) UnmarshalBSON ([]byte ) error {
346+ tracker .called = true
347+ return nil
348+ }
0 commit comments