blob: 38b7c5dfb1f987e365a47234eb7408f71d60f3f6 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package coder
import (
"bytes"
"fmt"
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
)
func TestReflectionRowCoderGeneration(t *testing.T) {
num := 35
tests := []struct {
want interface{}
}{{
// Top level value check
want: UserType1{
A: "cats",
B: 24,
C: "pjamas",
},
}, {
// Top level pointer check
want: &UserType1{
A: "marmalade",
B: 24,
C: "jam",
},
}, {
// Inner pointer check.
want: UserType2{
A: "dogs",
B: &UserType1{
A: "cats",
B: 24,
C: "pjamas",
},
C: &num,
},
}, {
// nil pointer check.
want: UserType2{
A: "dogs",
B: nil,
C: nil,
},
}, {
// All zeroes
want: struct {
V00 bool
V01 byte // unsupported by spec (same as uint8)
V02 uint8 // unsupported by spec
V03 int16
// V04 uint16 // unsupported by spec
V05 int32
// V06 uint32 // unsupported by spec
V07 int64
// V08 uint64 // unsupported by spec
V09 int
V10 struct{}
V11 *struct{}
V12 [0]int
V13 [2]int
V14 []int
V15 map[string]int
V16 float32
V17 float64
V18 []byte
V19 [2]*int
V20 map[*string]*int
}{},
}, {
want: struct {
V00 bool
V01 byte // unsupported by spec (same as uint8)
V02 uint8 // unsupported by spec
V03 int16
// V04 uint16 // unsupported by spec
V05 int32
// V06 uint32 // unsupported by spec
V07 int64
// V08 uint64 // unsupported by spec
V09 int
V10 struct{}
V11 *struct{}
V12 [0]int
V13 [2]int
V14 []int
V15 map[string]int
V16 float32
V17 float64
V18 []byte
V19 [2]*int
V20 map[string]*int
V21 []*int
}{
V00: true,
V01: 1,
V02: 2,
V03: 3,
V05: 5,
V07: 7,
V09: 9,
V10: struct{}{},
V11: &struct{}{},
V12: [0]int{},
V13: [2]int{72, 908},
V14: []int{12, 9326, 641346, 6},
V15: map[string]int{"pants": 42},
V16: 3.14169,
V17: 2.6e100,
V18: []byte{21, 17, 65, 255, 0, 16},
V19: [2]*int{nil, &num},
V20: map[string]*int{
"notnil": &num,
"nil": nil,
},
V21: []*int{nil, &num, nil},
},
// TODO add custom types such as protocol buffers.
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%+v", test.want), func(t *testing.T) {
rt := reflect.TypeOf(test.want)
enc, err := RowEncoderForStruct(rt)
if err != nil {
t.Fatalf("RowEncoderForStruct(%v) = %v, want nil error", rt, err)
}
var buf bytes.Buffer
if err := enc(test.want, &buf); err != nil {
t.Fatalf("enc(%v) = err, want nil error", err)
}
dec, err := RowDecoderForStruct(rt)
if err != nil {
t.Fatalf("RowDecoderForStruct(%v) = %v, want nil error", rt, err)
}
b := buf.Bytes()
r := bytes.NewBuffer(b)
got, err := dec(r)
if err != nil {
t.Fatalf("RowDecoderForStruct(%v) = %v, want nil error", rt, err)
}
if d := cmp.Diff(test.want, got); d != "" {
t.Fatalf("dec(enc(%v)) = %v\ndiff (-want, +got): %v", test.want, got, d)
}
})
}
}
type UserType1 struct {
A string
B int
C string
}
type UserType2 struct {
A string
B *UserType1
C *int
}