github.com/goki/ki@v1.1.11/kit/embeds_test.go (about) 1 // Copyright (c) 2018, The GoKi Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package kit 6 7 import ( 8 "fmt" 9 "reflect" 10 "testing" 11 ) 12 13 type A struct { 14 Mbr1 string 15 Mbr2 int 16 } 17 18 type AIf interface { 19 AFun() bool 20 } 21 22 func (a *A) AFun() bool { 23 return true 24 } 25 26 var _ AIf = &A{} 27 28 type B struct { 29 A 30 Mbr3 string 31 Mbr4 int 32 } 33 34 type C struct { 35 B 36 Mbr5 string 37 Mbr6 int 38 } 39 40 type D struct { 41 Mbr5 string 42 Mbr6 int 43 NmdA A 44 } 45 46 var a = A{} 47 var b = B{} 48 var c = C{} 49 var d = D{} 50 51 func InitC() { 52 c.Mbr1 = "mbr1 string" 53 c.Mbr2 = 2 54 c.Mbr3 = "mbr3 string" 55 c.Mbr4 = 4 56 c.Mbr5 = "mbr5 string" 57 c.Mbr6 = 6 58 } 59 60 func InitD() { 61 d.Mbr5 = "mbr5 string" 62 d.Mbr6 = 6 63 d.NmdA.Mbr1 = "a in d" 64 d.NmdA.Mbr2 = 2 65 } 66 67 func TestTypeEmbeds(t *testing.T) { 68 InitC() 69 70 a_in_a := TypeEmbeds(reflect.TypeOf(a), reflect.TypeOf(a)) 71 // fmt.Printf("A embeds A: %v\n", a_in_a) 72 73 b_in_a := TypeEmbeds(reflect.TypeOf(a), reflect.TypeOf(b)) 74 // fmt.Printf("A embeds B: %v\n", b_in_a) 75 76 a_in_b := TypeEmbeds(reflect.TypeOf(b), reflect.TypeOf(a)) 77 // fmt.Printf("B embeds A: %v\n", a_in_b) 78 79 a_in_c := TypeEmbeds(reflect.TypeOf(c), reflect.TypeOf(a)) 80 // fmt.Printf("C embeds A: %v\n", a_in_c) 81 82 aiftype := reflect.TypeOf((*AIf)(nil)).Elem() 83 84 // note: MUST use pointer for checking implements for pointer receivers! 85 // fmt.Printf("a implements Aif %v\n", reflect.TypeOf(&a).Implements(aiftype)) 86 87 aif_in_c := EmbedImplements(reflect.TypeOf(c), aiftype) 88 // fmt.Printf("C implements AIf: %v\n", aif_in_c) 89 90 aif_in_d := EmbedImplements(reflect.TypeOf(d), aiftype) 91 // fmt.Printf("D implements AIf: %v\n", aif_in_d) 92 93 if a_in_a != true || b_in_a != false || a_in_b != true || a_in_c != true || aif_in_c != true || aif_in_d != false { 94 t.Errorf("something wrong in TypeEmbeds: should have: true, false, true, true, true, false is: %v %v %v %v %v %v\n", a_in_a, b_in_a, a_in_b, a_in_c, aif_in_c, aif_in_d) 95 } 96 } 97 98 func TestEmbed(t *testing.T) { 99 InitC() 100 101 aa := Embed(&a, reflect.TypeOf(a)) 102 aas := fmt.Sprintf("%+v", aa) 103 aat := "&{Mbr1: Mbr2:0}" 104 if aas != aat { 105 t.Errorf("Didn't get proper embedded members of A from A: %v != %v\n", aas, aat) 106 } 107 108 ca := Embed(&c, reflect.TypeOf(a)) 109 cas := fmt.Sprintf("%+v", ca) 110 cat := "&{Mbr1:mbr1 string Mbr2:2}" 111 if cas != cat { 112 t.Errorf("Didn't get proper embedded members of C from A: %v != %v\n", cas, cat) 113 } 114 } 115 116 func TestFlatFields(t *testing.T) { 117 InitC() 118 119 // FlatFieldsTypeFunc(reflect.TypeOf(c), func(typ reflect.Type, field reflect.StructField) { 120 // fmt.Printf("typ: %v, field: %v\n", typ, field) 121 // }) 122 123 // FlatFieldsValueFunc(c, func(stru interface{}, typ reflect.Type, field reflect.StructField, fieldVal reflect.Value) { 124 // fmt.Printf("typ: %v, field: %v val: %v\n", typ, field, fieldVal) 125 // }) 126 127 // note: these test the above TypeFun and ValueFun 128 129 ff := FlatFields(reflect.TypeOf(c)) 130 ffs := fmt.Sprintf("%v", ff) 131 fft := `[{Mbr1 string 0 [0] false} {Mbr2 int 16 [1] false} {Mbr3 string 24 [1] false} {Mbr4 int 40 [2] false} {Mbr5 string 48 [1] false} {Mbr6 int 64 [2] false}]` 132 if ffs != fft { 133 t.Errorf("Didn't get proper flat field list of C: %v != %v\n", ffs, fft) 134 } 135 136 ffv := FlatFieldVals(&c) 137 ffvs := fmt.Sprintf("%v", ffv) 138 ffvt := `[mbr1 string <int Value> mbr3 string <int Value> mbr5 string <int Value>]` 139 if ffvs != ffvt { 140 t.Errorf("Didn't get proper flat field value list of C: %v != %v\n", ffvs, ffvt) 141 } 142 143 ffi := FlatFieldInterfaces(&c) 144 ffis := "" 145 for _, fi := range ffi { 146 ffis += fmt.Sprintf("%v,", NonPtrInterface(fi)) 147 } 148 ffit := `mbr1 string,2,mbr3 string,4,mbr5 string,6,` 149 if ffis != ffit { 150 t.Errorf("Didn't get proper flat field interface list of C: %v != %v\n", ffis, ffit) 151 } 152 } 153 154 func TestFlatFieldsByName(t *testing.T) { 155 InitC() 156 157 fif, _ := FlatFieldByName(reflect.TypeOf(c), "Mbr3") 158 fifs := fmt.Sprintf("%v", fif) 159 fift := `{Mbr3 string 24 [0 1] false}` 160 if fifs != fift { 161 t.Errorf("Didn't get proper find flat field by name: %v != %v\n", fifs, fift) 162 } 163 164 fifn, _ := FlatFieldByName(reflect.TypeOf(c), "Mbr31") 165 fifns := fmt.Sprintf("%v", fifn) 166 fifnt := `{ <nil> 0 [] false}` 167 if fifns != fifnt { 168 t.Errorf("Didn't get proper nil find flat field by name: %v != %v\n", fifns, fifnt) 169 } 170 171 fifv := FlatFieldValueByName(&c, "Mbr4") 172 fifvs := fmt.Sprintf("%v", fifv) 173 fifvt := `4` 174 if fifvs != fifvt { 175 t.Errorf("Didn't get proper find flat field value by name: %v != %v\n", fifvs, fifvt) 176 } 177 178 fifi := FlatFieldInterfaceByName(&c, "Mbr2") 179 fifis := fmt.Sprintf("%v", NonPtrInterface(fifi)) 180 fifit := `2` 181 if fifis != fifit { 182 t.Errorf("Didn't get proper find flat field value by name: %v != %v\n", fifis, fifit) 183 } 184 185 } 186 187 func TestFieldPaths(t *testing.T) { 188 InitD() 189 190 fld, ok := FieldByPath(reflect.TypeOf(d), "NmdA.Mbr1") 191 if !ok { 192 t.Errorf("FieldByPath failed per err msg, fld %v\n", fld.Name) 193 } 194 195 fi, ok := FieldValueByPath(d, "NmdA.Mbr1") 196 if !ok { 197 t.Errorf("FieldValueByPath failed per err msg, fi %v\n", fi) 198 } 199 // fmt.Printf("fi: %v\n", fi) 200 }