github.com/goplusjs/reflectx@v0.5.4/reflectx_test.go (about) 1 package reflectx_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "reflect" 7 "testing" 8 "unsafe" 9 10 "github.com/goplusjs/reflectx" 11 ) 12 13 type nPoint struct { 14 x int 15 y int 16 } 17 18 func TestFieldCanSet(t *testing.T) { 19 x := &nPoint{10, 20} 20 v := reflect.ValueOf(x).Elem() 21 22 sf := v.Field(0) 23 if sf.CanSet() { 24 t.Fatal("x unexport cannot set") 25 } 26 27 sf = reflectx.CanSet(sf) 28 if !sf.CanSet() { 29 t.Fatal("CanSet failed") 30 } 31 32 sf.Set(reflect.ValueOf(201)) 33 if x.x != 201 { 34 t.Fatalf("x value %v", x.x) 35 } 36 sf.SetInt(202) 37 if x.x != 202 { 38 t.Fatalf("x value %v", x.x) 39 } 40 } 41 42 type Rect struct { 43 pt1 nPoint 44 pt2 *nPoint 45 } 46 47 func TestField(t *testing.T) { 48 x := &Rect{nPoint{1, 2}, &nPoint{3, 4}} 49 v := reflect.ValueOf(x).Elem() 50 reflectx.Field(v, 0).Set(reflect.ValueOf(nPoint{10, 20})) 51 if x.pt1.x != 10 || x.pt1.y != 20 { 52 t.Fatalf("pt1 %v", x.pt1) 53 } 54 reflectx.FieldByName(v, "pt2").Set(reflect.ValueOf(&nPoint{30, 40})) 55 if x.pt2.x != 30 || x.pt2.y != 40 { 56 t.Fatalf("pt2 %v", x.pt2) 57 } 58 reflectx.FieldByNameFunc(v, func(name string) bool { 59 return name == "pt2" 60 }).Set(reflect.ValueOf(&nPoint{50, 60})) 61 if x.pt2.x != 50 || x.pt2.y != 60 { 62 t.Fatalf("pt2 %v", x.pt2) 63 } 64 reflectx.FieldByIndex(v, []int{0, 1}).SetInt(100) 65 if x.pt1.y != 100 { 66 t.Fatalf("pt1.y %v", x.pt1) 67 } 68 } 69 70 func TestFieldX(t *testing.T) { 71 x := &Rect{nPoint{1, 2}, &nPoint{3, 4}} 72 v := reflect.ValueOf(x).Elem() 73 reflectx.FieldX(v, 0).Set(reflect.ValueOf(nPoint{10, 20})) 74 if x.pt1.x != 10 || x.pt1.y != 20 { 75 t.Fatalf("pt1 %v", x.pt1) 76 } 77 reflectx.FieldByNameX(v, "pt2").Set(reflect.ValueOf(&nPoint{30, 40})) 78 if x.pt2.x != 30 || x.pt2.y != 40 { 79 t.Fatalf("pt2 %v", x.pt2) 80 } 81 reflectx.FieldByNameFuncX(v, func(name string) bool { 82 return name == "pt2" 83 }).Set(reflect.ValueOf(&nPoint{50, 60})) 84 if x.pt2.x != 50 || x.pt2.y != 60 { 85 t.Fatalf("pt2 %v", x.pt2) 86 } 87 reflectx.FieldByIndexX(v, []int{0, 1}).SetInt(100) 88 if x.pt1.y != 100 { 89 t.Fatalf("pt1.y %v", x.pt1) 90 } 91 } 92 93 func TestStructOfUnderscore(t *testing.T) { 94 fs := []reflect.StructField{ 95 reflect.StructField{ 96 Name: "_", 97 PkgPath: "main", 98 Type: tyInt, 99 }, 100 reflect.StructField{ 101 Name: "_", 102 PkgPath: "main", 103 Type: tyInt, 104 }, 105 } 106 typ := reflectx.NamedStructOf("main", "Point", fs) 107 if typ.Field(0).Name != "_" { 108 t.Fatalf("field name must underscore") 109 } 110 if typ.Field(1).Name != "_" { 111 t.Fatalf("field name must underscore") 112 } 113 } 114 115 func TestStructOfExport(t *testing.T) { 116 fs := []reflect.StructField{ 117 reflect.StructField{ 118 Name: "x", 119 PkgPath: "main", 120 Type: tyInt, 121 }, 122 reflect.StructField{ 123 Name: "y", 124 PkgPath: "main", 125 Type: tyInt, 126 }, 127 } 128 typ := reflectx.NamedStructOf("main", "Point", fs) 129 v := reflect.New(typ).Elem() 130 reflectx.FieldByIndex(v, []int{0}).SetInt(100) 131 reflectx.FieldByIndex(v, []int{1}).SetInt(200) 132 if s := fmt.Sprint(v); s != "{100 200}" { 133 t.Fatalf("have %v, want {100 200}", s) 134 } 135 } 136 137 type Buffer struct { 138 *bytes.Buffer 139 size int 140 value reflect.Value 141 *bytes.Reader 142 } 143 144 func TestStructOf(t *testing.T) { 145 defer func() { 146 v := recover() 147 if v != nil { 148 t.Fatalf("reflectx.StructOf %v", v) 149 } 150 }() 151 typ := reflect.TypeOf((*Buffer)(nil)).Elem() 152 var fs []reflect.StructField 153 for i := 0; i < typ.NumField(); i++ { 154 fs = append(fs, typ.Field(i)) 155 } 156 dst := reflectx.StructOf(fs) 157 for i := 0; i < dst.NumField(); i++ { 158 if dst.Field(i).Anonymous != fs[i].Anonymous { 159 t.Errorf("error field %v", dst.Field(i)) 160 } 161 } 162 163 v := reflect.New(dst) 164 v.Elem().Field(0).Set(reflect.ValueOf(bytes.NewBufferString("hello"))) 165 reflectx.CanSet(v.Elem().Field(1)).SetInt(100) 166 } 167 168 func TestNamedStruct(t *testing.T) { 169 fs := []reflect.StructField{ 170 reflect.StructField{Name: "X", Type: reflect.TypeOf(0)}, 171 reflect.StructField{Name: "Y", Type: reflect.TypeOf(0)}, 172 } 173 t1 := reflect.StructOf(fs) 174 t2 := reflect.StructOf(fs) 175 if t1 != t2 { 176 t.Fatalf("reflect.StructOf %v != %v", t1, t2) 177 } 178 t3 := reflectx.NamedStructOf("github.com/goplus/reflectx_test", "Point", fs) 179 t4 := reflectx.NamedStructOf("github.com/goplus/reflectx_test", "Point2", fs) 180 if t3 == t4 { 181 t.Fatalf("NamedStructOf %v == %v", t3, t4) 182 } 183 if t4.String() != "reflectx_test.Point2" { 184 t.Fatalf("t4.String=%v", t4.String()) 185 } 186 if t4.Name() != "Point2" { 187 t.Fatalf("t4.Name=%v", t4.Name()) 188 } 189 if t4.PkgPath() != "github.com/goplus/reflectx_test" { 190 t.Fatalf("t4.PkgPath=%v", t4.PkgPath()) 191 } 192 } 193 194 var ( 195 ch = make(chan bool) 196 fn = func(int, string) (bool, int) { 197 return true, 0 198 } 199 fn2 = func(*nPoint, int, bool, []byte) int { 200 return 0 201 } 202 testNamedValue = []interface{}{ 203 true, 204 false, 205 int(2), 206 int8(3), 207 int16(4), 208 int32(5), 209 int64(6), 210 uint(7), 211 uint8(8), 212 uint16(9), 213 uint32(10), 214 uint64(11), 215 uintptr(12), 216 float32(13), 217 float64(14), 218 complex64(15), 219 complex128(16), 220 "hello", 221 unsafe.Pointer(nil), 222 unsafe.Pointer(&fn), 223 []byte("hello"), 224 []int{1, 2, 3}, 225 [5]byte{'a', 'b', 'c', 'd', 'e'}, 226 [5]int{1, 2, 3, 4, 5}, 227 []string{"a", "b"}, 228 []int{100, 200}, 229 map[int]string{1: "hello", 2: "world"}, 230 new(uint8), 231 &fn, 232 &fn2, 233 &ch, 234 ch, 235 fn, 236 fn2, 237 } 238 ) 239 240 func TestNamedType(t *testing.T) { 241 pkgpath := "github.com/goplus/reflectx" 242 for i, v := range testNamedValue { 243 value := reflect.ValueOf(v) 244 typ := value.Type() 245 nt := reflectx.NamedTypeOf("github.com/goplus/reflectx", fmt.Sprintf("MyType%v", i), typ) 246 if nt.Kind() != typ.Kind() { 247 t.Errorf("kind: have %v, want %v", nt.Kind(), typ.Kind()) 248 } 249 if nt == typ { 250 t.Errorf("same type, %v", typ) 251 } 252 name := fmt.Sprintf("My_Type%v", i) 253 nt2 := reflectx.NamedTypeOf(pkgpath, name, typ) 254 if nt == nt2 { 255 t.Errorf("same type, %v", nt) 256 } 257 nv := reflect.New(nt).Elem() 258 reflectx.SetValue(nv, value) // 259 s1 := fmt.Sprint((nv)) 260 s2 := fmt.Sprint(v) 261 if s1 != s2 { 262 t.Errorf("%v: have %v, want %v", nt.Kind(), s1, s2) 263 } 264 if nt2.Name() != name { 265 t.Errorf("name: have %v, want %v", nt2.Name(), name) 266 } 267 if nt2.PkgPath() != pkgpath { 268 t.Errorf("pkgpath: have %v, want %v", nt2.PkgPath(), pkgpath) 269 } 270 } 271 } 272 273 var testInterfaceType = []reflect.Type{ 274 reflect.TypeOf((*interface{})(nil)).Elem(), 275 reflect.TypeOf((*fmt.Stringer)(nil)).Elem(), 276 reflect.TypeOf((*interface { 277 Read(p []byte) (n int, err error) 278 Write(p []byte) (n int, err error) 279 Close() error 280 })(nil)), 281 } 282 283 func TestNamedInterface(t *testing.T) { 284 pkgpath := reflect.TypeOf((*interface{})(nil)).Elem().PkgPath() 285 for i, styp := range testInterfaceType { 286 name := fmt.Sprintf("T%v", i) 287 typ := reflectx.NamedTypeOf(pkgpath, name, styp) 288 if typ.Name() != name { 289 t.Errorf("name: have %v, want %v", typ.Name(), name) 290 } 291 if typ.PkgPath() != pkgpath { 292 t.Errorf("pkgpath: have %v, want %v", typ.PkgPath(), pkgpath) 293 } 294 if typ.NumMethod() != styp.NumMethod() { 295 t.Errorf("num method: have %v, want %v", typ.NumMethod(), styp.NumMethod()) 296 } 297 for i := 0; i < typ.NumMethod(); i++ { 298 if typ.Method(i) != styp.Method(i) { 299 t.Errorf("method: have %v, want %v", typ.Method(i), styp.Method(i)) 300 } 301 } 302 if !typ.ConvertibleTo(styp) { 303 t.Errorf("%v cannot ConvertibleTo %v", typ, styp) 304 } 305 if !styp.ConvertibleTo(typ) { 306 t.Errorf("%v cannot ConvertibleTo %v", styp, typ) 307 } 308 } 309 } 310 311 func TestNamedTypeStruct(t *testing.T) { 312 typ := reflect.TypeOf((*nPoint)(nil)).Elem() 313 pkgpath := typ.PkgPath() 314 nt := reflectx.NamedTypeOf(pkgpath, "MyPoint", typ) 315 nt2 := reflectx.NamedTypeOf(pkgpath, "MyPoint2", typ) 316 if nt.NumField() != typ.NumField() { 317 t.Fatal("NumField != 2", nt.NumField()) 318 } 319 if nt.Name() != "MyPoint" { 320 t.Fatal("Name != MyPoint", nt.Name()) 321 } 322 if nt == nt2 { 323 t.Fatalf("same type %v", nt) 324 } 325 v := reflect.New(nt).Elem() 326 reflectx.Field(v, 0).SetInt(100) 327 reflectx.Field(v, 1).SetInt(200) 328 if v.FieldByName("x").Int() != 100 || v.FieldByName("y").Int() != 200 { 329 t.Fatal("Value != {100 200},", v) 330 } 331 } 332 333 func _TestSetElem(t *testing.T) { 334 typ := reflectx.NamedTypeOf("main", "T", reflect.TypeOf(([]struct{})(nil))) 335 reflectx.SetElem(typ, typ) 336 v := reflect.MakeSlice(typ, 3, 3) 337 v.Index(0).Set(reflect.MakeSlice(typ, 1, 1)) 338 v.Index(1).Set(reflect.MakeSlice(typ, 2, 2)) 339 s := fmt.Sprintf("%v", v.Interface()) 340 if s != "[[[]] [[] []] []]" { 341 t.Fatalf("failed SetElem s=%v", s) 342 } 343 }