911 lines
32 KiB
Go
911 lines
32 KiB
Go
// Copyright (C) MongoDB, Inc. 2022-present.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
// not use this file except in compliance with the License. You may obtain
|
|
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
package bsonx
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
|
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
|
"go.mongodb.org/mongo-driver/bson/bsonrw/bsonrwtest"
|
|
"go.mongodb.org/mongo-driver/bson/bsontype"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
|
|
)
|
|
|
|
func TestDefaultValueEncoders(t *testing.T) {
|
|
var pcx PrimitiveCodecs
|
|
|
|
var wrong = func(string, string) string { return "wrong" }
|
|
|
|
type subtest struct {
|
|
name string
|
|
val interface{}
|
|
ectx *bsoncodec.EncodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
invoke bsonrwtest.Invoked
|
|
err error
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
ve bsoncodec.ValueEncoder
|
|
subtests []subtest
|
|
}{
|
|
{
|
|
"ValueEncodeValue",
|
|
bsoncodec.ValueEncoderFunc(pcx.ValueEncodeValue),
|
|
[]subtest{
|
|
{
|
|
"wrong type",
|
|
wrong,
|
|
nil,
|
|
nil,
|
|
bsonrwtest.Nothing,
|
|
bsoncodec.ValueEncoderError{Name: "ValueEncodeValue", Types: []reflect.Type{tValue}, Received: reflect.ValueOf(wrong)},
|
|
},
|
|
{"empty value", Val{}, nil, nil, bsonrwtest.WriteNull, nil},
|
|
{
|
|
"success",
|
|
Null(),
|
|
&bsoncodec.EncodeContext{Registry: DefaultRegistry},
|
|
&bsonrwtest.ValueReaderWriter{},
|
|
bsonrwtest.WriteNull,
|
|
nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"ElementSliceEncodeValue",
|
|
bsoncodec.ValueEncoderFunc(pcx.ElementSliceEncodeValue),
|
|
[]subtest{
|
|
{
|
|
"wrong type",
|
|
wrong,
|
|
nil,
|
|
nil,
|
|
bsonrwtest.Nothing,
|
|
bsoncodec.ValueEncoderError{
|
|
Name: "ElementSliceEncodeValue",
|
|
Types: []reflect.Type{tElementSlice},
|
|
Received: reflect.ValueOf(wrong),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"ArrayEncodeValue",
|
|
bsoncodec.ValueEncoderFunc(pcx.ArrayEncodeValue),
|
|
[]subtest{
|
|
{
|
|
"wrong type",
|
|
wrong,
|
|
nil,
|
|
nil,
|
|
bsonrwtest.Nothing,
|
|
bsoncodec.ValueEncoderError{Name: "ArrayEncodeValue", Types: []reflect.Type{tArray}, Received: reflect.ValueOf(wrong)},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
for _, subtest := range tc.subtests {
|
|
t.Run(subtest.name, func(t *testing.T) {
|
|
var ec bsoncodec.EncodeContext
|
|
if subtest.ectx != nil {
|
|
ec = *subtest.ectx
|
|
}
|
|
llvrw := new(bsonrwtest.ValueReaderWriter)
|
|
if subtest.llvrw != nil {
|
|
llvrw = subtest.llvrw
|
|
}
|
|
llvrw.T = t
|
|
err := tc.ve.EncodeValue(ec, llvrw, reflect.ValueOf(subtest.val))
|
|
if !compareErrors(err, subtest.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, subtest.err)
|
|
}
|
|
invoked := llvrw.Invoked
|
|
if !cmp.Equal(invoked, subtest.invoke) {
|
|
t.Errorf("Incorrect method invoked. got %v; want %v", invoked, subtest.invoke)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("DocumentEncodeValue", func(t *testing.T) {
|
|
t.Run("ValueEncoderError", func(t *testing.T) {
|
|
val := reflect.ValueOf(bool(true))
|
|
want := bsoncodec.ValueEncoderError{Name: "DocumentEncodeValue", Types: []reflect.Type{tDocument}, Received: val}
|
|
got := (PrimitiveCodecs{}).DocumentEncodeValue(bsoncodec.EncodeContext{}, nil, val)
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("WriteDocument Error", func(t *testing.T) {
|
|
want := errors.New("WriteDocument Error")
|
|
llvrw := &bsonrwtest.ValueReaderWriter{
|
|
T: t,
|
|
Err: want,
|
|
ErrAfter: bsonrwtest.WriteDocument,
|
|
}
|
|
got := (PrimitiveCodecs{}).DocumentEncodeValue(bsoncodec.EncodeContext{}, llvrw, reflect.MakeSlice(tDocument, 0, 0))
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("encodeDocument errors", func(t *testing.T) {
|
|
ec := bsoncodec.EncodeContext{}
|
|
err := errors.New("encodeDocument error")
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
testCases := []struct {
|
|
name string
|
|
ec bsoncodec.EncodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
doc Doc
|
|
err error
|
|
}{
|
|
{
|
|
"WriteDocumentElement",
|
|
ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: errors.New("wde error"), ErrAfter: bsonrwtest.WriteDocumentElement},
|
|
Doc{{"foo", Null()}},
|
|
errors.New("wde error"),
|
|
},
|
|
{
|
|
"WriteDouble", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDouble},
|
|
Doc{{"foo", Double(3.14159)}}, err,
|
|
},
|
|
{
|
|
"WriteString", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteString},
|
|
Doc{{"foo", String("bar")}}, err,
|
|
},
|
|
{
|
|
"WriteDocument (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t},
|
|
Doc{{"foo", Document(Doc{{"bar", Null()}})}},
|
|
bsoncodec.ErrNoEncoder{Type: tDocument},
|
|
},
|
|
{
|
|
"WriteArray (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t},
|
|
Doc{{"foo", Array(Arr{Null()})}},
|
|
bsoncodec.ErrNoEncoder{Type: tArray},
|
|
},
|
|
{
|
|
"WriteBinary", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteBinaryWithSubtype},
|
|
Doc{{"foo", Binary(0xFF, []byte{0x01, 0x02, 0x03})}}, err,
|
|
},
|
|
{
|
|
"WriteUndefined", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteUndefined},
|
|
Doc{{"foo", Undefined()}}, err,
|
|
},
|
|
{
|
|
"WriteObjectID", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteObjectID},
|
|
Doc{{"foo", ObjectID(oid)}}, err,
|
|
},
|
|
{
|
|
"WriteBoolean", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteBoolean},
|
|
Doc{{"foo", Boolean(true)}}, err,
|
|
},
|
|
{
|
|
"WriteDateTime", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDateTime},
|
|
Doc{{"foo", DateTime(1234567890)}}, err,
|
|
},
|
|
{
|
|
"WriteNull", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteNull},
|
|
Doc{{"foo", Null()}}, err,
|
|
},
|
|
{
|
|
"WriteRegex", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteRegex},
|
|
Doc{{"foo", Regex("bar", "baz")}}, err,
|
|
},
|
|
{
|
|
"WriteDBPointer", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDBPointer},
|
|
Doc{{"foo", DBPointer("bar", oid)}}, err,
|
|
},
|
|
{
|
|
"WriteJavascript", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteJavascript},
|
|
Doc{{"foo", JavaScript("var hello = 'world';")}}, err,
|
|
},
|
|
{
|
|
"WriteSymbol", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteSymbol},
|
|
Doc{{"foo", Symbol("symbolbaz")}}, err,
|
|
},
|
|
{
|
|
"WriteCodeWithScope (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteCodeWithScope},
|
|
Doc{{"foo", CodeWithScope("var hello = 'world';", Doc{}.Append("bar", Null()))}},
|
|
err,
|
|
},
|
|
{
|
|
"WriteInt32", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteInt32},
|
|
Doc{{"foo", Int32(12345)}}, err,
|
|
},
|
|
{
|
|
"WriteInt64", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteInt64},
|
|
Doc{{"foo", Int64(1234567890)}}, err,
|
|
},
|
|
{
|
|
"WriteTimestamp", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteTimestamp},
|
|
Doc{{"foo", Timestamp(10, 20)}}, err,
|
|
},
|
|
{
|
|
"WriteDecimal128", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDecimal128},
|
|
Doc{{"foo", Decimal128(primitive.NewDecimal128(10, 20))}}, err,
|
|
},
|
|
{
|
|
"WriteMinKey", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteMinKey},
|
|
Doc{{"foo", MinKey()}}, err,
|
|
},
|
|
{
|
|
"WriteMaxKey", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteMaxKey},
|
|
Doc{{"foo", MaxKey()}}, err,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := (PrimitiveCodecs{}).DocumentEncodeValue(tc.ec, tc.llvrw, reflect.ValueOf(tc.doc))
|
|
if !compareErrors(err, tc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, tc.err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
d128 := primitive.NewDecimal128(10, 20)
|
|
want := Doc{
|
|
{"a", Double(3.14159)}, {"b", String("foo")},
|
|
{"c", Document(Doc{{"aa", Null()}})}, {"d", Array(Arr{Null()})},
|
|
{"e", Binary(0xFF, []byte{0x01, 0x02, 0x03})}, {"f", Undefined()},
|
|
{"g", ObjectID(oid)}, {"h", Boolean(true)},
|
|
{"i", DateTime(1234567890)}, {"j", Null()},
|
|
{"k", Regex("foo", "abr")},
|
|
{"l", DBPointer("foobar", oid)}, {"m", JavaScript("var hello = 'world';")},
|
|
{"n", Symbol("bazqux")},
|
|
{"o", CodeWithScope("var hello = 'world';", Doc{{"ab", Null()}})},
|
|
{"p", Int32(12345)},
|
|
{"q", Timestamp(10, 20)}, {"r", Int64(1234567890)}, {"s", Decimal128(d128)}, {"t", MinKey()}, {"u", MaxKey()},
|
|
}
|
|
slc := make(bsonrw.SliceWriter, 0, 128)
|
|
vw, err := bsonrw.NewBSONValueWriter(&slc)
|
|
noerr(t, err)
|
|
|
|
ec := bsoncodec.EncodeContext{Registry: DefaultRegistry}
|
|
err = (PrimitiveCodecs{}).DocumentEncodeValue(ec, vw, reflect.ValueOf(want))
|
|
noerr(t, err)
|
|
got, err := ReadDoc(slc)
|
|
noerr(t, err)
|
|
if !got.Equal(want) {
|
|
t.Error("Documents do not match")
|
|
t.Errorf("\ngot :%v\nwant:%v", got, want)
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("ArrayEncodeValue", func(t *testing.T) {
|
|
t.Run("CodecEncodeError", func(t *testing.T) {
|
|
val := reflect.ValueOf(bool(true))
|
|
want := bsoncodec.ValueEncoderError{Name: "ArrayEncodeValue", Types: []reflect.Type{tArray}, Received: val}
|
|
got := (PrimitiveCodecs{}).ArrayEncodeValue(bsoncodec.EncodeContext{}, nil, val)
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("WriteArray Error", func(t *testing.T) {
|
|
want := errors.New("WriteArray Error")
|
|
llvrw := &bsonrwtest.ValueReaderWriter{
|
|
T: t,
|
|
Err: want,
|
|
ErrAfter: bsonrwtest.WriteArray,
|
|
}
|
|
got := (PrimitiveCodecs{}).ArrayEncodeValue(bsoncodec.EncodeContext{}, llvrw, reflect.MakeSlice(tArray, 0, 0))
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("encode array errors", func(t *testing.T) {
|
|
ec := bsoncodec.EncodeContext{}
|
|
err := errors.New("encode array error")
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
testCases := []struct {
|
|
name string
|
|
ec bsoncodec.EncodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
arr Arr
|
|
err error
|
|
}{
|
|
{
|
|
"WriteDocumentElement",
|
|
ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: errors.New("wde error"), ErrAfter: bsonrwtest.WriteArrayElement},
|
|
Arr{Null()},
|
|
errors.New("wde error"),
|
|
},
|
|
{
|
|
"WriteDouble", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDouble},
|
|
Arr{Double(3.14159)}, err,
|
|
},
|
|
{
|
|
"WriteString", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteString},
|
|
Arr{String("bar")}, err,
|
|
},
|
|
{
|
|
"WriteDocument (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t},
|
|
Arr{Document(Doc{{"bar", Null()}})},
|
|
bsoncodec.ErrNoEncoder{Type: tDocument},
|
|
},
|
|
{
|
|
"WriteArray (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t},
|
|
Arr{Array(Arr{Null()})},
|
|
bsoncodec.ErrNoEncoder{Type: tArray},
|
|
},
|
|
{
|
|
"WriteBinary", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteBinaryWithSubtype},
|
|
Arr{Binary(0xFF, []byte{0x01, 0x02, 0x03})}, err,
|
|
},
|
|
{
|
|
"WriteUndefined", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteUndefined},
|
|
Arr{Undefined()}, err,
|
|
},
|
|
{
|
|
"WriteObjectID", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteObjectID},
|
|
Arr{ObjectID(oid)}, err,
|
|
},
|
|
{
|
|
"WriteBoolean", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteBoolean},
|
|
Arr{Boolean(true)}, err,
|
|
},
|
|
{
|
|
"WriteDateTime", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDateTime},
|
|
Arr{DateTime(1234567890)}, err,
|
|
},
|
|
{
|
|
"WriteNull", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteNull},
|
|
Arr{Null()}, err,
|
|
},
|
|
{
|
|
"WriteRegex", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteRegex},
|
|
Arr{Regex("bar", "baz")}, err,
|
|
},
|
|
{
|
|
"WriteDBPointer", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDBPointer},
|
|
Arr{DBPointer("bar", oid)}, err,
|
|
},
|
|
{
|
|
"WriteJavascript", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteJavascript},
|
|
Arr{JavaScript("var hello = 'world';")}, err,
|
|
},
|
|
{
|
|
"WriteSymbol", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteSymbol},
|
|
Arr{Symbol("symbolbaz")}, err,
|
|
},
|
|
{
|
|
"WriteCodeWithScope (Lookup)", bsoncodec.EncodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteCodeWithScope},
|
|
Arr{CodeWithScope("var hello = 'world';", Doc{{"bar", Null()}})},
|
|
err,
|
|
},
|
|
{
|
|
"WriteInt32", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteInt32},
|
|
Arr{Int32(12345)}, err,
|
|
},
|
|
{
|
|
"WriteInt64", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteInt64},
|
|
Arr{Int64(1234567890)}, err,
|
|
},
|
|
{
|
|
"WriteTimestamp", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteTimestamp},
|
|
Arr{Timestamp(10, 20)}, err,
|
|
},
|
|
{
|
|
"WriteDecimal128", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteDecimal128},
|
|
Arr{Decimal128(primitive.NewDecimal128(10, 20))}, err,
|
|
},
|
|
{
|
|
"WriteMinKey", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteMinKey},
|
|
Arr{MinKey()}, err,
|
|
},
|
|
{
|
|
"WriteMaxKey", ec,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.WriteMaxKey},
|
|
Arr{MaxKey()}, err,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := (PrimitiveCodecs{}).ArrayEncodeValue(tc.ec, tc.llvrw, reflect.ValueOf(tc.arr))
|
|
if !compareErrors(err, tc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, tc.err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
d128 := primitive.NewDecimal128(10, 20)
|
|
want := Arr{
|
|
Double(3.14159), String("foo"), Document(Doc{{"aa", Null()}}),
|
|
Array(Arr{Null()}),
|
|
Binary(0xFF, []byte{0x01, 0x02, 0x03}), Undefined(),
|
|
ObjectID(oid), Boolean(true), DateTime(1234567890), Null(), Regex("foo", "abr"),
|
|
DBPointer("foobar", oid), JavaScript("var hello = 'world';"), Symbol("bazqux"),
|
|
CodeWithScope("var hello = 'world';", Doc{{"ab", Null()}}), Int32(12345),
|
|
Timestamp(10, 20), Int64(1234567890), Decimal128(d128), MinKey(), MaxKey(),
|
|
}
|
|
|
|
ec := bsoncodec.EncodeContext{Registry: DefaultRegistry}
|
|
|
|
slc := make(bsonrw.SliceWriter, 0, 128)
|
|
vw, err := bsonrw.NewBSONValueWriter(&slc)
|
|
noerr(t, err)
|
|
|
|
dr, err := vw.WriteDocument()
|
|
noerr(t, err)
|
|
vr, err := dr.WriteDocumentElement("foo")
|
|
noerr(t, err)
|
|
|
|
err = (PrimitiveCodecs{}).ArrayEncodeValue(ec, vr, reflect.ValueOf(want))
|
|
noerr(t, err)
|
|
|
|
err = dr.WriteDocumentEnd()
|
|
noerr(t, err)
|
|
|
|
val, err := bsoncore.Document(slc).LookupErr("foo")
|
|
noerr(t, err)
|
|
rgot := val.Array()
|
|
doc, err := ReadDoc(rgot)
|
|
noerr(t, err)
|
|
got := make(Arr, 0)
|
|
for _, elem := range doc {
|
|
got = append(got, elem.Value)
|
|
}
|
|
if !got.Equal(want) {
|
|
t.Error("Documents do not match")
|
|
t.Errorf("\ngot :%v\nwant:%v", got, want)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestDefaultValueDecoders(t *testing.T) {
|
|
var pcx PrimitiveCodecs
|
|
|
|
var wrong = func(string, string) string { return "wrong" }
|
|
|
|
const cansetreflectiontest = "cansetreflectiontest"
|
|
|
|
type subtest struct {
|
|
name string
|
|
val interface{}
|
|
dctx *bsoncodec.DecodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
invoke bsonrwtest.Invoked
|
|
err error
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
vd bsoncodec.ValueDecoder
|
|
subtests []subtest
|
|
}{
|
|
{
|
|
"ValueDecodeValue",
|
|
bsoncodec.ValueDecoderFunc(pcx.ValueDecodeValue),
|
|
[]subtest{
|
|
{
|
|
"wrong type",
|
|
wrong,
|
|
nil,
|
|
nil,
|
|
bsonrwtest.Nothing,
|
|
bsoncodec.ValueDecoderError{
|
|
Name: "ValueDecodeValue",
|
|
Types: []reflect.Type{tValue},
|
|
Received: reflect.ValueOf(wrong),
|
|
},
|
|
},
|
|
{
|
|
"invalid value",
|
|
(*Val)(nil),
|
|
nil,
|
|
nil,
|
|
bsonrwtest.Nothing,
|
|
bsoncodec.ValueDecoderError{
|
|
Name: "ValueDecodeValue",
|
|
Types: []reflect.Type{tValue},
|
|
Received: reflect.ValueOf((*Val)(nil)),
|
|
},
|
|
},
|
|
{
|
|
"success",
|
|
Double(3.14159),
|
|
&bsoncodec.DecodeContext{Registry: NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
|
|
bsonrwtest.ReadDouble,
|
|
nil,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
for _, rc := range tc.subtests {
|
|
t.Run(rc.name, func(t *testing.T) {
|
|
var dc bsoncodec.DecodeContext
|
|
if rc.dctx != nil {
|
|
dc = *rc.dctx
|
|
}
|
|
llvrw := new(bsonrwtest.ValueReaderWriter)
|
|
if rc.llvrw != nil {
|
|
llvrw = rc.llvrw
|
|
}
|
|
llvrw.T = t
|
|
// var got interface{}
|
|
if rc.val == cansetreflectiontest { // We're doing a CanSet reflection test
|
|
err := tc.vd.DecodeValue(dc, llvrw, reflect.Value{})
|
|
if !compareErrors(err, rc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
|
|
}
|
|
|
|
val := reflect.New(reflect.TypeOf(rc.val)).Elem()
|
|
err = tc.vd.DecodeValue(dc, llvrw, val)
|
|
if !compareErrors(err, rc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
|
|
}
|
|
return
|
|
}
|
|
var val reflect.Value
|
|
if rtype := reflect.TypeOf(rc.val); rtype != nil {
|
|
val = reflect.New(rtype).Elem()
|
|
}
|
|
want := rc.val
|
|
defer func() {
|
|
if err := recover(); err != nil {
|
|
fmt.Println(t.Name())
|
|
panic(err)
|
|
}
|
|
}()
|
|
err := tc.vd.DecodeValue(dc, llvrw, val)
|
|
if !compareErrors(err, rc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
|
|
}
|
|
invoked := llvrw.Invoked
|
|
if !cmp.Equal(invoked, rc.invoke) {
|
|
t.Errorf("Incorrect method invoked. got %v; want %v", invoked, rc.invoke)
|
|
}
|
|
var got interface{}
|
|
if val.IsValid() && val.CanInterface() {
|
|
got = val.Interface()
|
|
}
|
|
if rc.err == nil && !cmp.Equal(got, want, cmp.Comparer(compareValues)) {
|
|
t.Errorf("Values do not match. got (%T)%v; want (%T)%v", got, got, want, want)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("DocumentDecodeValue", func(t *testing.T) {
|
|
t.Run("CodecDecodeError", func(t *testing.T) {
|
|
val := reflect.New(reflect.TypeOf(false)).Elem()
|
|
want := bsoncodec.ValueDecoderError{Name: "DocumentDecodeValue", Types: []reflect.Type{tDocument}, Received: val}
|
|
got := pcx.DocumentDecodeValue(bsoncodec.DecodeContext{}, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.EmbeddedDocument}, val)
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("ReadDocument Error", func(t *testing.T) {
|
|
want := errors.New("ReadDocument Error")
|
|
llvrw := &bsonrwtest.ValueReaderWriter{
|
|
T: t,
|
|
Err: want,
|
|
ErrAfter: bsonrwtest.ReadDocument,
|
|
BSONType: bsontype.EmbeddedDocument,
|
|
}
|
|
got := pcx.DocumentDecodeValue(bsoncodec.DecodeContext{}, llvrw, reflect.New(reflect.TypeOf(Doc{})).Elem())
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("decodeDocument errors", func(t *testing.T) {
|
|
dc := bsoncodec.DecodeContext{}
|
|
err := errors.New("decodeDocument error")
|
|
testCases := []struct {
|
|
name string
|
|
dc bsoncodec.DecodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
err error
|
|
}{
|
|
{
|
|
"ReadElement",
|
|
dc,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: errors.New("re error"), ErrAfter: bsonrwtest.ReadElement},
|
|
errors.New("re error"),
|
|
},
|
|
{"ReadDouble", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDouble, BSONType: bsontype.Double}, err},
|
|
{"ReadString", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadString, BSONType: bsontype.String}, err},
|
|
{"ReadBinary", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadBinary, BSONType: bsontype.Binary}, err},
|
|
{"ReadUndefined", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadUndefined, BSONType: bsontype.Undefined}, err},
|
|
{"ReadObjectID", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadObjectID, BSONType: bsontype.ObjectID}, err},
|
|
{"ReadBoolean", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadBoolean, BSONType: bsontype.Boolean}, err},
|
|
{"ReadDateTime", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDateTime, BSONType: bsontype.DateTime}, err},
|
|
{"ReadNull", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadNull, BSONType: bsontype.Null}, err},
|
|
{"ReadRegex", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadRegex, BSONType: bsontype.Regex}, err},
|
|
{"ReadDBPointer", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDBPointer, BSONType: bsontype.DBPointer}, err},
|
|
{"ReadJavascript", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadJavascript, BSONType: bsontype.JavaScript}, err},
|
|
{"ReadSymbol", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadSymbol, BSONType: bsontype.Symbol}, err},
|
|
{
|
|
"ReadCodeWithScope (Lookup)", bsoncodec.DecodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadCodeWithScope, BSONType: bsontype.CodeWithScope},
|
|
err,
|
|
},
|
|
{"ReadInt32", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadInt32, BSONType: bsontype.Int32}, err},
|
|
{"ReadInt64", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadInt64, BSONType: bsontype.Int64}, err},
|
|
{"ReadTimestamp", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadTimestamp, BSONType: bsontype.Timestamp}, err},
|
|
{"ReadDecimal128", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDecimal128, BSONType: bsontype.Decimal128}, err},
|
|
{"ReadMinKey", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadMinKey, BSONType: bsontype.MinKey}, err},
|
|
{"ReadMaxKey", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadMaxKey, BSONType: bsontype.MaxKey}, err},
|
|
{"Invalid Type", dc, &bsonrwtest.ValueReaderWriter{T: t, BSONType: bsontype.Type(0)}, fmt.Errorf("Cannot read unknown BSON type %s", bsontype.Type(0))},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := pcx.DecodeDocument(tc.dc, tc.llvrw, new(Doc))
|
|
if !compareErrors(err, tc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, tc.err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
d128 := primitive.NewDecimal128(10, 20)
|
|
want := Doc{
|
|
{"a", Double(3.14159)}, {"b", String("foo")},
|
|
{"c", Document(Doc{{"aa", Null()}})},
|
|
{"d", Array(Arr{Null()})},
|
|
{"e", Binary(0xFF, []byte{0x01, 0x02, 0x03})}, {"f", Undefined()},
|
|
{"g", ObjectID(oid)}, {"h", Boolean(true)},
|
|
{"i", DateTime(1234567890)}, {"j", Null()}, {"k", Regex("foo", "bar")},
|
|
{"l", DBPointer("foobar", oid)}, {"m", JavaScript("var hello = 'world';")},
|
|
{"n", Symbol("bazqux")},
|
|
{"o", CodeWithScope("var hello = 'world';", Doc{{"ab", Null()}})},
|
|
{"p", Int32(12345)},
|
|
{"q", Timestamp(10, 20)}, {"r", Int64(1234567890)},
|
|
{"s", Decimal128(d128)}, {"t", MinKey()}, {"u", MaxKey()},
|
|
}
|
|
got := reflect.New(reflect.TypeOf(Doc{})).Elem()
|
|
dc := bsoncodec.DecodeContext{Registry: NewRegistryBuilder().Build()}
|
|
b, err := want.MarshalBSON()
|
|
noerr(t, err)
|
|
err = pcx.DocumentDecodeValue(dc, bsonrw.NewBSONDocumentReader(b), got)
|
|
noerr(t, err)
|
|
if !got.Interface().(Doc).Equal(want) {
|
|
t.Error("Documents do not match")
|
|
t.Errorf("\ngot :%v\nwant:%v", got, want)
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("ArrayDecodeValue", func(t *testing.T) {
|
|
t.Run("CodecDecodeError", func(t *testing.T) {
|
|
val := reflect.New(reflect.TypeOf(false)).Elem()
|
|
want := bsoncodec.ValueDecoderError{Name: "ArrayDecodeValue", Types: []reflect.Type{tArray}, Received: val}
|
|
got := pcx.ArrayDecodeValue(bsoncodec.DecodeContext{}, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array}, val)
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("ReadArray Error", func(t *testing.T) {
|
|
want := errors.New("ReadArray Error")
|
|
llvrw := &bsonrwtest.ValueReaderWriter{
|
|
T: t,
|
|
Err: want,
|
|
ErrAfter: bsonrwtest.ReadArray,
|
|
BSONType: bsontype.Array,
|
|
}
|
|
got := pcx.ArrayDecodeValue(bsoncodec.DecodeContext{}, llvrw, reflect.New(tArray).Elem())
|
|
if !compareErrors(got, want) {
|
|
t.Errorf("Errors do not match. got %v; want %v", got, want)
|
|
}
|
|
})
|
|
t.Run("decode array errors", func(t *testing.T) {
|
|
dc := bsoncodec.DecodeContext{}
|
|
err := errors.New("decode array error")
|
|
testCases := []struct {
|
|
name string
|
|
dc bsoncodec.DecodeContext
|
|
llvrw *bsonrwtest.ValueReaderWriter
|
|
err error
|
|
}{
|
|
{
|
|
"ReadValue",
|
|
dc,
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: errors.New("re error"), ErrAfter: bsonrwtest.ReadValue},
|
|
errors.New("re error"),
|
|
},
|
|
{"ReadDouble", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDouble, BSONType: bsontype.Double}, err},
|
|
{"ReadString", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadString, BSONType: bsontype.String}, err},
|
|
{"ReadBinary", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadBinary, BSONType: bsontype.Binary}, err},
|
|
{"ReadUndefined", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadUndefined, BSONType: bsontype.Undefined}, err},
|
|
{"ReadObjectID", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadObjectID, BSONType: bsontype.ObjectID}, err},
|
|
{"ReadBoolean", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadBoolean, BSONType: bsontype.Boolean}, err},
|
|
{"ReadDateTime", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDateTime, BSONType: bsontype.DateTime}, err},
|
|
{"ReadNull", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadNull, BSONType: bsontype.Null}, err},
|
|
{"ReadRegex", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadRegex, BSONType: bsontype.Regex}, err},
|
|
{"ReadDBPointer", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDBPointer, BSONType: bsontype.DBPointer}, err},
|
|
{"ReadJavascript", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadJavascript, BSONType: bsontype.JavaScript}, err},
|
|
{"ReadSymbol", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadSymbol, BSONType: bsontype.Symbol}, err},
|
|
{
|
|
"ReadCodeWithScope (Lookup)", bsoncodec.DecodeContext{Registry: bsoncodec.NewRegistryBuilder().Build()},
|
|
&bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadCodeWithScope, BSONType: bsontype.CodeWithScope},
|
|
err,
|
|
},
|
|
{"ReadInt32", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadInt32, BSONType: bsontype.Int32}, err},
|
|
{"ReadInt64", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadInt64, BSONType: bsontype.Int64}, err},
|
|
{"ReadTimestamp", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadTimestamp, BSONType: bsontype.Timestamp}, err},
|
|
{"ReadDecimal128", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadDecimal128, BSONType: bsontype.Decimal128}, err},
|
|
{"ReadMinKey", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadMinKey, BSONType: bsontype.MinKey}, err},
|
|
{"ReadMaxKey", dc, &bsonrwtest.ValueReaderWriter{T: t, Err: err, ErrAfter: bsonrwtest.ReadMaxKey, BSONType: bsontype.MaxKey}, err},
|
|
{"Invalid Type", dc, &bsonrwtest.ValueReaderWriter{T: t, BSONType: bsontype.Type(0)}, fmt.Errorf("Cannot read unknown BSON type %s", bsontype.Type(0))},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := pcx.ArrayDecodeValue(tc.dc, tc.llvrw, reflect.New(tArray).Elem())
|
|
if !compareErrors(err, tc.err) {
|
|
t.Errorf("Errors do not match. got %v; want %v", err, tc.err)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
oid := primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}
|
|
d128 := primitive.NewDecimal128(10, 20)
|
|
want := Arr{
|
|
Double(3.14159), String("foo"), Document(Doc{{"aa", Null()}}),
|
|
Array(Arr{Null()}),
|
|
Binary(0xFF, []byte{0x01, 0x02, 0x03}), Undefined(),
|
|
ObjectID(oid), Boolean(true), DateTime(1234567890), Null(), Regex("foo", "bar"),
|
|
DBPointer("foobar", oid), JavaScript("var hello = 'world';"), Symbol("bazqux"),
|
|
CodeWithScope("var hello = 'world';", Doc{{"ab", Null()}}), Int32(12345),
|
|
Timestamp(10, 20), Int64(1234567890), Decimal128(d128), MinKey(), MaxKey(),
|
|
}
|
|
dc := bsoncodec.DecodeContext{Registry: NewRegistryBuilder().Build()}
|
|
|
|
b, err := Doc{{"", Array(want)}}.MarshalBSON()
|
|
noerr(t, err)
|
|
dvr := bsonrw.NewBSONDocumentReader(b)
|
|
dr, err := dvr.ReadDocument()
|
|
noerr(t, err)
|
|
_, vr, err := dr.ReadElement()
|
|
noerr(t, err)
|
|
|
|
val := reflect.New(tArray).Elem()
|
|
err = pcx.ArrayDecodeValue(dc, vr, val)
|
|
noerr(t, err)
|
|
got := val.Interface().(Arr)
|
|
if !got.Equal(want) {
|
|
t.Error("Documents do not match")
|
|
t.Errorf("\ngot :%v\nwant:%v", got, want)
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("success path", func(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
value interface{}
|
|
b []byte
|
|
err error
|
|
}{
|
|
{
|
|
"map[string][]Element",
|
|
map[string][]Elem{"Z": {{"A", Int32(1)}, {"B", Int32(2)}, {"EC", Int32(3)}}},
|
|
docToBytes(Doc{{"Z", Document(Doc{{"A", Int32(1)}, {"B", Int32(2)}, {"EC", Int32(3)}})}}),
|
|
nil,
|
|
},
|
|
{
|
|
"map[string][]Value",
|
|
map[string][]Val{"Z": {Int32(1), Int32(2), Int32(3)}},
|
|
docToBytes(Doc{{"Z", Array(Arr{Int32(1), Int32(2), Int32(3)})}}),
|
|
nil,
|
|
},
|
|
{
|
|
"map[string]*Document",
|
|
map[string]Doc{"Z": {{"foo", Null()}}},
|
|
docToBytes(Doc{{"Z", Document(Doc{{"foo", Null()}})}}),
|
|
nil,
|
|
},
|
|
}
|
|
|
|
t.Run("Decode", func(t *testing.T) {
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
vr := bsonrw.NewBSONDocumentReader(tc.b)
|
|
dec, err := bson.NewDecoderWithContext(bsoncodec.DecodeContext{Registry: DefaultRegistry}, vr)
|
|
noerr(t, err)
|
|
gotVal := reflect.New(reflect.TypeOf(tc.value))
|
|
err = dec.Decode(gotVal.Interface())
|
|
noerr(t, err)
|
|
got := gotVal.Elem().Interface()
|
|
want := tc.value
|
|
if diff := cmp.Diff(
|
|
got, want,
|
|
); diff != "" {
|
|
t.Errorf("difference:\n%s", diff)
|
|
t.Errorf("Values are not equal.\ngot: %#v\nwant:%#v", got, want)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
func compareValues(v1, v2 Val) bool { return v1.Equal(v2) }
|
|
|
|
func docToBytes(d Doc) []byte {
|
|
b, err := d.MarshalBSON()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return b
|
|
}
|