Copied mongo repo (to patch it)
This commit is contained in:
910
mongo/x/bsonx/primitive_codecs_test.go
Normal file
910
mongo/x/bsonx/primitive_codecs_test.go
Normal file
@@ -0,0 +1,910 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user