217 lines
3.9 KiB
Go
217 lines
3.9 KiB
Go
|
package reflectx
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func ival(v reflect.Value) int {
|
||
|
return v.Interface().(int)
|
||
|
}
|
||
|
|
||
|
func TestBasic(t *testing.T) {
|
||
|
type Foo struct {
|
||
|
A int
|
||
|
B int
|
||
|
C int
|
||
|
}
|
||
|
|
||
|
f := Foo{1, 2, 3}
|
||
|
fv := reflect.ValueOf(f)
|
||
|
m := NewMapper("")
|
||
|
|
||
|
v := m.FieldByName(fv, "A")
|
||
|
if ival(v) != f.A {
|
||
|
t.Errorf("Expecting %d, got %d", ival(v), f.A)
|
||
|
}
|
||
|
v = m.FieldByName(fv, "B")
|
||
|
if ival(v) != f.B {
|
||
|
t.Errorf("Expecting %d, got %d", f.B, ival(v))
|
||
|
}
|
||
|
v = m.FieldByName(fv, "C")
|
||
|
if ival(v) != f.C {
|
||
|
t.Errorf("Expecting %d, got %d", f.C, ival(v))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestEmbedded(t *testing.T) {
|
||
|
type Foo struct {
|
||
|
A int
|
||
|
}
|
||
|
|
||
|
type Bar struct {
|
||
|
Foo
|
||
|
B int
|
||
|
}
|
||
|
|
||
|
type Baz struct {
|
||
|
A int
|
||
|
Bar
|
||
|
}
|
||
|
|
||
|
m := NewMapper("")
|
||
|
|
||
|
z := Baz{}
|
||
|
z.A = 1
|
||
|
z.B = 2
|
||
|
z.Bar.Foo.A = 3
|
||
|
zv := reflect.ValueOf(z)
|
||
|
|
||
|
v := m.FieldByName(zv, "A")
|
||
|
if ival(v) != z.A {
|
||
|
t.Errorf("Expecting %d, got %d", ival(v), z.A)
|
||
|
}
|
||
|
v = m.FieldByName(zv, "B")
|
||
|
if ival(v) != z.B {
|
||
|
t.Errorf("Expecting %d, got %d", ival(v), z.B)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestMapping(t *testing.T) {
|
||
|
type Person struct {
|
||
|
ID int
|
||
|
Name string
|
||
|
WearsGlasses bool `db:"wears_glasses"`
|
||
|
}
|
||
|
|
||
|
m := NewMapperFunc("db", strings.ToLower)
|
||
|
p := Person{1, "Jason", true}
|
||
|
mapping := m.TypeMap(reflect.TypeOf(p))
|
||
|
|
||
|
for _, key := range []string{"id", "name", "wears_glasses"} {
|
||
|
if _, ok := mapping[key]; !ok {
|
||
|
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type SportsPerson struct {
|
||
|
Weight int
|
||
|
Age int
|
||
|
Person
|
||
|
}
|
||
|
s := SportsPerson{Weight: 100, Age: 30, Person: p}
|
||
|
mapping = m.TypeMap(reflect.TypeOf(s))
|
||
|
for _, key := range []string{"id", "name", "wears_glasses", "weight", "age"} {
|
||
|
if _, ok := mapping[key]; !ok {
|
||
|
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
type RugbyPlayer struct {
|
||
|
Position int
|
||
|
IsIntense bool `db:"is_intense"`
|
||
|
IsAllBlack bool `db:"-"`
|
||
|
SportsPerson
|
||
|
}
|
||
|
r := RugbyPlayer{12, true, false, s}
|
||
|
mapping = m.TypeMap(reflect.TypeOf(r))
|
||
|
for _, key := range []string{"id", "name", "wears_glasses", "weight", "age", "position", "is_intense"} {
|
||
|
if _, ok := mapping[key]; !ok {
|
||
|
t.Errorf("Expecting to find key %s in mapping but did not.", key)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if _, ok := mapping["isallblack"]; ok {
|
||
|
t.Errorf("Expecting to ignore `IsAllBlack` field")
|
||
|
}
|
||
|
|
||
|
type EmbeddedLiteral struct {
|
||
|
Embedded struct {
|
||
|
Person string
|
||
|
Position int
|
||
|
}
|
||
|
IsIntense bool
|
||
|
}
|
||
|
|
||
|
e := EmbeddedLiteral{}
|
||
|
mapping = m.TypeMap(reflect.TypeOf(e))
|
||
|
//fmt.Printf("Mapping: %#v\n", mapping)
|
||
|
|
||
|
//f := FieldByIndexes(reflect.ValueOf(e), mapping["isintense"])
|
||
|
//fmt.Println(f, f.Interface())
|
||
|
|
||
|
//tbn := m.TraversalsByName(reflect.TypeOf(e), []string{"isintense"})
|
||
|
//fmt.Printf("%#v\n", tbn)
|
||
|
|
||
|
}
|
||
|
|
||
|
type E1 struct {
|
||
|
A int
|
||
|
}
|
||
|
type E2 struct {
|
||
|
E1
|
||
|
B int
|
||
|
}
|
||
|
type E3 struct {
|
||
|
E2
|
||
|
C int
|
||
|
}
|
||
|
type E4 struct {
|
||
|
E3
|
||
|
D int
|
||
|
}
|
||
|
|
||
|
func BenchmarkFieldNameL1(b *testing.B) {
|
||
|
e4 := E4{D: 1}
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
v := reflect.ValueOf(e4)
|
||
|
f := v.FieldByName("D")
|
||
|
if f.Interface().(int) != 1 {
|
||
|
b.Fatal("Wrong value.")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFieldNameL4(b *testing.B) {
|
||
|
e4 := E4{}
|
||
|
e4.A = 1
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
v := reflect.ValueOf(e4)
|
||
|
f := v.FieldByName("A")
|
||
|
if f.Interface().(int) != 1 {
|
||
|
b.Fatal("Wrong value.")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFieldPosL1(b *testing.B) {
|
||
|
e4 := E4{D: 1}
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
v := reflect.ValueOf(e4)
|
||
|
f := v.Field(1)
|
||
|
if f.Interface().(int) != 1 {
|
||
|
b.Fatal("Wrong value.")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFieldPosL4(b *testing.B) {
|
||
|
e4 := E4{}
|
||
|
e4.A = 1
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
v := reflect.ValueOf(e4)
|
||
|
f := v.Field(0)
|
||
|
f = f.Field(0)
|
||
|
f = f.Field(0)
|
||
|
f = f.Field(0)
|
||
|
if f.Interface().(int) != 1 {
|
||
|
b.Fatal("Wrong value.")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkFieldByIndexL4(b *testing.B) {
|
||
|
e4 := E4{}
|
||
|
e4.A = 1
|
||
|
idx := []int{0, 0, 0, 0}
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
v := reflect.ValueOf(e4)
|
||
|
f := FieldByIndexes(v, idx)
|
||
|
if f.Interface().(int) != 1 {
|
||
|
b.Fatal("Wrong value.")
|
||
|
}
|
||
|
}
|
||
|
}
|