1
2
3
4
5
6
7 package bsoncodec
8
9 import (
10 "bytes"
11 "encoding/json"
12 "errors"
13 "fmt"
14 "math"
15 "net/url"
16 "reflect"
17 "strings"
18 "testing"
19 "time"
20
21 "github.com/google/go-cmp/cmp"
22 "go.mongodb.org/mongo-driver/bson/bsonrw"
23 "go.mongodb.org/mongo-driver/bson/bsonrw/bsonrwtest"
24 "go.mongodb.org/mongo-driver/bson/bsontype"
25 "go.mongodb.org/mongo-driver/bson/primitive"
26 "go.mongodb.org/mongo-driver/internal/assert"
27 "go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
28 )
29
30 var (
31 defaultTestStructCodec = newDefaultStructCodec()
32 )
33
34 func TestDefaultValueDecoders(t *testing.T) {
35 var dvd DefaultValueDecoders
36 var wrong = func(string, string) string { return "wrong" }
37
38 type mybool bool
39 type myint8 int8
40 type myint16 int16
41 type myint32 int32
42 type myint64 int64
43 type myint int
44 type myuint8 uint8
45 type myuint16 uint16
46 type myuint32 uint32
47 type myuint64 uint64
48 type myuint uint
49 type myfloat32 float32
50 type myfloat64 float64
51 type mystring string
52 type mystruct struct{}
53
54 const cansetreflectiontest = "cansetreflectiontest"
55 const cansettest = "cansettest"
56
57 now := time.Now().Truncate(time.Millisecond)
58 d128 := primitive.NewDecimal128(12345, 67890)
59 var pbool = func(b bool) *bool { return &b }
60 var pi32 = func(i32 int32) *int32 { return &i32 }
61 var pi64 = func(i64 int64) *int64 { return &i64 }
62
63 type subtest struct {
64 name string
65 val interface{}
66 dctx *DecodeContext
67 llvrw *bsonrwtest.ValueReaderWriter
68 invoke bsonrwtest.Invoked
69 err error
70 }
71
72 testCases := []struct {
73 name string
74 vd ValueDecoder
75 subtests []subtest
76 }{
77 {
78 "BooleanDecodeValue",
79 ValueDecoderFunc(dvd.BooleanDecodeValue),
80 []subtest{
81 {
82 "wrong type",
83 wrong,
84 nil,
85 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean},
86 bsonrwtest.Nothing,
87 ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: reflect.ValueOf(wrong)},
88 },
89 {
90 "type not boolean",
91 bool(false),
92 nil,
93 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
94 bsonrwtest.Nothing,
95 fmt.Errorf("cannot decode %v into a boolean", bsontype.String),
96 },
97 {
98 "fast path",
99 bool(true),
100 nil,
101 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true)},
102 bsonrwtest.ReadBoolean,
103 nil,
104 },
105 {
106 "reflection path",
107 mybool(true),
108 nil,
109 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true)},
110 bsonrwtest.ReadBoolean,
111 nil,
112 },
113 {
114 "reflection path error",
115 mybool(true),
116 nil,
117 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true), Err: errors.New("ReadBoolean Error"), ErrAfter: bsonrwtest.ReadBoolean},
118 bsonrwtest.ReadBoolean, errors.New("ReadBoolean Error"),
119 },
120 {
121 "can set false",
122 cansettest,
123 nil,
124 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean},
125 bsonrwtest.Nothing,
126 ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}},
127 },
128 {
129 "decode null",
130 mybool(false),
131 nil,
132 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
133 bsonrwtest.ReadNull,
134 nil,
135 },
136 {
137 "decode undefined",
138 mybool(false),
139 nil,
140 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
141 bsonrwtest.ReadUndefined,
142 nil,
143 },
144 },
145 },
146 {
147 "IntDecodeValue",
148 ValueDecoderFunc(dvd.IntDecodeValue),
149 []subtest{
150 {
151 "wrong type",
152 wrong,
153 nil,
154 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
155 bsonrwtest.ReadInt32,
156 ValueDecoderError{
157 Name: "IntDecodeValue",
158 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
159 Received: reflect.ValueOf(wrong),
160 },
161 },
162 {
163 "type not int32/int64",
164 0,
165 nil,
166 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
167 bsonrwtest.Nothing,
168 fmt.Errorf("cannot decode %v into an integer type", bsontype.String),
169 },
170 {
171 "ReadInt32 error",
172 0,
173 nil,
174 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
175 bsonrwtest.ReadInt32,
176 errors.New("ReadInt32 error"),
177 },
178 {
179 "ReadInt64 error",
180 0,
181 nil,
182 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
183 bsonrwtest.ReadInt64,
184 errors.New("ReadInt64 error"),
185 },
186 {
187 "ReadDouble error",
188 0,
189 nil,
190 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
191 bsonrwtest.ReadDouble,
192 errors.New("ReadDouble error"),
193 },
194 {
195 "ReadDouble", int64(3), &DecodeContext{},
196 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.00)}, bsonrwtest.ReadDouble,
197 nil,
198 },
199 {
200 "ReadDouble (truncate)", int64(3), &DecodeContext{Truncate: true},
201 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
202 nil,
203 },
204 {
205 "ReadDouble (no truncate)", int64(0), nil,
206 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
207 errCannotTruncate,
208 },
209 {
210 "ReadDouble overflows int64", int64(0), nil,
211 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: math.MaxFloat64}, bsonrwtest.ReadDouble,
212 fmt.Errorf("%g overflows int64", math.MaxFloat64),
213 },
214 {"int8/fast path", int8(127), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32, nil},
215 {"int16/fast path", int16(32676), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32676)}, bsonrwtest.ReadInt32, nil},
216 {"int32/fast path", int32(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1234)}, bsonrwtest.ReadInt32, nil},
217 {"int64/fast path", int64(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
218 {"int/fast path", int(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
219 {
220 "int8/fast path - nil", (*int8)(nil), nil,
221 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
222 ValueDecoderError{
223 Name: "IntDecodeValue",
224 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
225 Received: reflect.ValueOf((*int8)(nil)),
226 },
227 },
228 {
229 "int16/fast path - nil", (*int16)(nil), nil,
230 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
231 ValueDecoderError{
232 Name: "IntDecodeValue",
233 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
234 Received: reflect.ValueOf((*int16)(nil)),
235 },
236 },
237 {
238 "int32/fast path - nil", (*int32)(nil), nil,
239 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
240 ValueDecoderError{
241 Name: "IntDecodeValue",
242 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
243 Received: reflect.ValueOf((*int32)(nil)),
244 },
245 },
246 {
247 "int64/fast path - nil", (*int64)(nil), nil,
248 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
249 ValueDecoderError{
250 Name: "IntDecodeValue",
251 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
252 Received: reflect.ValueOf((*int64)(nil)),
253 },
254 },
255 {
256 "int/fast path - nil", (*int)(nil), nil,
257 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
258 ValueDecoderError{
259 Name: "IntDecodeValue",
260 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
261 Received: reflect.ValueOf((*int)(nil)),
262 },
263 },
264 {
265 "int8/fast path - overflow", int8(0), nil,
266 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(129)}, bsonrwtest.ReadInt32,
267 fmt.Errorf("%d overflows int8", 129),
268 },
269 {
270 "int16/fast path - overflow", int16(0), nil,
271 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32768)}, bsonrwtest.ReadInt32,
272 fmt.Errorf("%d overflows int16", 32768),
273 },
274 {
275 "int32/fast path - overflow", int32(0), nil,
276 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(2147483648)}, bsonrwtest.ReadInt64,
277 fmt.Errorf("%d overflows int32", int64(2147483648)),
278 },
279 {
280 "int8/fast path - overflow (negative)", int8(0), nil,
281 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-129)}, bsonrwtest.ReadInt32,
282 fmt.Errorf("%d overflows int8", -129),
283 },
284 {
285 "int16/fast path - overflow (negative)", int16(0), nil,
286 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-32769)}, bsonrwtest.ReadInt32,
287 fmt.Errorf("%d overflows int16", -32769),
288 },
289 {
290 "int32/fast path - overflow (negative)", int32(0), nil,
291 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-2147483649)}, bsonrwtest.ReadInt64,
292 fmt.Errorf("%d overflows int32", int64(-2147483649)),
293 },
294 {
295 "int8/reflection path", myint8(127), nil,
296 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32,
297 nil,
298 },
299 {
300 "int16/reflection path", myint16(255), nil,
301 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32,
302 nil,
303 },
304 {
305 "int32/reflection path", myint32(511), nil,
306 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(511)}, bsonrwtest.ReadInt32,
307 nil,
308 },
309 {
310 "int64/reflection path", myint64(1023), nil,
311 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1023)}, bsonrwtest.ReadInt32,
312 nil,
313 },
314 {
315 "int/reflection path", myint(2047), nil,
316 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(2047)}, bsonrwtest.ReadInt32,
317 nil,
318 },
319 {
320 "int8/reflection path - overflow", myint8(0), nil,
321 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(129)}, bsonrwtest.ReadInt32,
322 fmt.Errorf("%d overflows int8", 129),
323 },
324 {
325 "int16/reflection path - overflow", myint16(0), nil,
326 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32768)}, bsonrwtest.ReadInt32,
327 fmt.Errorf("%d overflows int16", 32768),
328 },
329 {
330 "int32/reflection path - overflow", myint32(0), nil,
331 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(2147483648)}, bsonrwtest.ReadInt64,
332 fmt.Errorf("%d overflows int32", int64(2147483648)),
333 },
334 {
335 "int8/reflection path - overflow (negative)", myint8(0), nil,
336 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-129)}, bsonrwtest.ReadInt32,
337 fmt.Errorf("%d overflows int8", -129),
338 },
339 {
340 "int16/reflection path - overflow (negative)", myint16(0), nil,
341 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-32769)}, bsonrwtest.ReadInt32,
342 fmt.Errorf("%d overflows int16", -32769),
343 },
344 {
345 "int32/reflection path - overflow (negative)", myint32(0), nil,
346 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-2147483649)}, bsonrwtest.ReadInt64,
347 fmt.Errorf("%d overflows int32", int64(-2147483649)),
348 },
349 {
350 "can set false",
351 cansettest,
352 nil,
353 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
354 bsonrwtest.Nothing,
355 ValueDecoderError{
356 Name: "IntDecodeValue",
357 Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
358 },
359 },
360 {
361 "decode null",
362 myint(0),
363 nil,
364 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
365 bsonrwtest.ReadNull,
366 nil,
367 },
368 {
369 "decode undefined",
370 myint(0),
371 nil,
372 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
373 bsonrwtest.ReadUndefined,
374 nil,
375 },
376 },
377 },
378 {
379 "defaultUIntCodec.DecodeValue",
380 defaultUIntCodec,
381 []subtest{
382 {
383 "wrong type",
384 wrong,
385 nil,
386 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
387 bsonrwtest.ReadInt32,
388 ValueDecoderError{
389 Name: "UintDecodeValue",
390 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
391 Received: reflect.ValueOf(wrong),
392 },
393 },
394 {
395 "type not int32/int64",
396 0,
397 nil,
398 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
399 bsonrwtest.Nothing,
400 fmt.Errorf("cannot decode %v into an integer type", bsontype.String),
401 },
402 {
403 "ReadInt32 error",
404 uint(0),
405 nil,
406 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
407 bsonrwtest.ReadInt32,
408 errors.New("ReadInt32 error"),
409 },
410 {
411 "ReadInt64 error",
412 uint(0),
413 nil,
414 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
415 bsonrwtest.ReadInt64,
416 errors.New("ReadInt64 error"),
417 },
418 {
419 "ReadDouble error",
420 0,
421 nil,
422 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
423 bsonrwtest.ReadDouble,
424 errors.New("ReadDouble error"),
425 },
426 {
427 "ReadDouble", uint64(3), &DecodeContext{},
428 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.00)}, bsonrwtest.ReadDouble,
429 nil,
430 },
431 {
432 "ReadDouble (truncate)", uint64(3), &DecodeContext{Truncate: true},
433 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
434 nil,
435 },
436 {
437 "ReadDouble (no truncate)", uint64(0), nil,
438 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
439 errCannotTruncate,
440 },
441 {
442 "ReadDouble overflows int64", uint64(0), nil,
443 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: math.MaxFloat64}, bsonrwtest.ReadDouble,
444 fmt.Errorf("%g overflows int64", math.MaxFloat64),
445 },
446 {"uint8/fast path", uint8(127), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32, nil},
447 {"uint16/fast path", uint16(255), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32, nil},
448 {"uint32/fast path", uint32(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1234)}, bsonrwtest.ReadInt32, nil},
449 {"uint64/fast path", uint64(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
450 {"uint/fast path", uint(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
451 {
452 "uint8/fast path - nil", (*uint8)(nil), nil,
453 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
454 ValueDecoderError{
455 Name: "UintDecodeValue",
456 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
457 Received: reflect.ValueOf((*uint8)(nil)),
458 },
459 },
460 {
461 "uint16/fast path - nil", (*uint16)(nil), nil,
462 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
463 ValueDecoderError{
464 Name: "UintDecodeValue",
465 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
466 Received: reflect.ValueOf((*uint16)(nil)),
467 },
468 },
469 {
470 "uint32/fast path - nil", (*uint32)(nil), nil,
471 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
472 ValueDecoderError{
473 Name: "UintDecodeValue",
474 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
475 Received: reflect.ValueOf((*uint32)(nil)),
476 },
477 },
478 {
479 "uint64/fast path - nil", (*uint64)(nil), nil,
480 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
481 ValueDecoderError{
482 Name: "UintDecodeValue",
483 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
484 Received: reflect.ValueOf((*uint64)(nil)),
485 },
486 },
487 {
488 "uint/fast path - nil", (*uint)(nil), nil,
489 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
490 ValueDecoderError{
491 Name: "UintDecodeValue",
492 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
493 Received: reflect.ValueOf((*uint)(nil)),
494 },
495 },
496 {
497 "uint8/fast path - overflow", uint8(0), nil,
498 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 8)}, bsonrwtest.ReadInt32,
499 fmt.Errorf("%d overflows uint8", 1<<8),
500 },
501 {
502 "uint16/fast path - overflow", uint16(0), nil,
503 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 16)}, bsonrwtest.ReadInt32,
504 fmt.Errorf("%d overflows uint16", 1<<16),
505 },
506 {
507 "uint32/fast path - overflow", uint32(0), nil,
508 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1 << 32)}, bsonrwtest.ReadInt64,
509 fmt.Errorf("%d overflows uint32", int64(1<<32)),
510 },
511 {
512 "uint8/fast path - overflow (negative)", uint8(0), nil,
513 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
514 fmt.Errorf("%d overflows uint8", -1),
515 },
516 {
517 "uint16/fast path - overflow (negative)", uint16(0), nil,
518 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
519 fmt.Errorf("%d overflows uint16", -1),
520 },
521 {
522 "uint32/fast path - overflow (negative)", uint32(0), nil,
523 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
524 fmt.Errorf("%d overflows uint32", -1),
525 },
526 {
527 "uint64/fast path - overflow (negative)", uint64(0), nil,
528 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
529 fmt.Errorf("%d overflows uint64", -1),
530 },
531 {
532 "uint/fast path - overflow (negative)", uint(0), nil,
533 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
534 fmt.Errorf("%d overflows uint", -1),
535 },
536 {
537 "uint8/reflection path", myuint8(127), nil,
538 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32,
539 nil,
540 },
541 {
542 "uint16/reflection path", myuint16(255), nil,
543 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32,
544 nil,
545 },
546 {
547 "uint32/reflection path", myuint32(511), nil,
548 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(511)}, bsonrwtest.ReadInt32,
549 nil,
550 },
551 {
552 "uint64/reflection path", myuint64(1023), nil,
553 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1023)}, bsonrwtest.ReadInt32,
554 nil,
555 },
556 {
557 "uint/reflection path", myuint(2047), nil,
558 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(2047)}, bsonrwtest.ReadInt32,
559 nil,
560 },
561 {
562 "uint8/reflection path - overflow", myuint8(0), nil,
563 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 8)}, bsonrwtest.ReadInt32,
564 fmt.Errorf("%d overflows uint8", 1<<8),
565 },
566 {
567 "uint16/reflection path - overflow", myuint16(0), nil,
568 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 16)}, bsonrwtest.ReadInt32,
569 fmt.Errorf("%d overflows uint16", 1<<16),
570 },
571 {
572 "uint32/reflection path - overflow", myuint32(0), nil,
573 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1 << 32)}, bsonrwtest.ReadInt64,
574 fmt.Errorf("%d overflows uint32", int64(1<<32)),
575 },
576 {
577 "uint8/reflection path - overflow (negative)", myuint8(0), nil,
578 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
579 fmt.Errorf("%d overflows uint8", -1),
580 },
581 {
582 "uint16/reflection path - overflow (negative)", myuint16(0), nil,
583 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
584 fmt.Errorf("%d overflows uint16", -1),
585 },
586 {
587 "uint32/reflection path - overflow (negative)", myuint32(0), nil,
588 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
589 fmt.Errorf("%d overflows uint32", -1),
590 },
591 {
592 "uint64/reflection path - overflow (negative)", myuint64(0), nil,
593 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
594 fmt.Errorf("%d overflows uint64", -1),
595 },
596 {
597 "uint/reflection path - overflow (negative)", myuint(0), nil,
598 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
599 fmt.Errorf("%d overflows uint", -1),
600 },
601 {
602 "can set false",
603 cansettest,
604 nil,
605 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
606 bsonrwtest.Nothing,
607 ValueDecoderError{
608 Name: "UintDecodeValue",
609 Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
610 },
611 },
612 },
613 },
614 {
615 "FloatDecodeValue",
616 ValueDecoderFunc(dvd.FloatDecodeValue),
617 []subtest{
618 {
619 "wrong type",
620 wrong,
621 nil,
622 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)},
623 bsonrwtest.ReadDouble,
624 ValueDecoderError{
625 Name: "FloatDecodeValue",
626 Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
627 Received: reflect.ValueOf(wrong),
628 },
629 },
630 {
631 "type not double",
632 0,
633 nil,
634 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
635 bsonrwtest.Nothing,
636 fmt.Errorf("cannot decode %v into a float32 or float64 type", bsontype.String),
637 },
638 {
639 "ReadDouble error",
640 float64(0),
641 nil,
642 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
643 bsonrwtest.ReadDouble,
644 errors.New("ReadDouble error"),
645 },
646 {
647 "ReadInt32 error",
648 float64(0),
649 nil,
650 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
651 bsonrwtest.ReadInt32,
652 errors.New("ReadInt32 error"),
653 },
654 {
655 "ReadInt64 error",
656 float64(0),
657 nil,
658 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
659 bsonrwtest.ReadInt64,
660 errors.New("ReadInt64 error"),
661 },
662 {
663 "float64/int32", float32(32.0), nil,
664 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32)}, bsonrwtest.ReadInt32,
665 nil,
666 },
667 {
668 "float64/int64", float32(64.0), nil,
669 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(64)}, bsonrwtest.ReadInt64,
670 nil,
671 },
672 {
673 "float32/fast path (equal)", float32(3.0), nil,
674 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.0)}, bsonrwtest.ReadDouble,
675 nil,
676 },
677 {
678 "float64/fast path", float64(3.14159), nil,
679 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)}, bsonrwtest.ReadDouble,
680 nil,
681 },
682 {
683 "float32/fast path (truncate)", float32(3.14), &DecodeContext{Truncate: true},
684 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
685 nil,
686 },
687 {
688 "float32/fast path (no truncate)", float32(0), nil,
689 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
690 errCannotTruncate,
691 },
692 {
693 "float32/fast path - nil", (*float32)(nil), nil,
694 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)}, bsonrwtest.ReadDouble,
695 ValueDecoderError{
696 Name: "FloatDecodeValue",
697 Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
698 Received: reflect.ValueOf((*float32)(nil)),
699 },
700 },
701 {
702 "float64/fast path - nil", (*float64)(nil), nil,
703 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)}, bsonrwtest.ReadDouble,
704 ValueDecoderError{
705 Name: "FloatDecodeValue",
706 Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
707 Received: reflect.ValueOf((*float64)(nil)),
708 },
709 },
710 {
711 "float32/reflection path (equal)", myfloat32(3.0), nil,
712 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.0)}, bsonrwtest.ReadDouble,
713 nil,
714 },
715 {
716 "float64/reflection path", myfloat64(3.14159), nil,
717 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)}, bsonrwtest.ReadDouble,
718 nil,
719 },
720 {
721 "float32/reflection path (truncate)", myfloat32(3.14), &DecodeContext{Truncate: true},
722 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
723 nil,
724 },
725 {
726 "float32/reflection path (no truncate)", myfloat32(0), nil,
727 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
728 errCannotTruncate,
729 },
730 {
731 "can set false",
732 cansettest,
733 nil,
734 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)},
735 bsonrwtest.Nothing,
736 ValueDecoderError{
737 Name: "FloatDecodeValue",
738 Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
739 },
740 },
741 },
742 },
743 {
744 "defaultTimeCodec.DecodeValue",
745 defaultTimeCodec,
746 []subtest{
747 {
748 "wrong type",
749 wrong,
750 nil,
751 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0)},
752 bsonrwtest.Nothing,
753 ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: reflect.ValueOf(wrong)},
754 },
755 {
756 "ReadDateTime error",
757 time.Time{},
758 nil,
759 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0), Err: errors.New("ReadDateTime error"), ErrAfter: bsonrwtest.ReadDateTime},
760 bsonrwtest.ReadDateTime,
761 errors.New("ReadDateTime error"),
762 },
763 {
764 "time.Time",
765 now,
766 nil,
767 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: now.UnixNano() / int64(time.Millisecond)},
768 bsonrwtest.ReadDateTime,
769 nil,
770 },
771 {
772 "can set false",
773 cansettest,
774 nil,
775 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0)},
776 bsonrwtest.Nothing,
777 ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}},
778 },
779 {
780 "decode null",
781 time.Time{},
782 nil,
783 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
784 bsonrwtest.ReadNull,
785 nil,
786 },
787 {
788 "decode undefined",
789 time.Time{},
790 nil,
791 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
792 bsonrwtest.ReadUndefined,
793 nil,
794 },
795 },
796 },
797 {
798 "defaultMapCodec.DecodeValue",
799 defaultMapCodec,
800 []subtest{
801 {
802 "wrong kind",
803 wrong,
804 nil,
805 &bsonrwtest.ValueReaderWriter{},
806 bsonrwtest.Nothing,
807 ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: reflect.ValueOf(wrong)},
808 },
809 {
810 "wrong kind (non-string key)",
811 map[bool]interface{}{},
812 &DecodeContext{Registry: buildDefaultRegistry()},
813 &bsonrwtest.ValueReaderWriter{},
814 bsonrwtest.ReadElement,
815 fmt.Errorf("unsupported key type: %T", false),
816 },
817 {
818 "ReadDocument Error",
819 make(map[string]interface{}),
820 nil,
821 &bsonrwtest.ValueReaderWriter{Err: errors.New("rd error"), ErrAfter: bsonrwtest.ReadDocument},
822 bsonrwtest.ReadDocument,
823 errors.New("rd error"),
824 },
825 {
826 "Lookup Error",
827 map[string]string{},
828 &DecodeContext{Registry: NewRegistryBuilder().Build()},
829 &bsonrwtest.ValueReaderWriter{},
830 bsonrwtest.ReadDocument,
831 ErrNoDecoder{Type: reflect.TypeOf("")},
832 },
833 {
834 "ReadElement Error",
835 make(map[string]interface{}),
836 &DecodeContext{Registry: buildDefaultRegistry()},
837 &bsonrwtest.ValueReaderWriter{Err: errors.New("re error"), ErrAfter: bsonrwtest.ReadElement},
838 bsonrwtest.ReadElement,
839 errors.New("re error"),
840 },
841 {
842 "can set false",
843 cansettest,
844 nil,
845 &bsonrwtest.ValueReaderWriter{},
846 bsonrwtest.Nothing,
847 ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}},
848 },
849 {
850 "wrong BSON type",
851 map[string]interface{}{},
852 nil,
853 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
854 bsonrwtest.Nothing,
855 errors.New("cannot decode string into a map[string]interface {}"),
856 },
857 {
858 "decode null",
859 (map[string]interface{})(nil),
860 nil,
861 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
862 bsonrwtest.ReadNull,
863 nil,
864 },
865 {
866 "decode undefined",
867 (map[string]interface{})(nil),
868 nil,
869 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
870 bsonrwtest.ReadUndefined,
871 nil,
872 },
873 },
874 },
875 {
876 "ArrayDecodeValue",
877 ValueDecoderFunc(dvd.ArrayDecodeValue),
878 []subtest{
879 {
880 "wrong kind",
881 wrong,
882 nil,
883 &bsonrwtest.ValueReaderWriter{},
884 bsonrwtest.Nothing,
885 ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: reflect.ValueOf(wrong)},
886 },
887 {
888 "can set false",
889 cansettest,
890 nil,
891 &bsonrwtest.ValueReaderWriter{},
892 bsonrwtest.Nothing,
893 ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}},
894 },
895 {
896 "Not Type Array",
897 [1]interface{}{},
898 nil,
899 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
900 bsonrwtest.Nothing,
901 errors.New("cannot decode string into an array"),
902 },
903 {
904 "ReadArray Error",
905 [1]interface{}{},
906 nil,
907 &bsonrwtest.ValueReaderWriter{Err: errors.New("ra error"), ErrAfter: bsonrwtest.ReadArray, BSONType: bsontype.Array},
908 bsonrwtest.ReadArray,
909 errors.New("ra error"),
910 },
911 {
912 "Lookup Error",
913 [1]string{},
914 &DecodeContext{Registry: NewRegistryBuilder().Build()},
915 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
916 bsonrwtest.ReadArray,
917 ErrNoDecoder{Type: reflect.TypeOf("")},
918 },
919 {
920 "ReadValue Error",
921 [1]string{},
922 &DecodeContext{Registry: buildDefaultRegistry()},
923 &bsonrwtest.ValueReaderWriter{Err: errors.New("rv error"), ErrAfter: bsonrwtest.ReadValue, BSONType: bsontype.Array},
924 bsonrwtest.ReadValue,
925 errors.New("rv error"),
926 },
927 {
928 "DecodeValue Error",
929 [1]string{},
930 &DecodeContext{Registry: buildDefaultRegistry()},
931 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
932 bsonrwtest.ReadValue,
933 &DecodeError{keys: []string{"0"}, wrapped: errors.New("cannot decode array into a string type")},
934 },
935 {
936 "Document but not D",
937 [1]string{},
938 nil,
939 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Type(0)},
940 bsonrwtest.Nothing,
941 errors.New("cannot decode document into [1]string"),
942 },
943 {
944 "EmbeddedDocument but not D",
945 [1]string{},
946 nil,
947 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.EmbeddedDocument},
948 bsonrwtest.Nothing,
949 errors.New("cannot decode document into [1]string"),
950 },
951 {
952 "decode null",
953 [1]string{},
954 nil,
955 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
956 bsonrwtest.ReadNull,
957 nil,
958 },
959 {
960 "decode undefined",
961 [1]string{},
962 nil,
963 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
964 bsonrwtest.ReadUndefined,
965 nil,
966 },
967 },
968 },
969 {
970 "defaultSliceCodec.DecodeValue",
971 defaultSliceCodec,
972 []subtest{
973 {
974 "wrong kind",
975 wrong,
976 nil,
977 &bsonrwtest.ValueReaderWriter{},
978 bsonrwtest.Nothing,
979 ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: reflect.ValueOf(wrong)},
980 },
981 {
982 "can set false",
983 cansettest,
984 nil,
985 &bsonrwtest.ValueReaderWriter{},
986 bsonrwtest.Nothing,
987 ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}},
988 },
989 {
990 "Not Type Array",
991 []interface{}{},
992 nil,
993 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
994 bsonrwtest.Nothing,
995 errors.New("cannot decode 32-bit integer into a slice"),
996 },
997 {
998 "ReadArray Error",
999 []interface{}{},
1000 nil,
1001 &bsonrwtest.ValueReaderWriter{Err: errors.New("ra error"), ErrAfter: bsonrwtest.ReadArray, BSONType: bsontype.Array},
1002 bsonrwtest.ReadArray,
1003 errors.New("ra error"),
1004 },
1005 {
1006 "Lookup Error",
1007 []string{},
1008 &DecodeContext{Registry: NewRegistryBuilder().Build()},
1009 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
1010 bsonrwtest.ReadArray,
1011 ErrNoDecoder{Type: reflect.TypeOf("")},
1012 },
1013 {
1014 "ReadValue Error",
1015 []string{},
1016 &DecodeContext{Registry: buildDefaultRegistry()},
1017 &bsonrwtest.ValueReaderWriter{Err: errors.New("rv error"), ErrAfter: bsonrwtest.ReadValue, BSONType: bsontype.Array},
1018 bsonrwtest.ReadValue,
1019 errors.New("rv error"),
1020 },
1021 {
1022 "DecodeValue Error",
1023 []string{},
1024 &DecodeContext{Registry: buildDefaultRegistry()},
1025 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
1026 bsonrwtest.ReadValue,
1027 &DecodeError{keys: []string{"0"}, wrapped: errors.New("cannot decode array into a string type")},
1028 },
1029 {
1030 "Document but not D",
1031 []string{},
1032 nil,
1033 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Type(0)},
1034 bsonrwtest.Nothing,
1035 errors.New("cannot decode document into []string"),
1036 },
1037 {
1038 "EmbeddedDocument but not D",
1039 []string{},
1040 nil,
1041 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.EmbeddedDocument},
1042 bsonrwtest.Nothing,
1043 errors.New("cannot decode document into []string"),
1044 },
1045 {
1046 "decode null",
1047 ([]string)(nil),
1048 nil,
1049 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1050 bsonrwtest.ReadNull,
1051 nil,
1052 },
1053 {
1054 "decode undefined",
1055 ([]string)(nil),
1056 nil,
1057 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1058 bsonrwtest.ReadUndefined,
1059 nil,
1060 },
1061 },
1062 },
1063 {
1064 "ObjectIDDecodeValue",
1065 ValueDecoderFunc(dvd.ObjectIDDecodeValue),
1066 []subtest{
1067 {
1068 "wrong type",
1069 wrong,
1070 nil,
1071 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID},
1072 bsonrwtest.Nothing,
1073 ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: reflect.ValueOf(wrong)},
1074 },
1075 {
1076 "type not objectID",
1077 primitive.ObjectID{},
1078 nil,
1079 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
1080 bsonrwtest.Nothing,
1081 fmt.Errorf("cannot decode %v into an ObjectID", bsontype.Int32),
1082 },
1083 {
1084 "ReadObjectID Error",
1085 primitive.ObjectID{},
1086 nil,
1087 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Err: errors.New("roid error"), ErrAfter: bsonrwtest.ReadObjectID},
1088 bsonrwtest.ReadObjectID,
1089 errors.New("roid error"),
1090 },
1091 {
1092 "can set false",
1093 cansettest,
1094 nil,
1095 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Return: primitive.ObjectID{}},
1096 bsonrwtest.Nothing,
1097 ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}},
1098 },
1099 {
1100 "success",
1101 primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
1102 nil,
1103 &bsonrwtest.ValueReaderWriter{
1104 BSONType: bsontype.ObjectID,
1105 Return: primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
1106 },
1107 bsonrwtest.ReadObjectID,
1108 nil,
1109 },
1110 {
1111 "success/string",
1112 primitive.ObjectID{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62},
1113 nil,
1114 &bsonrwtest.ValueReaderWriter{
1115 BSONType: bsontype.String,
1116 Return: "0123456789ab",
1117 },
1118 bsonrwtest.ReadString,
1119 nil,
1120 },
1121 {
1122 "success/string-hex",
1123 primitive.ObjectID{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62},
1124 nil,
1125 &bsonrwtest.ValueReaderWriter{
1126 BSONType: bsontype.String,
1127 Return: "303132333435363738396162",
1128 },
1129 bsonrwtest.ReadString,
1130 nil,
1131 },
1132 {
1133 "decode null",
1134 primitive.ObjectID{},
1135 nil,
1136 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1137 bsonrwtest.ReadNull,
1138 nil,
1139 },
1140 {
1141 "decode undefined",
1142 primitive.ObjectID{},
1143 nil,
1144 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1145 bsonrwtest.ReadUndefined,
1146 nil,
1147 },
1148 },
1149 },
1150 {
1151 "Decimal128DecodeValue",
1152 ValueDecoderFunc(dvd.Decimal128DecodeValue),
1153 []subtest{
1154 {
1155 "wrong type",
1156 wrong,
1157 nil,
1158 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128},
1159 bsonrwtest.Nothing,
1160 ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: reflect.ValueOf(wrong)},
1161 },
1162 {
1163 "type not decimal128",
1164 primitive.Decimal128{},
1165 nil,
1166 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1167 bsonrwtest.Nothing,
1168 fmt.Errorf("cannot decode %v into a primitive.Decimal128", bsontype.String),
1169 },
1170 {
1171 "ReadDecimal128 Error",
1172 primitive.Decimal128{},
1173 nil,
1174 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Err: errors.New("rd128 error"), ErrAfter: bsonrwtest.ReadDecimal128},
1175 bsonrwtest.ReadDecimal128,
1176 errors.New("rd128 error"),
1177 },
1178 {
1179 "can set false",
1180 cansettest,
1181 nil,
1182 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Return: d128},
1183 bsonrwtest.Nothing,
1184 ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}},
1185 },
1186 {
1187 "success",
1188 d128,
1189 nil,
1190 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Return: d128},
1191 bsonrwtest.ReadDecimal128,
1192 nil,
1193 },
1194 {
1195 "decode null",
1196 primitive.Decimal128{},
1197 nil,
1198 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1199 bsonrwtest.ReadNull,
1200 nil,
1201 },
1202 {
1203 "decode undefined",
1204 primitive.Decimal128{},
1205 nil,
1206 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1207 bsonrwtest.ReadUndefined,
1208 nil,
1209 },
1210 },
1211 },
1212 {
1213 "JSONNumberDecodeValue",
1214 ValueDecoderFunc(dvd.JSONNumberDecodeValue),
1215 []subtest{
1216 {
1217 "wrong type",
1218 wrong,
1219 nil,
1220 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID},
1221 bsonrwtest.Nothing,
1222 ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: reflect.ValueOf(wrong)},
1223 },
1224 {
1225 "type not double/int32/int64",
1226 json.Number(""),
1227 nil,
1228 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1229 bsonrwtest.Nothing,
1230 fmt.Errorf("cannot decode %v into a json.Number", bsontype.String),
1231 },
1232 {
1233 "ReadDouble Error",
1234 json.Number(""),
1235 nil,
1236 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Err: errors.New("rd error"), ErrAfter: bsonrwtest.ReadDouble},
1237 bsonrwtest.ReadDouble,
1238 errors.New("rd error"),
1239 },
1240 {
1241 "ReadInt32 Error",
1242 json.Number(""),
1243 nil,
1244 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Err: errors.New("ri32 error"), ErrAfter: bsonrwtest.ReadInt32},
1245 bsonrwtest.ReadInt32,
1246 errors.New("ri32 error"),
1247 },
1248 {
1249 "ReadInt64 Error",
1250 json.Number(""),
1251 nil,
1252 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Err: errors.New("ri64 error"), ErrAfter: bsonrwtest.ReadInt64},
1253 bsonrwtest.ReadInt64,
1254 errors.New("ri64 error"),
1255 },
1256 {
1257 "can set false",
1258 cansettest,
1259 nil,
1260 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Return: primitive.ObjectID{}},
1261 bsonrwtest.Nothing,
1262 ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}},
1263 },
1264 {
1265 "success/double",
1266 json.Number("3.14159"),
1267 nil,
1268 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
1269 bsonrwtest.ReadDouble,
1270 nil,
1271 },
1272 {
1273 "success/int32",
1274 json.Number("12345"),
1275 nil,
1276 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(12345)},
1277 bsonrwtest.ReadInt32,
1278 nil,
1279 },
1280 {
1281 "success/int64",
1282 json.Number("1234567890"),
1283 nil,
1284 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234567890)},
1285 bsonrwtest.ReadInt64,
1286 nil,
1287 },
1288 {
1289 "decode null",
1290 json.Number(""),
1291 nil,
1292 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1293 bsonrwtest.ReadNull,
1294 nil,
1295 },
1296 {
1297 "decode undefined",
1298 json.Number(""),
1299 nil,
1300 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1301 bsonrwtest.ReadUndefined,
1302 nil,
1303 },
1304 },
1305 },
1306 {
1307 "URLDecodeValue",
1308 ValueDecoderFunc(dvd.URLDecodeValue),
1309 []subtest{
1310 {
1311 "wrong type",
1312 url.URL{},
1313 nil,
1314 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
1315 bsonrwtest.Nothing,
1316 fmt.Errorf("cannot decode %v into a *url.URL", bsontype.Int32),
1317 },
1318 {
1319 "type not *url.URL",
1320 int64(0),
1321 nil,
1322 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
1323 bsonrwtest.Nothing,
1324 ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: reflect.ValueOf(int64(0))},
1325 },
1326 {
1327 "ReadString error",
1328 url.URL{},
1329 nil,
1330 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("rs error"), ErrAfter: bsonrwtest.ReadString},
1331 bsonrwtest.ReadString,
1332 errors.New("rs error"),
1333 },
1334 {
1335 "url.Parse error",
1336 url.URL{},
1337 nil,
1338 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "not-valid-%%%%://"},
1339 bsonrwtest.ReadString,
1340 &url.Error{
1341 Op: "parse",
1342 URL: "not-valid-%%%%://",
1343 Err: errors.New("first path segment in URL cannot contain colon"),
1344 },
1345 },
1346 {
1347 "can set false",
1348 cansettest,
1349 nil,
1350 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
1351 bsonrwtest.Nothing,
1352 ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}},
1353 },
1354 {
1355 "url.URL",
1356 url.URL{Scheme: "http", Host: "example.com"},
1357 nil,
1358 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
1359 bsonrwtest.ReadString,
1360 nil,
1361 },
1362 {
1363 "decode null",
1364 url.URL{},
1365 nil,
1366 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1367 bsonrwtest.ReadNull,
1368 nil,
1369 },
1370 {
1371 "decode undefined",
1372 url.URL{},
1373 nil,
1374 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1375 bsonrwtest.ReadUndefined,
1376 nil,
1377 },
1378 },
1379 },
1380 {
1381 "defaultByteSliceCodec.DecodeValue",
1382 defaultByteSliceCodec,
1383 []subtest{
1384 {
1385 "wrong type",
1386 []byte{},
1387 nil,
1388 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
1389 bsonrwtest.Nothing,
1390 fmt.Errorf("cannot decode %v into a []byte", bsontype.Int32),
1391 },
1392 {
1393 "type not []byte",
1394 int64(0),
1395 nil,
1396 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Return: bsoncore.Value{Type: bsontype.Binary}},
1397 bsonrwtest.Nothing,
1398 ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: reflect.ValueOf(int64(0))},
1399 },
1400 {
1401 "ReadBinary error",
1402 []byte{},
1403 nil,
1404 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Err: errors.New("rb error"), ErrAfter: bsonrwtest.ReadBinary},
1405 bsonrwtest.ReadBinary,
1406 errors.New("rb error"),
1407 },
1408 {
1409 "incorrect subtype",
1410 []byte{},
1411 nil,
1412 &bsonrwtest.ValueReaderWriter{
1413 BSONType: bsontype.Binary,
1414 Return: bsoncore.Value{
1415 Type: bsontype.Binary,
1416 Data: bsoncore.AppendBinary(nil, 0xFF, []byte{0x01, 0x02, 0x03}),
1417 },
1418 },
1419 bsonrwtest.ReadBinary,
1420 decodeBinaryError{subtype: byte(0xFF), typeName: "[]byte"},
1421 },
1422 {
1423 "can set false",
1424 cansettest,
1425 nil,
1426 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Return: bsoncore.AppendBinary(nil, 0x00, []byte{0x01, 0x02, 0x03})},
1427 bsonrwtest.Nothing,
1428 ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}},
1429 },
1430 {
1431 "decode null",
1432 ([]byte)(nil),
1433 nil,
1434 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1435 bsonrwtest.ReadNull,
1436 nil,
1437 },
1438 {
1439 "decode undefined",
1440 ([]byte)(nil),
1441 nil,
1442 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1443 bsonrwtest.ReadUndefined,
1444 nil,
1445 },
1446 },
1447 },
1448 {
1449 "defaultStringCodec.DecodeValue",
1450 defaultStringCodec,
1451 []subtest{
1452 {
1453 "symbol",
1454 "var hello = 'world';",
1455 nil,
1456 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: "var hello = 'world';"},
1457 bsonrwtest.ReadSymbol,
1458 nil,
1459 },
1460 {
1461 "decode null",
1462 "",
1463 nil,
1464 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1465 bsonrwtest.ReadNull,
1466 nil,
1467 },
1468 {
1469 "decode undefined",
1470 "",
1471 nil,
1472 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1473 bsonrwtest.ReadUndefined,
1474 nil,
1475 },
1476 },
1477 },
1478 {
1479 "ValueUnmarshalerDecodeValue",
1480 ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue),
1481 []subtest{
1482 {
1483 "wrong type",
1484 wrong,
1485 nil,
1486 nil,
1487 bsonrwtest.Nothing,
1488 ValueDecoderError{
1489 Name: "ValueUnmarshalerDecodeValue",
1490 Types: []reflect.Type{tValueUnmarshaler},
1491 Received: reflect.ValueOf(wrong),
1492 },
1493 },
1494 {
1495 "copy error",
1496 &testValueUnmarshaler{},
1497 nil,
1498 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadString},
1499 bsonrwtest.ReadString,
1500 errors.New("copy error"),
1501 },
1502 {
1503 "ValueUnmarshaler",
1504 &testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world")},
1505 nil,
1506 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "hello, world"},
1507 bsonrwtest.ReadString,
1508 nil,
1509 },
1510 },
1511 },
1512 {
1513 "UnmarshalerDecodeValue",
1514 ValueDecoderFunc(dvd.UnmarshalerDecodeValue),
1515 []subtest{
1516 {
1517 "wrong type",
1518 wrong,
1519 nil,
1520 nil,
1521 bsonrwtest.Nothing,
1522 ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: reflect.ValueOf(wrong)},
1523 },
1524 {
1525 "copy error",
1526 &testUnmarshaler{},
1527 nil,
1528 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadString},
1529 bsonrwtest.ReadString,
1530 errors.New("copy error"),
1531 },
1532 {
1533
1534 "value does not implement Unmarshaler",
1535 testUnmarshaler{Val: bsoncore.AppendDouble(nil, 3.14159)},
1536 nil,
1537 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
1538 bsonrwtest.ReadDouble,
1539 nil,
1540 },
1541 {
1542 "Unmarshaler",
1543 &testUnmarshaler{Val: bsoncore.AppendDouble(nil, 3.14159)},
1544 nil,
1545 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
1546 bsonrwtest.ReadDouble,
1547 nil,
1548 },
1549 },
1550 },
1551 {
1552 "PointerCodec.DecodeValue",
1553 NewPointerCodec(),
1554 []subtest{
1555 {
1556 "not valid", nil, nil, nil, bsonrwtest.Nothing,
1557 ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: reflect.Value{}},
1558 },
1559 {
1560 "can set", cansettest, nil, nil, bsonrwtest.Nothing,
1561 ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}},
1562 },
1563 {
1564 "No Decoder", &wrong, &DecodeContext{Registry: buildDefaultRegistry()}, nil, bsonrwtest.Nothing,
1565 ErrNoDecoder{Type: reflect.TypeOf(wrong)},
1566 },
1567 {
1568 "decode null",
1569 (*mystruct)(nil),
1570 nil,
1571 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1572 bsonrwtest.ReadNull,
1573 nil,
1574 },
1575 {
1576 "decode undefined",
1577 (*mystruct)(nil),
1578 nil,
1579 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1580 bsonrwtest.ReadUndefined,
1581 nil,
1582 },
1583 },
1584 },
1585 {
1586 "BinaryDecodeValue",
1587 ValueDecoderFunc(dvd.BinaryDecodeValue),
1588 []subtest{
1589 {
1590 "wrong type",
1591 wrong,
1592 nil,
1593 &bsonrwtest.ValueReaderWriter{},
1594 bsonrwtest.Nothing,
1595 ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: reflect.ValueOf(wrong)},
1596 },
1597 {
1598 "type not binary",
1599 primitive.Binary{},
1600 nil,
1601 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1602 bsonrwtest.Nothing,
1603 fmt.Errorf("cannot decode %v into a Binary", bsontype.String),
1604 },
1605 {
1606 "ReadBinary Error",
1607 primitive.Binary{},
1608 nil,
1609 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Err: errors.New("rb error"), ErrAfter: bsonrwtest.ReadBinary},
1610 bsonrwtest.ReadBinary,
1611 errors.New("rb error"),
1612 },
1613 {
1614 "Binary/success",
1615 primitive.Binary{Data: []byte{0x01, 0x02, 0x03}, Subtype: 0xFF},
1616 nil,
1617 &bsonrwtest.ValueReaderWriter{
1618 BSONType: bsontype.Binary,
1619 Return: bsoncore.Value{
1620 Type: bsontype.Binary,
1621 Data: bsoncore.AppendBinary(nil, 0xFF, []byte{0x01, 0x02, 0x03}),
1622 },
1623 },
1624 bsonrwtest.ReadBinary,
1625 nil,
1626 },
1627 {
1628 "decode null",
1629 primitive.Binary{},
1630 nil,
1631 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1632 bsonrwtest.ReadNull,
1633 nil,
1634 },
1635 {
1636 "decode undefined",
1637 primitive.Binary{},
1638 nil,
1639 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1640 bsonrwtest.ReadUndefined,
1641 nil,
1642 },
1643 },
1644 },
1645 {
1646 "UndefinedDecodeValue",
1647 ValueDecoderFunc(dvd.UndefinedDecodeValue),
1648 []subtest{
1649 {
1650 "wrong type",
1651 wrong,
1652 nil,
1653 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1654 bsonrwtest.Nothing,
1655 ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: reflect.ValueOf(wrong)},
1656 },
1657 {
1658 "type not undefined",
1659 primitive.Undefined{},
1660 nil,
1661 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1662 bsonrwtest.Nothing,
1663 fmt.Errorf("cannot decode %v into an Undefined", bsontype.String),
1664 },
1665 {
1666 "ReadUndefined Error",
1667 primitive.Undefined{},
1668 nil,
1669 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined, Err: errors.New("ru error"), ErrAfter: bsonrwtest.ReadUndefined},
1670 bsonrwtest.ReadUndefined,
1671 errors.New("ru error"),
1672 },
1673 {
1674 "ReadUndefined/success",
1675 primitive.Undefined{},
1676 nil,
1677 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1678 bsonrwtest.ReadUndefined,
1679 nil,
1680 },
1681 {
1682 "decode null",
1683 primitive.Undefined{},
1684 nil,
1685 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1686 bsonrwtest.ReadNull,
1687 nil,
1688 },
1689 },
1690 },
1691 {
1692 "DateTimeDecodeValue",
1693 ValueDecoderFunc(dvd.DateTimeDecodeValue),
1694 []subtest{
1695 {
1696 "wrong type",
1697 wrong,
1698 nil,
1699 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime},
1700 bsonrwtest.Nothing,
1701 ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: reflect.ValueOf(wrong)},
1702 },
1703 {
1704 "type not datetime",
1705 primitive.DateTime(0),
1706 nil,
1707 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1708 bsonrwtest.Nothing,
1709 fmt.Errorf("cannot decode %v into a DateTime", bsontype.String),
1710 },
1711 {
1712 "ReadDateTime Error",
1713 primitive.DateTime(0),
1714 nil,
1715 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Err: errors.New("rdt error"), ErrAfter: bsonrwtest.ReadDateTime},
1716 bsonrwtest.ReadDateTime,
1717 errors.New("rdt error"),
1718 },
1719 {
1720 "success",
1721 primitive.DateTime(1234567890),
1722 nil,
1723 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(1234567890)},
1724 bsonrwtest.ReadDateTime,
1725 nil,
1726 },
1727 {
1728 "decode null",
1729 primitive.DateTime(0),
1730 nil,
1731 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1732 bsonrwtest.ReadNull,
1733 nil,
1734 },
1735 {
1736 "decode undefined",
1737 primitive.DateTime(0),
1738 nil,
1739 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1740 bsonrwtest.ReadUndefined,
1741 nil,
1742 },
1743 },
1744 },
1745 {
1746 "NullDecodeValue",
1747 ValueDecoderFunc(dvd.NullDecodeValue),
1748 []subtest{
1749 {
1750 "wrong type",
1751 wrong,
1752 nil,
1753 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1754 bsonrwtest.Nothing,
1755 ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: reflect.ValueOf(wrong)},
1756 },
1757 {
1758 "type not null",
1759 primitive.Null{},
1760 nil,
1761 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1762 bsonrwtest.Nothing,
1763 fmt.Errorf("cannot decode %v into a Null", bsontype.String),
1764 },
1765 {
1766 "ReadNull Error",
1767 primitive.Null{},
1768 nil,
1769 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadNull},
1770 bsonrwtest.ReadNull,
1771 errors.New("rn error"),
1772 },
1773 {
1774 "success",
1775 primitive.Null{},
1776 nil,
1777 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1778 bsonrwtest.ReadNull,
1779 nil,
1780 },
1781 },
1782 },
1783 {
1784 "RegexDecodeValue",
1785 ValueDecoderFunc(dvd.RegexDecodeValue),
1786 []subtest{
1787 {
1788 "wrong type",
1789 wrong,
1790 nil,
1791 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Regex},
1792 bsonrwtest.Nothing,
1793 ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: reflect.ValueOf(wrong)},
1794 },
1795 {
1796 "type not regex",
1797 primitive.Regex{},
1798 nil,
1799 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1800 bsonrwtest.Nothing,
1801 fmt.Errorf("cannot decode %v into a Regex", bsontype.String),
1802 },
1803 {
1804 "ReadRegex Error",
1805 primitive.Regex{},
1806 nil,
1807 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Regex, Err: errors.New("rr error"), ErrAfter: bsonrwtest.ReadRegex},
1808 bsonrwtest.ReadRegex,
1809 errors.New("rr error"),
1810 },
1811 {
1812 "success",
1813 primitive.Regex{Pattern: "foo", Options: "bar"},
1814 nil,
1815 &bsonrwtest.ValueReaderWriter{
1816 BSONType: bsontype.Regex,
1817 Return: bsoncore.Value{
1818 Type: bsontype.Regex,
1819 Data: bsoncore.AppendRegex(nil, "foo", "bar"),
1820 },
1821 },
1822 bsonrwtest.ReadRegex,
1823 nil,
1824 },
1825 {
1826 "decode null",
1827 primitive.Regex{},
1828 nil,
1829 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1830 bsonrwtest.ReadNull,
1831 nil,
1832 },
1833 {
1834 "decode undefined",
1835 primitive.Regex{},
1836 nil,
1837 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1838 bsonrwtest.ReadUndefined,
1839 nil,
1840 },
1841 },
1842 },
1843 {
1844 "DBPointerDecodeValue",
1845 ValueDecoderFunc(dvd.DBPointerDecodeValue),
1846 []subtest{
1847 {
1848 "wrong type",
1849 wrong,
1850 nil,
1851 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DBPointer},
1852 bsonrwtest.Nothing,
1853 ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: reflect.ValueOf(wrong)},
1854 },
1855 {
1856 "type not dbpointer",
1857 primitive.DBPointer{},
1858 nil,
1859 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1860 bsonrwtest.Nothing,
1861 fmt.Errorf("cannot decode %v into a DBPointer", bsontype.String),
1862 },
1863 {
1864 "ReadDBPointer Error",
1865 primitive.DBPointer{},
1866 nil,
1867 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.DBPointer, Err: errors.New("rdbp error"), ErrAfter: bsonrwtest.ReadDBPointer},
1868 bsonrwtest.ReadDBPointer,
1869 errors.New("rdbp error"),
1870 },
1871 {
1872 "success",
1873 primitive.DBPointer{
1874 DB: "foobar",
1875 Pointer: primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
1876 },
1877 nil,
1878 &bsonrwtest.ValueReaderWriter{
1879 BSONType: bsontype.DBPointer,
1880 Return: bsoncore.Value{
1881 Type: bsontype.DBPointer,
1882 Data: bsoncore.AppendDBPointer(
1883 nil, "foobar", primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
1884 ),
1885 },
1886 },
1887 bsonrwtest.ReadDBPointer,
1888 nil,
1889 },
1890 {
1891 "decode null",
1892 primitive.DBPointer{},
1893 nil,
1894 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1895 bsonrwtest.ReadNull,
1896 nil,
1897 },
1898 {
1899 "decode undefined",
1900 primitive.DBPointer{},
1901 nil,
1902 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1903 bsonrwtest.ReadUndefined,
1904 nil,
1905 },
1906 },
1907 },
1908 {
1909 "TimestampDecodeValue",
1910 ValueDecoderFunc(dvd.TimestampDecodeValue),
1911 []subtest{
1912 {
1913 "wrong type",
1914 wrong,
1915 nil,
1916 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Timestamp},
1917 bsonrwtest.Nothing,
1918 ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: reflect.ValueOf(wrong)},
1919 },
1920 {
1921 "type not timestamp",
1922 primitive.Timestamp{},
1923 nil,
1924 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1925 bsonrwtest.Nothing,
1926 fmt.Errorf("cannot decode %v into a Timestamp", bsontype.String),
1927 },
1928 {
1929 "ReadTimestamp Error",
1930 primitive.Timestamp{},
1931 nil,
1932 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Timestamp, Err: errors.New("rt error"), ErrAfter: bsonrwtest.ReadTimestamp},
1933 bsonrwtest.ReadTimestamp,
1934 errors.New("rt error"),
1935 },
1936 {
1937 "success",
1938 primitive.Timestamp{T: 12345, I: 67890},
1939 nil,
1940 &bsonrwtest.ValueReaderWriter{
1941 BSONType: bsontype.Timestamp,
1942 Return: bsoncore.Value{
1943 Type: bsontype.Timestamp,
1944 Data: bsoncore.AppendTimestamp(nil, 12345, 67890),
1945 },
1946 },
1947 bsonrwtest.ReadTimestamp,
1948 nil,
1949 },
1950 {
1951 "decode null",
1952 primitive.Timestamp{},
1953 nil,
1954 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
1955 bsonrwtest.ReadNull,
1956 nil,
1957 },
1958 {
1959 "decode undefined",
1960 primitive.Timestamp{},
1961 nil,
1962 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
1963 bsonrwtest.ReadUndefined,
1964 nil,
1965 },
1966 },
1967 },
1968 {
1969 "MinKeyDecodeValue",
1970 ValueDecoderFunc(dvd.MinKeyDecodeValue),
1971 []subtest{
1972 {
1973 "wrong type",
1974 wrong,
1975 nil,
1976 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey},
1977 bsonrwtest.Nothing,
1978 ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: reflect.ValueOf(wrong)},
1979 },
1980 {
1981 "type not null",
1982 primitive.MinKey{},
1983 nil,
1984 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
1985 bsonrwtest.Nothing,
1986 fmt.Errorf("cannot decode %v into a MinKey", bsontype.String),
1987 },
1988 {
1989 "ReadMinKey Error",
1990 primitive.MinKey{},
1991 nil,
1992 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadMinKey},
1993 bsonrwtest.ReadMinKey,
1994 errors.New("rn error"),
1995 },
1996 {
1997 "success",
1998 primitive.MinKey{},
1999 nil,
2000 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey},
2001 bsonrwtest.ReadMinKey,
2002 nil,
2003 },
2004 {
2005 "decode null",
2006 primitive.MinKey{},
2007 nil,
2008 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2009 bsonrwtest.ReadNull,
2010 nil,
2011 },
2012 {
2013 "decode undefined",
2014 primitive.MinKey{},
2015 nil,
2016 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2017 bsonrwtest.ReadUndefined,
2018 nil,
2019 },
2020 },
2021 },
2022 {
2023 "MaxKeyDecodeValue",
2024 ValueDecoderFunc(dvd.MaxKeyDecodeValue),
2025 []subtest{
2026 {
2027 "wrong type",
2028 wrong,
2029 nil,
2030 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey},
2031 bsonrwtest.Nothing,
2032 ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: reflect.ValueOf(wrong)},
2033 },
2034 {
2035 "type not null",
2036 primitive.MaxKey{},
2037 nil,
2038 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
2039 bsonrwtest.Nothing,
2040 fmt.Errorf("cannot decode %v into a MaxKey", bsontype.String),
2041 },
2042 {
2043 "ReadMaxKey Error",
2044 primitive.MaxKey{},
2045 nil,
2046 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadMaxKey},
2047 bsonrwtest.ReadMaxKey,
2048 errors.New("rn error"),
2049 },
2050 {
2051 "success",
2052 primitive.MaxKey{},
2053 nil,
2054 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey},
2055 bsonrwtest.ReadMaxKey,
2056 nil,
2057 },
2058 {
2059 "decode null",
2060 primitive.MaxKey{},
2061 nil,
2062 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2063 bsonrwtest.ReadNull,
2064 nil,
2065 },
2066 {
2067 "decode undefined",
2068 primitive.MaxKey{},
2069 nil,
2070 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2071 bsonrwtest.ReadUndefined,
2072 nil,
2073 },
2074 },
2075 },
2076 {
2077 "JavaScriptDecodeValue",
2078 ValueDecoderFunc(dvd.JavaScriptDecodeValue),
2079 []subtest{
2080 {
2081 "wrong type",
2082 wrong,
2083 nil,
2084 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Return: ""},
2085 bsonrwtest.Nothing,
2086 ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: reflect.ValueOf(wrong)},
2087 },
2088 {
2089 "type not Javascript",
2090 primitive.JavaScript(""),
2091 nil,
2092 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
2093 bsonrwtest.Nothing,
2094 fmt.Errorf("cannot decode %v into a primitive.JavaScript", bsontype.String),
2095 },
2096 {
2097 "ReadJavascript Error",
2098 primitive.JavaScript(""),
2099 nil,
2100 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Err: errors.New("rjs error"), ErrAfter: bsonrwtest.ReadJavascript},
2101 bsonrwtest.ReadJavascript,
2102 errors.New("rjs error"),
2103 },
2104 {
2105 "JavaScript/success",
2106 primitive.JavaScript("var hello = 'world';"),
2107 nil,
2108 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Return: "var hello = 'world';"},
2109 bsonrwtest.ReadJavascript,
2110 nil,
2111 },
2112 {
2113 "decode null",
2114 primitive.JavaScript(""),
2115 nil,
2116 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2117 bsonrwtest.ReadNull,
2118 nil,
2119 },
2120 {
2121 "decode undefined",
2122 primitive.JavaScript(""),
2123 nil,
2124 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2125 bsonrwtest.ReadUndefined,
2126 nil,
2127 },
2128 },
2129 },
2130 {
2131 "SymbolDecodeValue",
2132 ValueDecoderFunc(dvd.SymbolDecodeValue),
2133 []subtest{
2134 {
2135 "wrong type",
2136 wrong,
2137 nil,
2138 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: ""},
2139 bsonrwtest.Nothing,
2140 ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: reflect.ValueOf(wrong)},
2141 },
2142 {
2143 "type not Symbol",
2144 primitive.Symbol(""),
2145 nil,
2146 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
2147 bsonrwtest.Nothing,
2148 fmt.Errorf("cannot decode %v into a primitive.Symbol", bsontype.Int32),
2149 },
2150 {
2151 "ReadSymbol Error",
2152 primitive.Symbol(""),
2153 nil,
2154 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Err: errors.New("rjs error"), ErrAfter: bsonrwtest.ReadSymbol},
2155 bsonrwtest.ReadSymbol,
2156 errors.New("rjs error"),
2157 },
2158 {
2159 "Symbol/success",
2160 primitive.Symbol("var hello = 'world';"),
2161 nil,
2162 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: "var hello = 'world';"},
2163 bsonrwtest.ReadSymbol,
2164 nil,
2165 },
2166 {
2167 "decode null",
2168 primitive.Symbol(""),
2169 nil,
2170 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2171 bsonrwtest.ReadNull,
2172 nil,
2173 },
2174 {
2175 "decode undefined",
2176 primitive.Symbol(""),
2177 nil,
2178 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2179 bsonrwtest.ReadUndefined,
2180 nil,
2181 },
2182 },
2183 },
2184 {
2185 "CoreDocumentDecodeValue",
2186 ValueDecoderFunc(dvd.CoreDocumentDecodeValue),
2187 []subtest{
2188 {
2189 "wrong type",
2190 wrong,
2191 nil,
2192 &bsonrwtest.ValueReaderWriter{},
2193 bsonrwtest.Nothing,
2194 ValueDecoderError{
2195 Name: "CoreDocumentDecodeValue",
2196 Types: []reflect.Type{tCoreDocument},
2197 Received: reflect.ValueOf(wrong),
2198 },
2199 },
2200 {
2201 "*bsoncore.Document is nil",
2202 (*bsoncore.Document)(nil),
2203 nil,
2204 nil,
2205 bsonrwtest.Nothing,
2206 ValueDecoderError{
2207 Name: "CoreDocumentDecodeValue",
2208 Types: []reflect.Type{tCoreDocument},
2209 Received: reflect.ValueOf((*bsoncore.Document)(nil)),
2210 },
2211 },
2212 {
2213 "Copy error",
2214 bsoncore.Document{},
2215 nil,
2216 &bsonrwtest.ValueReaderWriter{Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadDocument},
2217 bsonrwtest.ReadDocument,
2218 errors.New("copy error"),
2219 },
2220 },
2221 },
2222 {
2223 "StructCodec.DecodeValue",
2224 defaultTestStructCodec,
2225 []subtest{
2226 {
2227 "Not struct",
2228 reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
2229 nil,
2230 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
2231 bsonrwtest.Nothing,
2232 errors.New("cannot decode string into a struct { Foo string }"),
2233 },
2234 {
2235 "decode null",
2236 reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
2237 nil,
2238 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2239 bsonrwtest.ReadNull,
2240 nil,
2241 },
2242 {
2243 "decode undefined",
2244 reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
2245 nil,
2246 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2247 bsonrwtest.ReadUndefined,
2248 nil,
2249 },
2250 },
2251 },
2252 {
2253 "CodeWithScopeDecodeValue",
2254 ValueDecoderFunc(dvd.CodeWithScopeDecodeValue),
2255 []subtest{
2256 {
2257 "wrong type",
2258 wrong,
2259 nil,
2260 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope},
2261 bsonrwtest.Nothing,
2262 ValueDecoderError{
2263 Name: "CodeWithScopeDecodeValue",
2264 Types: []reflect.Type{tCodeWithScope},
2265 Received: reflect.ValueOf(wrong),
2266 },
2267 },
2268 {
2269 "type not codewithscope",
2270 primitive.CodeWithScope{},
2271 nil,
2272 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
2273 bsonrwtest.Nothing,
2274 fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", bsontype.String),
2275 },
2276 {
2277 "ReadCodeWithScope Error",
2278 primitive.CodeWithScope{},
2279 nil,
2280 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope, Err: errors.New("rcws error"), ErrAfter: bsonrwtest.ReadCodeWithScope},
2281 bsonrwtest.ReadCodeWithScope,
2282 errors.New("rcws error"),
2283 },
2284 {
2285 "decodeDocument Error",
2286 primitive.CodeWithScope{
2287 Code: "var hello = 'world';",
2288 Scope: primitive.D{{"foo", nil}},
2289 },
2290 &DecodeContext{Registry: buildDefaultRegistry()},
2291 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope, Err: errors.New("dd error"), ErrAfter: bsonrwtest.ReadElement},
2292 bsonrwtest.ReadElement,
2293 errors.New("dd error"),
2294 },
2295 {
2296 "decode null",
2297 primitive.CodeWithScope{},
2298 nil,
2299 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
2300 bsonrwtest.ReadNull,
2301 nil,
2302 },
2303 {
2304 "decode undefined",
2305 primitive.CodeWithScope{},
2306 nil,
2307 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
2308 bsonrwtest.ReadUndefined,
2309 nil,
2310 },
2311 },
2312 },
2313 {
2314 "CoreArrayDecodeValue",
2315 defaultArrayCodec,
2316 []subtest{
2317 {
2318 "wrong type",
2319 wrong,
2320 nil,
2321 &bsonrwtest.ValueReaderWriter{},
2322 bsonrwtest.Nothing,
2323 ValueDecoderError{
2324 Name: "CoreArrayDecodeValue",
2325 Types: []reflect.Type{tCoreArray},
2326 Received: reflect.ValueOf(wrong),
2327 },
2328 },
2329 {
2330 "*bsoncore.Array is nil",
2331 (*bsoncore.Array)(nil),
2332 nil,
2333 nil,
2334 bsonrwtest.Nothing,
2335 ValueDecoderError{
2336 Name: "CoreArrayDecodeValue",
2337 Types: []reflect.Type{tCoreArray},
2338 Received: reflect.ValueOf((*bsoncore.Array)(nil)),
2339 },
2340 },
2341 },
2342 },
2343 }
2344
2345 for _, tc := range testCases {
2346 t.Run(tc.name, func(t *testing.T) {
2347 for _, rc := range tc.subtests {
2348 t.Run(rc.name, func(t *testing.T) {
2349 var dc DecodeContext
2350 if rc.dctx != nil {
2351 dc = *rc.dctx
2352 }
2353 llvrw := new(bsonrwtest.ValueReaderWriter)
2354 if rc.llvrw != nil {
2355 llvrw = rc.llvrw
2356 }
2357 llvrw.T = t
2358
2359 if rc.val == cansetreflectiontest {
2360 err := tc.vd.DecodeValue(dc, llvrw, reflect.Value{})
2361 if !compareErrors(err, rc.err) {
2362 t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
2363 }
2364
2365 val := reflect.New(reflect.TypeOf(rc.val)).Elem()
2366 err = tc.vd.DecodeValue(dc, llvrw, val)
2367 if !compareErrors(err, rc.err) {
2368 t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
2369 }
2370 return
2371 }
2372 if rc.val == cansettest {
2373 var wanterr ValueDecoderError
2374 if !errors.As(rc.err, &wanterr) {
2375 t.Fatalf("Error must be a DecodeValueError, but got a %T", rc.err)
2376 }
2377
2378 err := tc.vd.DecodeValue(dc, llvrw, reflect.Value{})
2379 wanterr.Received = reflect.ValueOf(nil)
2380 if !compareErrors(err, wanterr) {
2381 t.Errorf("Errors do not match. got %v; want %v", err, wanterr)
2382 }
2383
2384 err = tc.vd.DecodeValue(dc, llvrw, reflect.ValueOf(int(12345)))
2385 wanterr.Received = reflect.ValueOf(int(12345))
2386 if !compareErrors(err, wanterr) {
2387 t.Errorf("Errors do not match. got %v; want %v", err, wanterr)
2388 }
2389 return
2390 }
2391 var val reflect.Value
2392 if rtype := reflect.TypeOf(rc.val); rtype != nil {
2393 val = reflect.New(rtype).Elem()
2394 }
2395 want := rc.val
2396 defer func() {
2397 if err := recover(); err != nil {
2398 fmt.Println(t.Name())
2399 panic(err)
2400 }
2401 }()
2402 err := tc.vd.DecodeValue(dc, llvrw, val)
2403 if !compareErrors(err, rc.err) {
2404 t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
2405 }
2406 invoked := llvrw.Invoked
2407 if !cmp.Equal(invoked, rc.invoke) {
2408 t.Errorf("Incorrect method invoked. got %v; want %v", invoked, rc.invoke)
2409 }
2410 var got interface{}
2411 if val.IsValid() && val.CanInterface() {
2412 got = val.Interface()
2413 }
2414 if rc.err == nil && !cmp.Equal(got, want, cmp.Comparer(compareDecimal128)) {
2415 t.Errorf("Values do not match. got (%T)%v; want (%T)%v", got, got, want, want)
2416 }
2417 })
2418 }
2419 })
2420 }
2421
2422 t.Run("CodeWithScopeCodec/DecodeValue/success", func(t *testing.T) {
2423 dc := DecodeContext{Registry: buildDefaultRegistry()}
2424 b := bsoncore.BuildDocument(nil,
2425 bsoncore.AppendCodeWithScopeElement(
2426 nil, "foo", "var hello = 'world';",
2427 buildDocument(bsoncore.AppendNullElement(nil, "bar")),
2428 ),
2429 )
2430 dvr := bsonrw.NewBSONDocumentReader(b)
2431 dr, err := dvr.ReadDocument()
2432 noerr(t, err)
2433 _, vr, err := dr.ReadElement()
2434 noerr(t, err)
2435
2436 want := primitive.CodeWithScope{
2437 Code: "var hello = 'world';",
2438 Scope: primitive.D{{"bar", nil}},
2439 }
2440 val := reflect.New(tCodeWithScope).Elem()
2441 err = dvd.CodeWithScopeDecodeValue(dc, vr, val)
2442 noerr(t, err)
2443
2444 got := val.Interface().(primitive.CodeWithScope)
2445 if got.Code != want.Code && !cmp.Equal(got.Scope, want.Scope) {
2446 t.Errorf("CodeWithScopes do not match. got %v; want %v", got, want)
2447 }
2448 })
2449 t.Run("ValueUnmarshalerDecodeValue/UnmarshalBSONValue error", func(t *testing.T) {
2450 var dc DecodeContext
2451 llvrw := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: string("hello, world!")}
2452 llvrw.T = t
2453
2454 want := errors.New("ubsonv error")
2455 valUnmarshaler := &testValueUnmarshaler{err: want}
2456 got := dvd.ValueUnmarshalerDecodeValue(dc, llvrw, reflect.ValueOf(valUnmarshaler))
2457 if !compareErrors(got, want) {
2458 t.Errorf("Errors do not match. got %v; want %v", got, want)
2459 }
2460 })
2461 t.Run("ValueUnmarshalerDecodeValue/Unaddressable value", func(t *testing.T) {
2462 var dc DecodeContext
2463 llvrw := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: string("hello, world!")}
2464 llvrw.T = t
2465
2466 val := reflect.ValueOf(testValueUnmarshaler{})
2467 want := ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
2468 got := dvd.ValueUnmarshalerDecodeValue(dc, llvrw, val)
2469 if !compareErrors(got, want) {
2470 t.Errorf("Errors do not match. got %v; want %v", got, want)
2471 }
2472 })
2473
2474 t.Run("SliceCodec/DecodeValue/can't set slice", func(t *testing.T) {
2475 var val []string
2476 want := ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: reflect.ValueOf(val)}
2477 got := dvd.SliceDecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
2478 if !compareErrors(got, want) {
2479 t.Errorf("Errors do not match. got %v; want %v", got, want)
2480 }
2481 })
2482 t.Run("SliceCodec/DecodeValue/too many elements", func(t *testing.T) {
2483 idx, doc := bsoncore.AppendDocumentStart(nil)
2484 aidx, doc := bsoncore.AppendArrayElementStart(doc, "foo")
2485 doc = bsoncore.AppendStringElement(doc, "0", "foo")
2486 doc = bsoncore.AppendStringElement(doc, "1", "bar")
2487 doc, err := bsoncore.AppendArrayEnd(doc, aidx)
2488 noerr(t, err)
2489 doc, err = bsoncore.AppendDocumentEnd(doc, idx)
2490 noerr(t, err)
2491 dvr := bsonrw.NewBSONDocumentReader(doc)
2492 noerr(t, err)
2493 dr, err := dvr.ReadDocument()
2494 noerr(t, err)
2495 _, vr, err := dr.ReadElement()
2496 noerr(t, err)
2497 var val [1]string
2498 want := fmt.Errorf("more elements returned in array than can fit inside %T, got 2 elements", val)
2499
2500 dc := DecodeContext{Registry: buildDefaultRegistry()}
2501 got := dvd.ArrayDecodeValue(dc, vr, reflect.ValueOf(val))
2502 if !compareErrors(got, want) {
2503 t.Errorf("Errors do not match. got %v; want %v", got, want)
2504 }
2505 })
2506
2507 t.Run("success path", func(t *testing.T) {
2508 oid := primitive.NewObjectID()
2509 oids := []primitive.ObjectID{primitive.NewObjectID(), primitive.NewObjectID(), primitive.NewObjectID()}
2510 var str = new(string)
2511 *str = "bar"
2512 now := time.Now().Truncate(time.Millisecond).UTC()
2513 murl, err := url.Parse("https://mongodb.com/random-url?hello=world")
2514 if err != nil {
2515 t.Errorf("Error parsing URL: %v", err)
2516 t.FailNow()
2517 }
2518 decimal128, err := primitive.ParseDecimal128("1.5e10")
2519 if err != nil {
2520 t.Errorf("Error parsing decimal128: %v", err)
2521 t.FailNow()
2522 }
2523
2524 testCases := []struct {
2525 name string
2526 value interface{}
2527 b []byte
2528 err error
2529 }{
2530 {
2531 "map[string]int",
2532 map[string]int32{"foo": 1},
2533 []byte{
2534 0x0E, 0x00, 0x00, 0x00,
2535 0x10, 'f', 'o', 'o', 0x00,
2536 0x01, 0x00, 0x00, 0x00,
2537 0x00,
2538 },
2539 nil,
2540 },
2541 {
2542 "map[string]primitive.ObjectID",
2543 map[string]primitive.ObjectID{"foo": oid},
2544 func() []byte {
2545 idx, doc := bsoncore.AppendDocumentStart(nil)
2546 doc = bsoncore.AppendObjectIDElement(doc, "foo", oid)
2547 doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
2548 return doc
2549 }(),
2550 nil,
2551 },
2552 {
2553 "map[string][]int32",
2554 map[string][]int32{"Z": {1, 2, 3}},
2555 buildDocumentArray(func(doc []byte) []byte {
2556 doc = bsoncore.AppendInt32Element(doc, "0", 1)
2557 doc = bsoncore.AppendInt32Element(doc, "1", 2)
2558 return bsoncore.AppendInt32Element(doc, "2", 3)
2559 }),
2560 nil,
2561 },
2562 {
2563 "map[string][]primitive.ObjectID",
2564 map[string][]primitive.ObjectID{"Z": oids},
2565 buildDocumentArray(func(doc []byte) []byte {
2566 doc = bsoncore.AppendObjectIDElement(doc, "0", oids[0])
2567 doc = bsoncore.AppendObjectIDElement(doc, "1", oids[1])
2568 return bsoncore.AppendObjectIDElement(doc, "2", oids[2])
2569 }),
2570 nil,
2571 },
2572 {
2573 "map[string][]json.Number(int64)",
2574 map[string][]json.Number{"Z": {json.Number("5"), json.Number("10")}},
2575 buildDocumentArray(func(doc []byte) []byte {
2576 doc = bsoncore.AppendInt64Element(doc, "0", 5)
2577 return bsoncore.AppendInt64Element(doc, "1", 10)
2578 }),
2579 nil,
2580 },
2581 {
2582 "map[string][]json.Number(float64)",
2583 map[string][]json.Number{"Z": {json.Number("5"), json.Number("10.1")}},
2584 buildDocumentArray(func(doc []byte) []byte {
2585 doc = bsoncore.AppendInt64Element(doc, "0", 5)
2586 return bsoncore.AppendDoubleElement(doc, "1", 10.1)
2587 }),
2588 nil,
2589 },
2590 {
2591 "map[string][]*url.URL",
2592 map[string][]*url.URL{"Z": {murl}},
2593 buildDocumentArray(func(doc []byte) []byte {
2594 return bsoncore.AppendStringElement(doc, "0", murl.String())
2595 }),
2596 nil,
2597 },
2598 {
2599 "map[string][]primitive.Decimal128",
2600 map[string][]primitive.Decimal128{"Z": {decimal128}},
2601 buildDocumentArray(func(doc []byte) []byte {
2602 return bsoncore.AppendDecimal128Element(doc, "0", decimal128)
2603 }),
2604 nil,
2605 },
2606 {
2607 "map[mystring]interface{}",
2608 map[mystring]interface{}{"pi": 3.14159},
2609 buildDocument(bsoncore.AppendDoubleElement(nil, "pi", 3.14159)),
2610 nil,
2611 },
2612 {
2613 "-",
2614 struct {
2615 A string `bson:"-"`
2616 }{
2617 A: "",
2618 },
2619 []byte{0x05, 0x00, 0x00, 0x00, 0x00},
2620 nil,
2621 },
2622 {
2623 "omitempty",
2624 struct {
2625 A string `bson:",omitempty"`
2626 }{
2627 A: "",
2628 },
2629 []byte{0x05, 0x00, 0x00, 0x00, 0x00},
2630 nil,
2631 },
2632 {
2633 "omitempty, empty time",
2634 struct {
2635 A time.Time `bson:",omitempty"`
2636 }{
2637 A: time.Time{},
2638 },
2639 []byte{0x05, 0x00, 0x00, 0x00, 0x00},
2640 nil,
2641 },
2642 {
2643 "no private fields",
2644 noPrivateFields{a: "should be empty"},
2645 []byte{0x05, 0x00, 0x00, 0x00, 0x00},
2646 nil,
2647 },
2648 {
2649 "minsize",
2650 struct {
2651 A int64 `bson:",minsize"`
2652 }{
2653 A: 12345,
2654 },
2655 buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
2656 nil,
2657 },
2658 {
2659 "inline",
2660 struct {
2661 Foo struct {
2662 A int64 `bson:",minsize"`
2663 } `bson:",inline"`
2664 }{
2665 Foo: struct {
2666 A int64 `bson:",minsize"`
2667 }{
2668 A: 12345,
2669 },
2670 },
2671 buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
2672 nil,
2673 },
2674 {
2675 "inline struct pointer",
2676 struct {
2677 Foo *struct {
2678 A int64 `bson:",minsize"`
2679 } `bson:",inline"`
2680 Bar *struct {
2681 B int64
2682 } `bson:",inline"`
2683 }{
2684 Foo: &struct {
2685 A int64 `bson:",minsize"`
2686 }{
2687 A: 12345,
2688 },
2689 Bar: nil,
2690 },
2691 buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
2692 nil,
2693 },
2694 {
2695 "nested inline struct pointer",
2696 struct {
2697 Foo *struct {
2698 Bar *struct {
2699 A int64 `bson:",minsize"`
2700 } `bson:",inline"`
2701 } `bson:",inline"`
2702 }{
2703 Foo: &struct {
2704 Bar *struct {
2705 A int64 `bson:",minsize"`
2706 } `bson:",inline"`
2707 }{
2708 Bar: &struct {
2709 A int64 `bson:",minsize"`
2710 }{
2711 A: 12345,
2712 },
2713 },
2714 },
2715 buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
2716 nil,
2717 },
2718 {
2719 "inline nil struct pointer",
2720 struct {
2721 Foo *struct {
2722 A int64 `bson:",minsize"`
2723 } `bson:",inline"`
2724 }{
2725 Foo: nil,
2726 },
2727 buildDocument([]byte{}),
2728 nil,
2729 },
2730 {
2731 "inline overwrite",
2732 struct {
2733 Foo struct {
2734 A int32
2735 B string
2736 } `bson:",inline"`
2737 A int64
2738 }{
2739 Foo: struct {
2740 A int32
2741 B string
2742 }{
2743 A: 0,
2744 B: "foo",
2745 },
2746 A: 54321,
2747 },
2748 buildDocument(func(doc []byte) []byte {
2749 doc = bsoncore.AppendStringElement(doc, "b", "foo")
2750 doc = bsoncore.AppendInt64Element(doc, "a", 54321)
2751 return doc
2752 }(nil)),
2753 nil,
2754 },
2755 {
2756 "inline overwrite with nested structs",
2757 struct {
2758 Foo struct {
2759 A int32
2760 } `bson:",inline"`
2761 Bar struct {
2762 A int32
2763 } `bson:",inline"`
2764 A int64
2765 }{
2766 Foo: struct {
2767 A int32
2768 }{},
2769 Bar: struct {
2770 A int32
2771 }{},
2772 A: 54321,
2773 },
2774 buildDocument(bsoncore.AppendInt64Element(nil, "a", 54321)),
2775 nil,
2776 },
2777 {
2778 "inline map",
2779 struct {
2780 Foo map[string]string `bson:",inline"`
2781 }{
2782 Foo: map[string]string{"foo": "bar"},
2783 },
2784 buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
2785 nil,
2786 },
2787 {
2788 "alternate name bson:name",
2789 struct {
2790 A string `bson:"foo"`
2791 }{
2792 A: "bar",
2793 },
2794 buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
2795 nil,
2796 },
2797 {
2798 "alternate name",
2799 struct {
2800 A string `bson:"foo"`
2801 }{
2802 A: "bar",
2803 },
2804 buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
2805 nil,
2806 },
2807 {
2808 "inline, omitempty",
2809 struct {
2810 A string
2811 Foo zeroTest `bson:"omitempty,inline"`
2812 }{
2813 A: "bar",
2814 Foo: zeroTest{true},
2815 },
2816 buildDocument(bsoncore.AppendStringElement(nil, "a", "bar")),
2817 nil,
2818 },
2819 {
2820 "struct{}",
2821 struct {
2822 A bool
2823 B int32
2824 C int64
2825 D uint16
2826 E uint64
2827 F float64
2828 G string
2829 H map[string]string
2830 I []byte
2831 K [2]string
2832 L struct {
2833 M string
2834 }
2835 Q primitive.ObjectID
2836 T []struct{}
2837 Y json.Number
2838 Z time.Time
2839 AA json.Number
2840 AB *url.URL
2841 AC primitive.Decimal128
2842 AD *time.Time
2843 AE *testValueUnmarshaler
2844 AF *bool
2845 AG *bool
2846 AH *int32
2847 AI *int64
2848 AJ *primitive.ObjectID
2849 AK *primitive.ObjectID
2850 AL testValueUnmarshaler
2851 AM interface{}
2852 AN interface{}
2853 AO interface{}
2854 AP primitive.D
2855 AQ primitive.A
2856 AR [2]primitive.E
2857 AS []byte
2858 AT map[string]interface{}
2859 AU primitive.CodeWithScope
2860 AV primitive.M
2861 AW primitive.D
2862 AX map[string]interface{}
2863 AY []primitive.E
2864 AZ interface{}
2865 }{
2866 A: true,
2867 B: 123,
2868 C: 456,
2869 D: 789,
2870 E: 101112,
2871 F: 3.14159,
2872 G: "Hello, world",
2873 H: map[string]string{"foo": "bar"},
2874 I: []byte{0x01, 0x02, 0x03},
2875 K: [2]string{"baz", "qux"},
2876 L: struct {
2877 M string
2878 }{
2879 M: "foobar",
2880 },
2881 Q: oid,
2882 T: nil,
2883 Y: json.Number("5"),
2884 Z: now,
2885 AA: json.Number("10.1"),
2886 AB: murl,
2887 AC: decimal128,
2888 AD: &now,
2889 AE: &testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world!")},
2890 AF: func(b bool) *bool { return &b }(true),
2891 AG: nil,
2892 AH: func(i32 int32) *int32 { return &i32 }(12345),
2893 AI: func(i64 int64) *int64 { return &i64 }(1234567890),
2894 AJ: &oid,
2895 AK: nil,
2896 AL: testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world!")},
2897 AM: "hello, world",
2898 AN: int32(12345),
2899 AO: oid,
2900 AP: primitive.D{{"foo", "bar"}},
2901 AQ: primitive.A{"foo", "bar"},
2902 AR: [2]primitive.E{{"hello", "world"}, {"pi", 3.14159}},
2903 AS: nil,
2904 AT: nil,
2905 AU: primitive.CodeWithScope{Code: "var hello = 'world';", Scope: primitive.D{{"pi", 3.14159}}},
2906 AV: primitive.M{"foo": primitive.M{"bar": "baz"}},
2907 AW: primitive.D{{"foo", primitive.D{{"bar", "baz"}}}},
2908 AX: map[string]interface{}{"foo": map[string]interface{}{"bar": "baz"}},
2909 AY: []primitive.E{{"foo", []primitive.E{{"bar", "baz"}}}},
2910 AZ: primitive.D{{"foo", primitive.D{{"bar", "baz"}}}},
2911 },
2912 buildDocument(func(doc []byte) []byte {
2913 doc = bsoncore.AppendBooleanElement(doc, "a", true)
2914 doc = bsoncore.AppendInt32Element(doc, "b", 123)
2915 doc = bsoncore.AppendInt64Element(doc, "c", 456)
2916 doc = bsoncore.AppendInt32Element(doc, "d", 789)
2917 doc = bsoncore.AppendInt64Element(doc, "e", 101112)
2918 doc = bsoncore.AppendDoubleElement(doc, "f", 3.14159)
2919 doc = bsoncore.AppendStringElement(doc, "g", "Hello, world")
2920 doc = bsoncore.AppendDocumentElement(doc, "h", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")))
2921 doc = bsoncore.AppendBinaryElement(doc, "i", 0x00, []byte{0x01, 0x02, 0x03})
2922 doc = bsoncore.AppendArrayElement(doc, "k",
2923 buildArray(bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "baz"), "1", "qux")),
2924 )
2925 doc = bsoncore.AppendDocumentElement(doc, "l", buildDocument(bsoncore.AppendStringElement(nil, "m", "foobar")))
2926 doc = bsoncore.AppendObjectIDElement(doc, "q", oid)
2927 doc = bsoncore.AppendNullElement(doc, "t")
2928 doc = bsoncore.AppendInt64Element(doc, "y", 5)
2929 doc = bsoncore.AppendDateTimeElement(doc, "z", now.UnixNano()/int64(time.Millisecond))
2930 doc = bsoncore.AppendDoubleElement(doc, "aa", 10.1)
2931 doc = bsoncore.AppendStringElement(doc, "ab", murl.String())
2932 doc = bsoncore.AppendDecimal128Element(doc, "ac", decimal128)
2933 doc = bsoncore.AppendDateTimeElement(doc, "ad", now.UnixNano()/int64(time.Millisecond))
2934 doc = bsoncore.AppendStringElement(doc, "ae", "hello, world!")
2935 doc = bsoncore.AppendBooleanElement(doc, "af", true)
2936 doc = bsoncore.AppendNullElement(doc, "ag")
2937 doc = bsoncore.AppendInt32Element(doc, "ah", 12345)
2938 doc = bsoncore.AppendInt32Element(doc, "ai", 1234567890)
2939 doc = bsoncore.AppendObjectIDElement(doc, "aj", oid)
2940 doc = bsoncore.AppendNullElement(doc, "ak")
2941 doc = bsoncore.AppendStringElement(doc, "al", "hello, world!")
2942 doc = bsoncore.AppendStringElement(doc, "am", "hello, world")
2943 doc = bsoncore.AppendInt32Element(doc, "an", 12345)
2944 doc = bsoncore.AppendObjectIDElement(doc, "ao", oid)
2945 doc = bsoncore.AppendDocumentElement(doc, "ap", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")))
2946 doc = bsoncore.AppendArrayElement(doc, "aq",
2947 buildArray(bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar")),
2948 )
2949 doc = bsoncore.AppendDocumentElement(doc, "ar",
2950 buildDocument(bsoncore.AppendDoubleElement(bsoncore.AppendStringElement(nil, "hello", "world"), "pi", 3.14159)),
2951 )
2952 doc = bsoncore.AppendNullElement(doc, "as")
2953 doc = bsoncore.AppendNullElement(doc, "at")
2954 doc = bsoncore.AppendCodeWithScopeElement(doc, "au",
2955 "var hello = 'world';", buildDocument(bsoncore.AppendDoubleElement(nil, "pi", 3.14159)),
2956 )
2957 for _, name := range [5]string{"av", "aw", "ax", "ay", "az"} {
2958 doc = bsoncore.AppendDocumentElement(doc, name, buildDocument(
2959 bsoncore.AppendDocumentElement(nil, "foo", buildDocument(
2960 bsoncore.AppendStringElement(nil, "bar", "baz"),
2961 )),
2962 ))
2963 }
2964 return doc
2965 }(nil)),
2966 nil,
2967 },
2968 {
2969 "struct{[]interface{}}",
2970 struct {
2971 A []bool
2972 B []int32
2973 C []int64
2974 D []uint16
2975 E []uint64
2976 F []float64
2977 G []string
2978 H []map[string]string
2979 I [][]byte
2980 K [1][2]string
2981 L []struct {
2982 M string
2983 }
2984 N [][]string
2985 R []primitive.ObjectID
2986 T []struct{}
2987 W []map[string]struct{}
2988 X []map[string]struct{}
2989 Y []map[string]struct{}
2990 Z []time.Time
2991 AA []json.Number
2992 AB []*url.URL
2993 AC []primitive.Decimal128
2994 AD []*time.Time
2995 AE []*testValueUnmarshaler
2996 AF []*bool
2997 AG []*int32
2998 AH []*int64
2999 AI []*primitive.ObjectID
3000 AJ []primitive.D
3001 AK []primitive.A
3002 AL [][2]primitive.E
3003 }{
3004 A: []bool{true},
3005 B: []int32{123},
3006 C: []int64{456},
3007 D: []uint16{789},
3008 E: []uint64{101112},
3009 F: []float64{3.14159},
3010 G: []string{"Hello, world"},
3011 H: []map[string]string{{"foo": "bar"}},
3012 I: [][]byte{{0x01, 0x02, 0x03}},
3013 K: [1][2]string{{"baz", "qux"}},
3014 L: []struct {
3015 M string
3016 }{
3017 {
3018 M: "foobar",
3019 },
3020 },
3021 N: [][]string{{"foo", "bar"}},
3022 R: oids,
3023 T: nil,
3024 W: nil,
3025 X: []map[string]struct{}{},
3026 Y: []map[string]struct{}{{}},
3027 Z: []time.Time{now, now},
3028 AA: []json.Number{json.Number("5"), json.Number("10.1")},
3029 AB: []*url.URL{murl},
3030 AC: []primitive.Decimal128{decimal128},
3031 AD: []*time.Time{&now, &now},
3032 AE: []*testValueUnmarshaler{
3033 {t: bsontype.String, val: bsoncore.AppendString(nil, "hello")},
3034 {t: bsontype.String, val: bsoncore.AppendString(nil, "world")},
3035 },
3036 AF: []*bool{pbool(true), nil},
3037 AG: []*int32{pi32(12345), nil},
3038 AH: []*int64{pi64(1234567890), nil, pi64(9012345678)},
3039 AI: []*primitive.ObjectID{&oid, nil},
3040 AJ: []primitive.D{{{"foo", "bar"}}, nil},
3041 AK: []primitive.A{{"foo", "bar"}, nil},
3042 AL: [][2]primitive.E{{{"hello", "world"}, {"pi", 3.14159}}},
3043 },
3044 buildDocument(func(doc []byte) []byte {
3045 doc = appendArrayElement(doc, "a", bsoncore.AppendBooleanElement(nil, "0", true))
3046 doc = appendArrayElement(doc, "b", bsoncore.AppendInt32Element(nil, "0", 123))
3047 doc = appendArrayElement(doc, "c", bsoncore.AppendInt64Element(nil, "0", 456))
3048 doc = appendArrayElement(doc, "d", bsoncore.AppendInt32Element(nil, "0", 789))
3049 doc = appendArrayElement(doc, "e", bsoncore.AppendInt64Element(nil, "0", 101112))
3050 doc = appendArrayElement(doc, "f", bsoncore.AppendDoubleElement(nil, "0", 3.14159))
3051 doc = appendArrayElement(doc, "g", bsoncore.AppendStringElement(nil, "0", "Hello, world"))
3052 doc = appendArrayElement(doc, "h", bsoncore.BuildDocumentElement(nil, "0", bsoncore.AppendStringElement(nil, "foo", "bar")))
3053 doc = appendArrayElement(doc, "i", bsoncore.AppendBinaryElement(nil, "0", 0x00, []byte{0x01, 0x02, 0x03}))
3054 doc = appendArrayElement(doc, "k",
3055 appendArrayElement(nil, "0",
3056 bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "baz"), "1", "qux")),
3057 )
3058 doc = appendArrayElement(doc, "l", bsoncore.BuildDocumentElement(nil, "0", bsoncore.AppendStringElement(nil, "m", "foobar")))
3059 doc = appendArrayElement(doc, "n",
3060 appendArrayElement(nil, "0",
3061 bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar")),
3062 )
3063 doc = appendArrayElement(doc, "r",
3064 bsoncore.AppendObjectIDElement(
3065 bsoncore.AppendObjectIDElement(
3066 bsoncore.AppendObjectIDElement(nil,
3067 "0", oids[0]),
3068 "1", oids[1]),
3069 "2", oids[2]),
3070 )
3071 doc = bsoncore.AppendNullElement(doc, "t")
3072 doc = bsoncore.AppendNullElement(doc, "w")
3073 doc = appendArrayElement(doc, "x", nil)
3074 doc = appendArrayElement(doc, "y", bsoncore.BuildDocumentElement(nil, "0", nil))
3075 doc = appendArrayElement(doc, "z",
3076 bsoncore.AppendDateTimeElement(
3077 bsoncore.AppendDateTimeElement(
3078 nil, "0", now.UnixNano()/int64(time.Millisecond)),
3079 "1", now.UnixNano()/int64(time.Millisecond)),
3080 )
3081 doc = appendArrayElement(doc, "aa", bsoncore.AppendDoubleElement(bsoncore.AppendInt64Element(nil, "0", 5), "1", 10.10))
3082 doc = appendArrayElement(doc, "ab", bsoncore.AppendStringElement(nil, "0", murl.String()))
3083 doc = appendArrayElement(doc, "ac", bsoncore.AppendDecimal128Element(nil, "0", decimal128))
3084 doc = appendArrayElement(doc, "ad",
3085 bsoncore.AppendDateTimeElement(
3086 bsoncore.AppendDateTimeElement(nil, "0", now.UnixNano()/int64(time.Millisecond)),
3087 "1", now.UnixNano()/int64(time.Millisecond)),
3088 )
3089 doc = appendArrayElement(doc, "ae",
3090 bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "hello"), "1", "world"),
3091 )
3092 doc = appendArrayElement(doc, "af",
3093 bsoncore.AppendNullElement(bsoncore.AppendBooleanElement(nil, "0", true), "1"),
3094 )
3095 doc = appendArrayElement(doc, "ag",
3096 bsoncore.AppendNullElement(bsoncore.AppendInt32Element(nil, "0", 12345), "1"),
3097 )
3098 doc = appendArrayElement(doc, "ah",
3099 bsoncore.AppendInt64Element(
3100 bsoncore.AppendNullElement(bsoncore.AppendInt64Element(nil, "0", 1234567890), "1"),
3101 "2", 9012345678,
3102 ),
3103 )
3104 doc = appendArrayElement(doc, "ai",
3105 bsoncore.AppendNullElement(bsoncore.AppendObjectIDElement(nil, "0", oid), "1"),
3106 )
3107 doc = appendArrayElement(doc, "aj",
3108 bsoncore.AppendNullElement(
3109 bsoncore.AppendDocumentElement(nil, "0", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar"))),
3110 "1",
3111 ),
3112 )
3113 doc = appendArrayElement(doc, "ak",
3114 bsoncore.AppendNullElement(
3115 appendArrayElement(nil, "0",
3116 bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar"),
3117 ),
3118 "1",
3119 ),
3120 )
3121 doc = appendArrayElement(doc, "al",
3122 bsoncore.BuildDocumentElement(nil, "0",
3123 bsoncore.AppendDoubleElement(bsoncore.AppendStringElement(nil, "hello", "world"), "pi", 3.14159),
3124 ),
3125 )
3126 return doc
3127 }(nil)),
3128 nil,
3129 },
3130 }
3131
3132 t.Run("Decode", func(t *testing.T) {
3133 for _, tc := range testCases {
3134 t.Run(tc.name, func(t *testing.T) {
3135 vr := bsonrw.NewBSONDocumentReader(tc.b)
3136 reg := buildDefaultRegistry()
3137 vtype := reflect.TypeOf(tc.value)
3138 dec, err := reg.LookupDecoder(vtype)
3139 noerr(t, err)
3140
3141 gotVal := reflect.New(reflect.TypeOf(tc.value)).Elem()
3142 err = dec.DecodeValue(DecodeContext{Registry: reg}, vr, gotVal)
3143 noerr(t, err)
3144
3145 got := gotVal.Interface()
3146 want := tc.value
3147 if diff := cmp.Diff(
3148 got, want,
3149 cmp.Comparer(compareDecimal128),
3150 cmp.Comparer(compareNoPrivateFields),
3151 cmp.Comparer(compareZeroTest),
3152 cmp.Comparer(compareTime),
3153 ); diff != "" {
3154 t.Errorf("difference:\n%s", diff)
3155 t.Errorf("Values are not equal.\ngot: %#v\nwant:%#v", got, want)
3156 }
3157 })
3158 }
3159 })
3160 })
3161 t.Run("error path", func(t *testing.T) {
3162 testCases := []struct {
3163 name string
3164 value interface{}
3165 b []byte
3166 err error
3167 }{
3168 {
3169 "duplicate name struct",
3170 struct {
3171 A int64
3172 B int64 `bson:"a"`
3173 }{
3174 A: 0,
3175 B: 54321,
3176 },
3177 buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
3178 fmt.Errorf("duplicated key a"),
3179 },
3180 }
3181
3182 for _, tc := range testCases {
3183 t.Run(tc.name, func(t *testing.T) {
3184 vr := bsonrw.NewBSONDocumentReader(tc.b)
3185 reg := buildDefaultRegistry()
3186 vtype := reflect.TypeOf(tc.value)
3187 dec, err := reg.LookupDecoder(vtype)
3188 noerr(t, err)
3189
3190 gotVal := reflect.New(reflect.TypeOf(tc.value)).Elem()
3191 err = dec.DecodeValue(DecodeContext{Registry: reg}, vr, gotVal)
3192 if err == nil || !strings.Contains(err.Error(), tc.err.Error()) {
3193 t.Errorf("Did not receive expected error. got %v; want %v", err, tc.err)
3194 }
3195 })
3196 }
3197 })
3198
3199 t.Run("defaultEmptyInterfaceCodec.DecodeValue", func(t *testing.T) {
3200 t.Run("DecodeValue", func(t *testing.T) {
3201 testCases := []struct {
3202 name string
3203 val interface{}
3204 bsontype bsontype.Type
3205 }{
3206 {
3207 "Double - float64",
3208 float64(3.14159),
3209 bsontype.Double,
3210 },
3211 {
3212 "String - string",
3213 "foo bar baz",
3214 bsontype.String,
3215 },
3216 {
3217 "Array - primitive.A",
3218 primitive.A{3.14159},
3219 bsontype.Array,
3220 },
3221 {
3222 "Binary - Binary",
3223 primitive.Binary{Subtype: 0xFF, Data: []byte{0x01, 0x02, 0x03}},
3224 bsontype.Binary,
3225 },
3226 {
3227 "Undefined - Undefined",
3228 primitive.Undefined{},
3229 bsontype.Undefined,
3230 },
3231 {
3232 "ObjectID - primitive.ObjectID",
3233 primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
3234 bsontype.ObjectID,
3235 },
3236 {
3237 "Boolean - bool",
3238 bool(true),
3239 bsontype.Boolean,
3240 },
3241 {
3242 "DateTime - DateTime",
3243 primitive.DateTime(1234567890),
3244 bsontype.DateTime,
3245 },
3246 {
3247 "Null - Null",
3248 nil,
3249 bsontype.Null,
3250 },
3251 {
3252 "Regex - Regex",
3253 primitive.Regex{Pattern: "foo", Options: "bar"},
3254 bsontype.Regex,
3255 },
3256 {
3257 "DBPointer - DBPointer",
3258 primitive.DBPointer{
3259 DB: "foobar",
3260 Pointer: primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
3261 },
3262 bsontype.DBPointer,
3263 },
3264 {
3265 "JavaScript - JavaScript",
3266 primitive.JavaScript("var foo = 'bar';"),
3267 bsontype.JavaScript,
3268 },
3269 {
3270 "Symbol - Symbol",
3271 primitive.Symbol("foobarbazlolz"),
3272 bsontype.Symbol,
3273 },
3274 {
3275 "Int32 - int32",
3276 int32(123456),
3277 bsontype.Int32,
3278 },
3279 {
3280 "Int64 - int64",
3281 int64(1234567890),
3282 bsontype.Int64,
3283 },
3284 {
3285 "Timestamp - Timestamp",
3286 primitive.Timestamp{T: 12345, I: 67890},
3287 bsontype.Timestamp,
3288 },
3289 {
3290 "Decimal128 - decimal.Decimal128",
3291 primitive.NewDecimal128(12345, 67890),
3292 bsontype.Decimal128,
3293 },
3294 {
3295 "MinKey - MinKey",
3296 primitive.MinKey{},
3297 bsontype.MinKey,
3298 },
3299 {
3300 "MaxKey - MaxKey",
3301 primitive.MaxKey{},
3302 bsontype.MaxKey,
3303 },
3304 }
3305 for _, tc := range testCases {
3306 t.Run(tc.name, func(t *testing.T) {
3307 llvr := &bsonrwtest.ValueReaderWriter{BSONType: tc.bsontype}
3308
3309 t.Run("Type Map failure", func(t *testing.T) {
3310 if tc.bsontype == bsontype.Null {
3311 t.Skip()
3312 }
3313 val := reflect.New(tEmpty).Elem()
3314 dc := DecodeContext{Registry: NewRegistryBuilder().Build()}
3315 want := ErrNoTypeMapEntry{Type: tc.bsontype}
3316 got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, val)
3317 if !compareErrors(got, want) {
3318 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3319 }
3320 })
3321
3322 t.Run("Lookup failure", func(t *testing.T) {
3323 if tc.bsontype == bsontype.Null {
3324 t.Skip()
3325 }
3326 val := reflect.New(tEmpty).Elem()
3327 dc := DecodeContext{
3328 Registry: NewRegistryBuilder().
3329 RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
3330 Build(),
3331 }
3332 want := ErrNoDecoder{Type: reflect.TypeOf(tc.val)}
3333 got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, val)
3334 if !compareErrors(got, want) {
3335 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3336 }
3337 })
3338
3339 t.Run("DecodeValue failure", func(t *testing.T) {
3340 if tc.bsontype == bsontype.Null {
3341 t.Skip()
3342 }
3343 want := errors.New("DecodeValue failure error")
3344 llc := &llCodec{t: t, err: want}
3345 dc := DecodeContext{
3346 Registry: NewRegistryBuilder().
3347 RegisterTypeDecoder(reflect.TypeOf(tc.val), llc).
3348 RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
3349 Build(),
3350 }
3351 got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, reflect.New(tEmpty).Elem())
3352 if !compareErrors(got, want) {
3353 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3354 }
3355 })
3356
3357 t.Run("Success", func(t *testing.T) {
3358 want := tc.val
3359 llc := &llCodec{t: t, decodeval: tc.val}
3360 dc := DecodeContext{
3361 Registry: NewRegistryBuilder().
3362 RegisterTypeDecoder(reflect.TypeOf(tc.val), llc).
3363 RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
3364 Build(),
3365 }
3366 got := reflect.New(tEmpty).Elem()
3367 err := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, got)
3368 noerr(t, err)
3369 if !cmp.Equal(got.Interface(), want, cmp.Comparer(compareDecimal128)) {
3370 t.Errorf("Did not receive expected value. got %v; want %v", got.Interface(), want)
3371 }
3372 })
3373 })
3374 }
3375 })
3376
3377 t.Run("non-interface{}", func(t *testing.T) {
3378 val := uint64(1234567890)
3379 want := ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.ValueOf(val)}
3380 got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
3381 if !compareErrors(got, want) {
3382 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3383 }
3384 })
3385
3386 t.Run("nil *interface{}", func(t *testing.T) {
3387 var val interface{}
3388 want := ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.ValueOf(val)}
3389 got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
3390 if !compareErrors(got, want) {
3391 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3392 }
3393 })
3394
3395 t.Run("no type registered", func(t *testing.T) {
3396 llvr := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double}
3397 want := ErrNoTypeMapEntry{Type: bsontype.Double}
3398 val := reflect.New(tEmpty).Elem()
3399 got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: NewRegistryBuilder().Build()}, llvr, val)
3400 if !compareErrors(got, want) {
3401 t.Errorf("Errors are not equal. got %v; want %v", got, want)
3402 }
3403 })
3404 t.Run("top level document", func(t *testing.T) {
3405 data := bsoncore.BuildDocument(nil, bsoncore.AppendDoubleElement(nil, "pi", 3.14159))
3406 vr := bsonrw.NewBSONDocumentReader(data)
3407 want := primitive.D{{"pi", 3.14159}}
3408 var got interface{}
3409 val := reflect.ValueOf(&got).Elem()
3410 err := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: buildDefaultRegistry()}, vr, val)
3411 noerr(t, err)
3412 if !cmp.Equal(got, want) {
3413 t.Errorf("Did not get correct result. got %v; want %v", got, want)
3414 }
3415 })
3416 t.Run("custom type map entry", func(t *testing.T) {
3417
3418
3419
3420 topLevelRb := NewRegistryBuilder()
3421 defaultValueEncoders.RegisterDefaultEncoders(topLevelRb)
3422 defaultValueDecoders.RegisterDefaultDecoders(topLevelRb)
3423 topLevelRb.RegisterTypeMapEntry(bsontype.Type(0), reflect.TypeOf(primitive.M{}))
3424
3425 embeddedRb := NewRegistryBuilder()
3426 defaultValueEncoders.RegisterDefaultEncoders(embeddedRb)
3427 defaultValueDecoders.RegisterDefaultDecoders(embeddedRb)
3428 embeddedRb.RegisterTypeMapEntry(bsontype.Type(0), reflect.TypeOf(primitive.M{}))
3429
3430
3431 innerDoc := bsoncore.BuildDocument(
3432 nil,
3433 bsoncore.AppendInt32Element(nil, "foo", 1),
3434 )
3435 doc := bsoncore.BuildDocument(
3436 nil,
3437 bsoncore.AppendDocumentElement(nil, "nested", innerDoc),
3438 )
3439 want := primitive.M{
3440 "nested": primitive.M{
3441 "foo": int32(1),
3442 },
3443 }
3444
3445 testCases := []struct {
3446 name string
3447 registry *Registry
3448 }{
3449 {"top level", topLevelRb.Build()},
3450 {"embedded", embeddedRb.Build()},
3451 }
3452 for _, tc := range testCases {
3453 var got interface{}
3454 vr := bsonrw.NewBSONDocumentReader(doc)
3455 val := reflect.ValueOf(&got).Elem()
3456
3457 err := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: tc.registry}, vr, val)
3458 noerr(t, err)
3459 if !cmp.Equal(got, want) {
3460 t.Fatalf("got %v, want %v", got, want)
3461 }
3462 }
3463 })
3464 t.Run("ancestor info is used over custom type map entry", func(t *testing.T) {
3465
3466
3467
3468 rb := NewRegistryBuilder()
3469 defaultValueEncoders.RegisterDefaultEncoders(rb)
3470 defaultValueDecoders.RegisterDefaultDecoders(rb)
3471 rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(primitive.M{}))
3472 reg := rb.Build()
3473
3474
3475 inner := bsoncore.BuildDocument(
3476 nil,
3477 bsoncore.AppendInt32Element(nil, "foo", 10),
3478 )
3479 doc := bsoncore.BuildDocument(
3480 nil,
3481 bsoncore.AppendDocumentElement(nil, "nested", inner),
3482 )
3483 want := primitive.D{
3484 {"nested", primitive.D{
3485 {"foo", int32(10)},
3486 }},
3487 }
3488
3489 var got primitive.D
3490 vr := bsonrw.NewBSONDocumentReader(doc)
3491 val := reflect.ValueOf(&got).Elem()
3492 err := defaultSliceCodec.DecodeValue(DecodeContext{Registry: reg}, vr, val)
3493 noerr(t, err)
3494 if !cmp.Equal(got, want) {
3495 t.Fatalf("got %v, want %v", got, want)
3496 }
3497 })
3498 })
3499
3500 t.Run("decode errors contain key information", func(t *testing.T) {
3501 decodeValueError := errors.New("decode value error")
3502 emptyInterfaceErrorDecode := func(DecodeContext, bsonrw.ValueReader, reflect.Value) error {
3503 return decodeValueError
3504 }
3505 emptyInterfaceErrorRegistry := NewRegistryBuilder().
3506 RegisterTypeDecoder(tEmpty, ValueDecoderFunc(emptyInterfaceErrorDecode)).Build()
3507
3508
3509
3510 docBytes := bsoncore.BuildDocumentFromElements(
3511 nil,
3512 bsoncore.AppendInt32Element(nil, "foo", 10),
3513 )
3514 docEmptyInterfaceErr := &DecodeError{
3515 keys: []string{"foo"},
3516 wrapped: decodeValueError,
3517 }
3518
3519
3520
3521
3522 type emptyInterfaceStruct struct {
3523 Foo interface{}
3524 }
3525 type stringStruct struct {
3526 Foo string
3527 }
3528 emptyInterfaceStructErr := &DecodeError{
3529 keys: []string{"foo"},
3530 wrapped: decodeValueError,
3531 }
3532 stringStructErr := &DecodeError{
3533 keys: []string{"foo"},
3534 wrapped: ErrNoDecoder{reflect.TypeOf("")},
3535 }
3536
3537
3538
3539 type inner3 struct{ Fourth interface{} }
3540 type inner2 struct{ Third []inner3 }
3541 type inner1 struct{ Second map[string]inner2 }
3542 type outer struct{ First inner1 }
3543 inner3EmptyDoc := buildDocument(nil)
3544 inner3Doc := buildDocument(bsoncore.AppendStringElement(nil, "fourth", "value"))
3545 inner3Array := buildArray(
3546
3547 append(
3548 bsoncore.AppendDocumentElement(nil, "0", inner3EmptyDoc),
3549 bsoncore.AppendDocumentElement(nil, "1", inner3Doc)...,
3550 ),
3551 )
3552 inner2Doc := buildDocument(bsoncore.AppendArrayElement(nil, "third", inner3Array))
3553 inner2Map := buildDocument(bsoncore.AppendDocumentElement(nil, "randomKey", inner2Doc))
3554 inner1Doc := buildDocument(bsoncore.AppendDocumentElement(nil, "second", inner2Map))
3555 outerDoc := buildDocument(bsoncore.AppendDocumentElement(nil, "first", inner1Doc))
3556
3557
3558 nestedRegistryBuilder := NewRegistryBuilder()
3559 defaultValueDecoders.RegisterDefaultDecoders(nestedRegistryBuilder)
3560 nestedRegistry := nestedRegistryBuilder.
3561 RegisterTypeDecoder(tEmpty, ValueDecoderFunc(emptyInterfaceErrorDecode)).
3562 Build()
3563 nestedErr := &DecodeError{
3564 keys: []string{"fourth", "1", "third", "randomKey", "second", "first"},
3565 wrapped: decodeValueError,
3566 }
3567
3568 testCases := []struct {
3569 name string
3570 val interface{}
3571 vr bsonrw.ValueReader
3572 registry *Registry
3573 decoder ValueDecoder
3574 err error
3575 }{
3576 {
3577
3578 "primitive.D slice",
3579 primitive.D{},
3580 bsonrw.NewBSONDocumentReader(docBytes),
3581 emptyInterfaceErrorRegistry,
3582 defaultSliceCodec,
3583 docEmptyInterfaceErr,
3584 },
3585 {
3586
3587 "string slice",
3588 []string{},
3589 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
3590 nil,
3591 defaultSliceCodec,
3592 &DecodeError{
3593 keys: []string{"0"},
3594 wrapped: errors.New("cannot decode array into a string type"),
3595 },
3596 },
3597 {
3598
3599
3600
3601 "primitive.D array",
3602 [1]primitive.E{},
3603 bsonrw.NewBSONDocumentReader(docBytes),
3604 emptyInterfaceErrorRegistry,
3605 ValueDecoderFunc(dvd.ArrayDecodeValue),
3606 docEmptyInterfaceErr,
3607 },
3608 {
3609
3610
3611
3612 "string array",
3613 [1]string{},
3614 &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
3615 nil,
3616 ValueDecoderFunc(dvd.ArrayDecodeValue),
3617 &DecodeError{
3618 keys: []string{"0"},
3619 wrapped: errors.New("cannot decode array into a string type"),
3620 },
3621 },
3622 {
3623
3624 "map",
3625 map[string]interface{}{},
3626 bsonrw.NewBSONDocumentReader(docBytes),
3627 emptyInterfaceErrorRegistry,
3628 defaultMapCodec,
3629 docEmptyInterfaceErr,
3630 },
3631 {
3632
3633 "struct - DecodeValue error",
3634 emptyInterfaceStruct{},
3635 bsonrw.NewBSONDocumentReader(docBytes),
3636 emptyInterfaceErrorRegistry,
3637 defaultTestStructCodec,
3638 emptyInterfaceStructErr,
3639 },
3640 {
3641
3642
3643
3644 "struct - no decoder found",
3645 stringStruct{},
3646 bsonrw.NewBSONDocumentReader(docBytes),
3647 NewRegistryBuilder().Build(),
3648 defaultTestStructCodec,
3649 stringStructErr,
3650 },
3651 {
3652 "deeply nested struct",
3653 outer{},
3654 bsonrw.NewBSONDocumentReader(outerDoc),
3655 nestedRegistry,
3656 defaultTestStructCodec,
3657 nestedErr,
3658 },
3659 }
3660 for _, tc := range testCases {
3661 t.Run(tc.name, func(t *testing.T) {
3662 dc := DecodeContext{Registry: tc.registry}
3663 if dc.Registry == nil {
3664 dc.Registry = buildDefaultRegistry()
3665 }
3666
3667 var val reflect.Value
3668 if rtype := reflect.TypeOf(tc.val); rtype != nil {
3669 val = reflect.New(rtype).Elem()
3670 }
3671 err := tc.decoder.DecodeValue(dc, tc.vr, val)
3672 assert.Equal(t, tc.err, err, "expected error %v, got %v", tc.err, err)
3673 })
3674 }
3675
3676 t.Run("keys are correctly reversed", func(t *testing.T) {
3677 innerBytes := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendInt32Element(nil, "bar", 10))
3678 outerBytes := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendDocumentElement(nil, "foo", innerBytes))
3679
3680 type inner struct{ Bar string }
3681 type outer struct{ Foo inner }
3682
3683 dc := DecodeContext{Registry: buildDefaultRegistry()}
3684 vr := bsonrw.NewBSONDocumentReader(outerBytes)
3685 val := reflect.New(reflect.TypeOf(outer{})).Elem()
3686 err := defaultTestStructCodec.DecodeValue(dc, vr, val)
3687
3688 var decodeErr *DecodeError
3689 assert.True(t, errors.As(err, &decodeErr), "expected DecodeError, got %v of type %T", err, err)
3690 expectedKeys := []string{"foo", "bar"}
3691 assert.Equal(t, expectedKeys, decodeErr.Keys(), "expected keys slice %v, got %v", expectedKeys,
3692 decodeErr.Keys())
3693 keyPath := strings.Join(expectedKeys, ".")
3694 assert.True(t, strings.Contains(decodeErr.Error(), keyPath),
3695 "expected error %v to contain key pattern %s", decodeErr, keyPath)
3696 })
3697 })
3698
3699 t.Run("values are converted", func(t *testing.T) {
3700
3701
3702 t.Run("D", func(t *testing.T) {
3703 trueValue := bsoncore.Value{
3704 Type: bsontype.Boolean,
3705 Data: bsoncore.AppendBoolean(nil, true),
3706 }
3707 docBytes := bsoncore.BuildDocumentFromElements(nil,
3708 bsoncore.AppendBooleanElement(nil, "bool", true),
3709 bsoncore.BuildArrayElement(nil, "boolArray", trueValue),
3710 )
3711
3712 rb := NewRegistryBuilder()
3713 defaultValueDecoders.RegisterDefaultDecoders(rb)
3714 reg := rb.RegisterTypeMapEntry(bsontype.Boolean, reflect.TypeOf(mybool(true))).Build()
3715
3716 dc := DecodeContext{Registry: reg}
3717 vr := bsonrw.NewBSONDocumentReader(docBytes)
3718 val := reflect.New(tD).Elem()
3719 err := defaultValueDecoders.DDecodeValue(dc, vr, val)
3720 assert.Nil(t, err, "DDecodeValue error: %v", err)
3721
3722 want := primitive.D{
3723 {"bool", mybool(true)},
3724 {"boolArray", primitive.A{mybool(true)}},
3725 }
3726 got := val.Interface().(primitive.D)
3727 assert.Equal(t, want, got, "want document %v, got %v", want, got)
3728 })
3729 t.Run("M", func(t *testing.T) {
3730 docBytes := bsoncore.BuildDocumentFromElements(nil,
3731 bsoncore.AppendBooleanElement(nil, "bool", true),
3732 )
3733
3734 type myMap map[string]mybool
3735 dc := DecodeContext{Registry: buildDefaultRegistry()}
3736 vr := bsonrw.NewBSONDocumentReader(docBytes)
3737 val := reflect.New(reflect.TypeOf(myMap{})).Elem()
3738 err := defaultMapCodec.DecodeValue(dc, vr, val)
3739 assert.Nil(t, err, "DecodeValue error: %v", err)
3740
3741 want := myMap{
3742 "bool": mybool(true),
3743 }
3744 got := val.Interface().(myMap)
3745 assert.Equal(t, want, got, "expected map %v, got %v", want, got)
3746 })
3747 })
3748 }
3749
3750 type testValueUnmarshaler struct {
3751 t bsontype.Type
3752 val []byte
3753 err error
3754 }
3755
3756 func (tvu *testValueUnmarshaler) UnmarshalBSONValue(t bsontype.Type, val []byte) error {
3757 tvu.t, tvu.val = t, val
3758 return tvu.err
3759 }
3760
3761 type testUnmarshaler struct {
3762 Val []byte
3763 Err error
3764 }
3765
3766 func (tvu *testUnmarshaler) UnmarshalBSON(val []byte) error {
3767 tvu.Val = val
3768 return tvu.Err
3769 }
3770
3771 func (tvu testValueUnmarshaler) Equal(tvu2 testValueUnmarshaler) bool {
3772 return tvu.t == tvu2.t && bytes.Equal(tvu.val, tvu2.val)
3773 }
3774
3775
3776 func buildDocumentArray(fn func([]byte) []byte) []byte {
3777 aix, doc := bsoncore.AppendArrayElementStart(nil, "Z")
3778 doc = fn(doc)
3779 doc, _ = bsoncore.AppendArrayEnd(doc, aix)
3780 return buildDocument(doc)
3781 }
3782
3783 func buildArray(vals []byte) []byte {
3784 aix, doc := bsoncore.AppendArrayStart(nil)
3785 doc = append(doc, vals...)
3786 doc, _ = bsoncore.AppendArrayEnd(doc, aix)
3787 return doc
3788 }
3789
3790 func appendArrayElement(dst []byte, key string, vals []byte) []byte {
3791 aix, doc := bsoncore.AppendArrayElementStart(dst, key)
3792 doc = append(doc, vals...)
3793 doc, _ = bsoncore.AppendArrayEnd(doc, aix)
3794 return doc
3795 }
3796
3797
3798 func buildDocument(elems []byte) []byte {
3799 idx, doc := bsoncore.AppendDocumentStart(nil)
3800 doc = append(doc, elems...)
3801 doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
3802 return doc
3803 }
3804
3805 func buildDefaultRegistry() *Registry {
3806 rb := NewRegistryBuilder()
3807 defaultValueEncoders.RegisterDefaultEncoders(rb)
3808 defaultValueDecoders.RegisterDefaultDecoders(rb)
3809 return rb.Build()
3810 }
3811
View as plain text