Skip to content

Commit

Permalink
GODRIVER-2348 Resolve merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
prestonvasquez committed Jun 10, 2024
2 parents c9475c7 + bfe610f commit 6d1b1ff
Show file tree
Hide file tree
Showing 118 changed files with 3,457 additions and 3,094 deletions.
13 changes: 3 additions & 10 deletions bson/bsoncodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,17 +309,10 @@ type decodeAdapter struct {
var _ ValueDecoder = decodeAdapter{}
var _ typeDecoder = decodeAdapter{}

// decodeTypeOrValue calls decoder.decodeType is decoder is a typeDecoder. Otherwise, it allocates a new element of type
// t and calls decoder.DecodeValue on it.
func decodeTypeOrValue(decoder ValueDecoder, dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
td, _ := decoder.(typeDecoder)
return decodeTypeOrValueWithInfo(decoder, td, dc, vr, t, true)
}

func decodeTypeOrValueWithInfo(vd ValueDecoder, td typeDecoder, dc DecodeContext, vr ValueReader, t reflect.Type, convert bool) (reflect.Value, error) {
if td != nil {
func decodeTypeOrValueWithInfo(vd ValueDecoder, dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
if td, _ := vd.(typeDecoder); td != nil {
val, err := td.decodeType(dc, vr, t)
if err == nil && convert && val.Type() != t {
if err == nil && val.Type() != t {
// This conversion step is necessary for slices and maps. If a user declares variables like:
//
// type myBool bool
Expand Down
156 changes: 156 additions & 0 deletions bson/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,162 @@ func TestBasicDecode(t *testing.T) {
}
}

func TestDecodingInterfaces(t *testing.T) {
t.Parallel()

type testCase struct {
name string
stub func() ([]byte, interface{}, func(*testing.T))
}
testCases := []testCase{
{
name: "struct with interface containing a concrete value",
stub: func() ([]byte, interface{}, func(*testing.T)) {
type testStruct struct {
Value interface{}
}
var value string

data := docToBytes(struct {
Value string
}{
Value: "foo",
})

receiver := testStruct{&value}

check := func(t *testing.T) {
t.Helper()
assert.Equal(t, "foo", value)
}

return data, &receiver, check
},
},
{
name: "struct with interface containing a struct",
stub: func() ([]byte, interface{}, func(*testing.T)) {
type demo struct {
Data string
}

type testStruct struct {
Value interface{}
}
var value demo

data := docToBytes(struct {
Value demo
}{
Value: demo{"foo"},
})

receiver := testStruct{&value}

check := func(t *testing.T) {
t.Helper()
assert.Equal(t, "foo", value.Data)
}

return data, &receiver, check
},
},
{
name: "struct with interface containing a slice",
stub: func() ([]byte, interface{}, func(*testing.T)) {
type testStruct struct {
Values interface{}
}
var values []string

data := docToBytes(struct {
Values []string
}{
Values: []string{"foo", "bar"},
})

receiver := testStruct{&values}

check := func(t *testing.T) {
t.Helper()
assert.Equal(t, []string{"foo", "bar"}, values)
}

return data, &receiver, check
},
},
{
name: "struct with interface containing an array",
stub: func() ([]byte, interface{}, func(*testing.T)) {
type testStruct struct {
Values interface{}
}
var values [2]string

data := docToBytes(struct {
Values []string
}{
Values: []string{"foo", "bar"},
})

receiver := testStruct{&values}

check := func(t *testing.T) {
t.Helper()
assert.Equal(t, [2]string{"foo", "bar"}, values)
}

return data, &receiver, check
},
},
{
name: "struct with interface array containing concrete values",
stub: func() ([]byte, interface{}, func(*testing.T)) {
type testStruct struct {
Values [3]interface{}
}
var str string
var i, j int

data := docToBytes(struct {
Values []interface{}
}{
Values: []interface{}{"foo", 42, nil},
})

receiver := testStruct{[3]interface{}{&str, &i, &j}}

check := func(t *testing.T) {
t.Helper()
assert.Equal(t, "foo", str)
assert.Equal(t, 42, i)
assert.Equal(t, 0, j)
assert.Equal(t, testStruct{[3]interface{}{&str, &i, nil}}, receiver)
}

return data, &receiver, check
},
},
}
for _, tc := range testCases {
tc := tc

t.Run(tc.name, func(t *testing.T) {
t.Parallel()

data, receiver, check := tc.stub()
got := reflect.ValueOf(receiver).Elem()
vr := NewValueReader(data)
reg := DefaultRegistry
decoder, err := reg.LookupDecoder(got.Type())
noerr(t, err)
err = decoder.DecodeValue(DecodeContext{Registry: reg}, vr, got)
noerr(t, err)
check(t)
})
}
}

func TestDecoderv2(t *testing.T) {
t.Parallel()

Expand Down
Loading

0 comments on commit 6d1b1ff

Please sign in to comment.