1
2
3
4
5 package reflectlite_test
6
7 import (
8 "encoding/base64"
9 "fmt"
10 . "internal/reflectlite"
11 "math"
12 "reflect"
13 "runtime"
14 "testing"
15 "unsafe"
16 )
17
18 func ToValue(v Value) reflect.Value {
19 return reflect.ValueOf(ToInterface(v))
20 }
21
22 func TypeString(t Type) string {
23 return fmt.Sprintf("%T", ToInterface(Zero(t)))
24 }
25
26 type integer int
27 type T struct {
28 a int
29 b float64
30 c string
31 d *int
32 }
33
34 type pair struct {
35 i any
36 s string
37 }
38
39 func assert(t *testing.T, s, want string) {
40 t.Helper()
41 if s != want {
42 t.Errorf("have %#q want %#q", s, want)
43 }
44 }
45
46 var typeTests = []pair{
47 {struct{ x int }{}, "int"},
48 {struct{ x int8 }{}, "int8"},
49 {struct{ x int16 }{}, "int16"},
50 {struct{ x int32 }{}, "int32"},
51 {struct{ x int64 }{}, "int64"},
52 {struct{ x uint }{}, "uint"},
53 {struct{ x uint8 }{}, "uint8"},
54 {struct{ x uint16 }{}, "uint16"},
55 {struct{ x uint32 }{}, "uint32"},
56 {struct{ x uint64 }{}, "uint64"},
57 {struct{ x float32 }{}, "float32"},
58 {struct{ x float64 }{}, "float64"},
59 {struct{ x int8 }{}, "int8"},
60 {struct{ x (**int8) }{}, "**int8"},
61 {struct{ x (**integer) }{}, "**reflectlite_test.integer"},
62 {struct{ x ([32]int32) }{}, "[32]int32"},
63 {struct{ x ([]int8) }{}, "[]int8"},
64 {struct{ x (map[string]int32) }{}, "map[string]int32"},
65 {struct{ x (chan<- string) }{}, "chan<- string"},
66 {struct {
67 x struct {
68 c chan *int32
69 d float32
70 }
71 }{},
72 "struct { c chan *int32; d float32 }",
73 },
74 {struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
75 {struct {
76 x struct {
77 c func(chan *integer, *int8)
78 }
79 }{},
80 "struct { c func(chan *reflectlite_test.integer, *int8) }",
81 },
82 {struct {
83 x struct {
84 a int8
85 b int32
86 }
87 }{},
88 "struct { a int8; b int32 }",
89 },
90 {struct {
91 x struct {
92 a int8
93 b int8
94 c int32
95 }
96 }{},
97 "struct { a int8; b int8; c int32 }",
98 },
99 {struct {
100 x struct {
101 a int8
102 b int8
103 c int8
104 d int32
105 }
106 }{},
107 "struct { a int8; b int8; c int8; d int32 }",
108 },
109 {struct {
110 x struct {
111 a int8
112 b int8
113 c int8
114 d int8
115 e int32
116 }
117 }{},
118 "struct { a int8; b int8; c int8; d int8; e int32 }",
119 },
120 {struct {
121 x struct {
122 a int8
123 b int8
124 c int8
125 d int8
126 e int8
127 f int32
128 }
129 }{},
130 "struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
131 },
132 {struct {
133 x struct {
134 a int8 `reflect:"hi there"`
135 }
136 }{},
137 `struct { a int8 "reflect:\"hi there\"" }`,
138 },
139 {struct {
140 x struct {
141 a int8 `reflect:"hi \x00there\t\n\"\\"`
142 }
143 }{},
144 `struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
145 },
146 {struct {
147 x struct {
148 f func(args ...int)
149 }
150 }{},
151 "struct { f func(...int) }",
152 },
153
154
155
156
157
158
159
160
161 {struct {
162 x struct {
163 int32
164 int64
165 }
166 }{},
167 "struct { int32; int64 }",
168 },
169 }
170
171 var valueTests = []pair{
172 {new(int), "132"},
173 {new(int8), "8"},
174 {new(int16), "16"},
175 {new(int32), "32"},
176 {new(int64), "64"},
177 {new(uint), "132"},
178 {new(uint8), "8"},
179 {new(uint16), "16"},
180 {new(uint32), "32"},
181 {new(uint64), "64"},
182 {new(float32), "256.25"},
183 {new(float64), "512.125"},
184 {new(complex64), "532.125+10i"},
185 {new(complex128), "564.25+1i"},
186 {new(string), "stringy cheese"},
187 {new(bool), "true"},
188 {new(*int8), "*int8(0)"},
189 {new(**int8), "**int8(0)"},
190 {new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
191 {new(**integer), "**reflectlite_test.integer(0)"},
192 {new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
193 {new(chan<- string), "chan<- string"},
194 {new(func(a int8, b int32)), "func(int8, int32)(arg)"},
195 {new(struct {
196 c chan *int32
197 d float32
198 }),
199 "struct { c chan *int32; d float32 }{chan *int32, 0}",
200 },
201 {new(struct{ c func(chan *integer, *int8) }),
202 "struct { c func(chan *reflectlite_test.integer, *int8) }{func(chan *reflectlite_test.integer, *int8)(arg)}",
203 },
204 {new(struct {
205 a int8
206 b int32
207 }),
208 "struct { a int8; b int32 }{0, 0}",
209 },
210 {new(struct {
211 a int8
212 b int8
213 c int32
214 }),
215 "struct { a int8; b int8; c int32 }{0, 0, 0}",
216 },
217 }
218
219 func testType(t *testing.T, i int, typ Type, want string) {
220 s := TypeString(typ)
221 if s != want {
222 t.Errorf("#%d: have %#q, want %#q", i, s, want)
223 }
224 }
225
226 func testReflectType(t *testing.T, i int, typ Type, want string) {
227 s := TypeString(typ)
228 if s != want {
229 t.Errorf("#%d: have %#q, want %#q", i, s, want)
230 }
231 }
232
233 func TestTypes(t *testing.T) {
234 for i, tt := range typeTests {
235 testReflectType(t, i, Field(ValueOf(tt.i), 0).Type(), tt.s)
236 }
237 }
238
239 func TestSetValue(t *testing.T) {
240 for i, tt := range valueTests {
241 v := ValueOf(tt.i).Elem()
242 switch v.Kind() {
243 case Int:
244 v.Set(ValueOf(int(132)))
245 case Int8:
246 v.Set(ValueOf(int8(8)))
247 case Int16:
248 v.Set(ValueOf(int16(16)))
249 case Int32:
250 v.Set(ValueOf(int32(32)))
251 case Int64:
252 v.Set(ValueOf(int64(64)))
253 case Uint:
254 v.Set(ValueOf(uint(132)))
255 case Uint8:
256 v.Set(ValueOf(uint8(8)))
257 case Uint16:
258 v.Set(ValueOf(uint16(16)))
259 case Uint32:
260 v.Set(ValueOf(uint32(32)))
261 case Uint64:
262 v.Set(ValueOf(uint64(64)))
263 case Float32:
264 v.Set(ValueOf(float32(256.25)))
265 case Float64:
266 v.Set(ValueOf(512.125))
267 case Complex64:
268 v.Set(ValueOf(complex64(532.125 + 10i)))
269 case Complex128:
270 v.Set(ValueOf(complex128(564.25 + 1i)))
271 case String:
272 v.Set(ValueOf("stringy cheese"))
273 case Bool:
274 v.Set(ValueOf(true))
275 }
276 s := valueToString(v)
277 if s != tt.s {
278 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
279 }
280 }
281 }
282
283 func TestCanSetField(t *testing.T) {
284 type embed struct{ x, X int }
285 type Embed struct{ x, X int }
286 type S1 struct {
287 embed
288 x, X int
289 }
290 type S2 struct {
291 *embed
292 x, X int
293 }
294 type S3 struct {
295 Embed
296 x, X int
297 }
298 type S4 struct {
299 *Embed
300 x, X int
301 }
302
303 type testCase struct {
304 index []int
305 canSet bool
306 }
307 tests := []struct {
308 val Value
309 cases []testCase
310 }{{
311 val: ValueOf(&S1{}),
312 cases: []testCase{
313 {[]int{0}, false},
314 {[]int{0, 0}, false},
315 {[]int{0, 1}, true},
316 {[]int{1}, false},
317 {[]int{2}, true},
318 },
319 }, {
320 val: ValueOf(&S2{embed: &embed{}}),
321 cases: []testCase{
322 {[]int{0}, false},
323 {[]int{0, 0}, false},
324 {[]int{0, 1}, true},
325 {[]int{1}, false},
326 {[]int{2}, true},
327 },
328 }, {
329 val: ValueOf(&S3{}),
330 cases: []testCase{
331 {[]int{0}, true},
332 {[]int{0, 0}, false},
333 {[]int{0, 1}, true},
334 {[]int{1}, false},
335 {[]int{2}, true},
336 },
337 }, {
338 val: ValueOf(&S4{Embed: &Embed{}}),
339 cases: []testCase{
340 {[]int{0}, true},
341 {[]int{0, 0}, false},
342 {[]int{0, 1}, true},
343 {[]int{1}, false},
344 {[]int{2}, true},
345 },
346 }}
347
348 for _, tt := range tests {
349 t.Run(tt.val.Type().Name(), func(t *testing.T) {
350 for _, tc := range tt.cases {
351 f := tt.val
352 for _, i := range tc.index {
353 if f.Kind() == Ptr {
354 f = f.Elem()
355 }
356 f = Field(f, i)
357 }
358 if got := f.CanSet(); got != tc.canSet {
359 t.Errorf("CanSet() = %v, want %v", got, tc.canSet)
360 }
361 }
362 })
363 }
364 }
365
366 var _i = 7
367
368 var valueToStringTests = []pair{
369 {123, "123"},
370 {123.5, "123.5"},
371 {byte(123), "123"},
372 {"abc", "abc"},
373 {T{123, 456.75, "hello", &_i}, "reflectlite_test.T{123, 456.75, hello, *int(&7)}"},
374 {new(chan *T), "*chan *reflectlite_test.T(&chan *reflectlite_test.T)"},
375 {[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
376 {&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[10]int(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
377 {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
378 {&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
379 }
380
381 func TestValueToString(t *testing.T) {
382 for i, test := range valueToStringTests {
383 s := valueToString(ValueOf(test.i))
384 if s != test.s {
385 t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
386 }
387 }
388 }
389
390 func TestPtrSetNil(t *testing.T) {
391 var i int32 = 1234
392 ip := &i
393 vip := ValueOf(&ip)
394 vip.Elem().Set(Zero(vip.Elem().Type()))
395 if ip != nil {
396 t.Errorf("got non-nil (%d), want nil", *ip)
397 }
398 }
399
400 func TestMapSetNil(t *testing.T) {
401 m := make(map[string]int)
402 vm := ValueOf(&m)
403 vm.Elem().Set(Zero(vm.Elem().Type()))
404 if m != nil {
405 t.Errorf("got non-nil (%p), want nil", m)
406 }
407 }
408
409 func TestAll(t *testing.T) {
410 testType(t, 1, TypeOf((int8)(0)), "int8")
411 testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
412
413 typ := TypeOf((*struct {
414 c chan *int32
415 d float32
416 })(nil))
417 testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
418 etyp := typ.Elem()
419 testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
420 }
421
422 func TestInterfaceValue(t *testing.T) {
423 var inter struct {
424 E any
425 }
426 inter.E = 123.456
427 v1 := ValueOf(&inter)
428 v2 := Field(v1.Elem(), 0)
429
430 v3 := v2.Elem()
431 assert(t, TypeString(v3.Type()), "float64")
432
433 i3 := ToInterface(v2)
434 if _, ok := i3.(float64); !ok {
435 t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
436 }
437 }
438
439 func TestFunctionValue(t *testing.T) {
440 var x any = func() {}
441 v := ValueOf(x)
442 if fmt.Sprint(ToInterface(v)) != fmt.Sprint(x) {
443 t.Fatalf("TestFunction returned wrong pointer")
444 }
445 assert(t, TypeString(v.Type()), "func()")
446 }
447
448 var appendTests = []struct {
449 orig, extra []int
450 }{
451 {make([]int, 2, 4), []int{22}},
452 {make([]int, 2, 4), []int{22, 33, 44}},
453 }
454
455 func sameInts(x, y []int) bool {
456 if len(x) != len(y) {
457 return false
458 }
459 for i, xx := range x {
460 if xx != y[i] {
461 return false
462 }
463 }
464 return true
465 }
466
467 func TestBigUnnamedStruct(t *testing.T) {
468 b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
469 v := ValueOf(b)
470 b1 := ToInterface(v).(struct {
471 a, b, c, d int64
472 })
473 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
474 t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
475 }
476 }
477
478 type big struct {
479 a, b, c, d, e int64
480 }
481
482 func TestBigStruct(t *testing.T) {
483 b := big{1, 2, 3, 4, 5}
484 v := ValueOf(b)
485 b1 := ToInterface(v).(big)
486 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
487 t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
488 }
489 }
490
491 type Basic struct {
492 x int
493 y float32
494 }
495
496 type NotBasic Basic
497
498 type DeepEqualTest struct {
499 a, b any
500 eq bool
501 }
502
503
504 var (
505 fn1 func()
506 fn2 func()
507 fn3 = func() { fn1() }
508 )
509
510 type self struct{}
511
512 type Loop *Loop
513 type Loopy any
514
515 var loop1, loop2 Loop
516 var loopy1, loopy2 Loopy
517
518 func init() {
519 loop1 = &loop2
520 loop2 = &loop1
521
522 loopy1 = &loopy2
523 loopy2 = &loopy1
524 }
525
526 var typeOfTests = []DeepEqualTest{
527
528 {nil, nil, true},
529 {1, 1, true},
530 {int32(1), int32(1), true},
531 {0.5, 0.5, true},
532 {float32(0.5), float32(0.5), true},
533 {"hello", "hello", true},
534 {make([]int, 10), make([]int, 10), true},
535 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
536 {Basic{1, 0.5}, Basic{1, 0.5}, true},
537 {error(nil), error(nil), true},
538 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
539 {fn1, fn2, true},
540
541
542 {1, 2, false},
543 {int32(1), int32(2), false},
544 {0.5, 0.6, false},
545 {float32(0.5), float32(0.6), false},
546 {"hello", "hey", false},
547 {make([]int, 10), make([]int, 11), false},
548 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
549 {Basic{1, 0.5}, Basic{1, 0.6}, false},
550 {Basic{1, 0}, Basic{2, 0}, false},
551 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
552 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
553 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
554 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
555 {nil, 1, false},
556 {1, nil, false},
557 {fn1, fn3, false},
558 {fn3, fn3, false},
559 {[][]int{{1}}, [][]int{{2}}, false},
560 {math.NaN(), math.NaN(), false},
561 {&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false},
562 {&[1]float64{math.NaN()}, self{}, true},
563 {[]float64{math.NaN()}, []float64{math.NaN()}, false},
564 {[]float64{math.NaN()}, self{}, true},
565 {map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
566 {map[float64]float64{math.NaN(): 1}, self{}, true},
567
568
569 {[]int{}, []int(nil), false},
570 {[]int{}, []int{}, true},
571 {[]int(nil), []int(nil), true},
572 {map[int]int{}, map[int]int(nil), false},
573 {map[int]int{}, map[int]int{}, true},
574 {map[int]int(nil), map[int]int(nil), true},
575
576
577 {1, 1.0, false},
578 {int32(1), int64(1), false},
579 {0.5, "hello", false},
580 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
581 {&[3]any{1, 2, 4}, &[3]any{1, 2, "s"}, false},
582 {Basic{1, 0.5}, NotBasic{1, 0.5}, false},
583 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
584
585
586 {&loop1, &loop1, true},
587 {&loop1, &loop2, true},
588 {&loopy1, &loopy1, true},
589 {&loopy1, &loopy2, true},
590 }
591
592 func TestTypeOf(t *testing.T) {
593
594 if typ := TypeOf(nil); typ != nil {
595 t.Errorf("expected nil type for nil value; got %v", typ)
596 }
597 for _, test := range typeOfTests {
598 v := ValueOf(test.a)
599 if !v.IsValid() {
600 continue
601 }
602 typ := TypeOf(test.a)
603 if typ != v.Type() {
604 t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
605 }
606 }
607 }
608
609 func Nil(a any, t *testing.T) {
610 n := Field(ValueOf(a), 0)
611 if !n.IsNil() {
612 t.Errorf("%v should be nil", a)
613 }
614 }
615
616 func NotNil(a any, t *testing.T) {
617 n := Field(ValueOf(a), 0)
618 if n.IsNil() {
619 t.Errorf("value of type %v should not be nil", TypeString(ValueOf(a).Type()))
620 }
621 }
622
623 func TestIsNil(t *testing.T) {
624
625
626 doNil := []any{
627 struct{ x *int }{},
628 struct{ x any }{},
629 struct{ x map[string]int }{},
630 struct{ x func() bool }{},
631 struct{ x chan int }{},
632 struct{ x []string }{},
633 struct{ x unsafe.Pointer }{},
634 }
635 for _, ts := range doNil {
636 ty := TField(TypeOf(ts), 0)
637 v := Zero(ty)
638 v.IsNil()
639 }
640
641
642 var pi struct {
643 x *int
644 }
645 Nil(pi, t)
646 pi.x = new(int)
647 NotNil(pi, t)
648
649 var si struct {
650 x []int
651 }
652 Nil(si, t)
653 si.x = make([]int, 10)
654 NotNil(si, t)
655
656 var ci struct {
657 x chan int
658 }
659 Nil(ci, t)
660 ci.x = make(chan int)
661 NotNil(ci, t)
662
663 var mi struct {
664 x map[int]int
665 }
666 Nil(mi, t)
667 mi.x = make(map[int]int)
668 NotNil(mi, t)
669
670 var ii struct {
671 x any
672 }
673 Nil(ii, t)
674 ii.x = 2
675 NotNil(ii, t)
676
677 var fi struct {
678 x func(t *testing.T)
679 }
680 Nil(fi, t)
681 fi.x = TestIsNil
682 NotNil(fi, t)
683 }
684
685
686
687
688 func Indirect(v Value) Value {
689 if v.Kind() != Ptr {
690 return v
691 }
692 return v.Elem()
693 }
694
695 func TestNilPtrValueSub(t *testing.T) {
696 var pi *int
697 if pv := ValueOf(pi); pv.Elem().IsValid() {
698 t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
699 }
700 }
701
702 type Point struct {
703 x, y int
704 }
705
706
707 func (p Point) AnotherMethod(scale int) int {
708 return -1
709 }
710
711
712 func (p Point) Dist(scale int) int {
713
714 return p.x*p.x*scale + p.y*p.y*scale
715 }
716
717
718 func (p Point) GCMethod(k int) int {
719 runtime.GC()
720 return k + p.x
721 }
722
723
724 func (p Point) NoArgs() {
725
726 }
727
728
729 func (p Point) TotalDist(points ...Point) int {
730 tot := 0
731 for _, q := range points {
732 dx := q.x - p.x
733 dy := q.y - p.y
734 tot += dx*dx + dy*dy
735
736 }
737 return tot
738 }
739
740 type D1 struct {
741 d int
742 }
743 type D2 struct {
744 d int
745 }
746
747 func TestImportPath(t *testing.T) {
748 tests := []struct {
749 t Type
750 path string
751 }{
752 {TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
753 {TypeOf(int(0)), ""},
754 {TypeOf(int8(0)), ""},
755 {TypeOf(int16(0)), ""},
756 {TypeOf(int32(0)), ""},
757 {TypeOf(int64(0)), ""},
758 {TypeOf(uint(0)), ""},
759 {TypeOf(uint8(0)), ""},
760 {TypeOf(uint16(0)), ""},
761 {TypeOf(uint32(0)), ""},
762 {TypeOf(uint64(0)), ""},
763 {TypeOf(uintptr(0)), ""},
764 {TypeOf(float32(0)), ""},
765 {TypeOf(float64(0)), ""},
766 {TypeOf(complex64(0)), ""},
767 {TypeOf(complex128(0)), ""},
768 {TypeOf(byte(0)), ""},
769 {TypeOf(rune(0)), ""},
770 {TypeOf([]byte(nil)), ""},
771 {TypeOf([]rune(nil)), ""},
772 {TypeOf(string("")), ""},
773 {TypeOf((*any)(nil)).Elem(), ""},
774 {TypeOf((*byte)(nil)), ""},
775 {TypeOf((*rune)(nil)), ""},
776 {TypeOf((*int64)(nil)), ""},
777 {TypeOf(map[string]int{}), ""},
778 {TypeOf((*error)(nil)).Elem(), ""},
779 {TypeOf((*Point)(nil)), ""},
780 {TypeOf((*Point)(nil)).Elem(), "internal/reflectlite_test"},
781 }
782 for _, test := range tests {
783 if path := test.t.PkgPath(); path != test.path {
784 t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
785 }
786 }
787 }
788
789 func noAlloc(t *testing.T, n int, f func(int)) {
790 if testing.Short() {
791 t.Skip("skipping malloc count in short mode")
792 }
793 if runtime.GOMAXPROCS(0) > 1 {
794 t.Skip("skipping; GOMAXPROCS>1")
795 }
796 i := -1
797 allocs := testing.AllocsPerRun(n, func() {
798 f(i)
799 i++
800 })
801 if allocs > 0 {
802 t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
803 }
804 }
805
806 func TestAllocations(t *testing.T) {
807 noAlloc(t, 100, func(j int) {
808 var i any
809 var v Value
810
811
812
813
814
815
816
817
818
819
820
821 i = func(j int) int { return j }
822 v = ValueOf(i)
823 if ToInterface(v).(func(int) int)(j) != j {
824 panic("wrong result")
825 }
826 })
827 }
828
829 func TestSetPanic(t *testing.T) {
830 ok := func(f func()) { f() }
831 bad := shouldPanic
832 clear := func(v Value) { v.Set(Zero(v.Type())) }
833
834 type t0 struct {
835 W int
836 }
837
838 type t1 struct {
839 Y int
840 t0
841 }
842
843 type T2 struct {
844 Z int
845 namedT0 t0
846 }
847
848 type T struct {
849 X int
850 t1
851 T2
852 NamedT1 t1
853 NamedT2 T2
854 namedT1 t1
855 namedT2 T2
856 }
857
858
859 v := ValueOf(T{})
860 bad(func() { clear(Field(v, 0)) })
861 bad(func() { clear(Field(v, 1)) })
862 bad(func() { clear(Field(Field(v, 1), 0)) })
863 bad(func() { clear(Field(Field(v, 1), 1)) })
864 bad(func() { clear(Field(Field(Field(v, 1), 1), 0)) })
865 bad(func() { clear(Field(v, 2)) })
866 bad(func() { clear(Field(Field(v, 2), 0)) })
867 bad(func() { clear(Field(Field(v, 2), 1)) })
868 bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) })
869 bad(func() { clear(Field(v, 3)) })
870 bad(func() { clear(Field(Field(v, 3), 0)) })
871 bad(func() { clear(Field(Field(v, 3), 1)) })
872 bad(func() { clear(Field(Field(Field(v, 3), 1), 0)) })
873 bad(func() { clear(Field(v, 4)) })
874 bad(func() { clear(Field(Field(v, 4), 0)) })
875 bad(func() { clear(Field(Field(v, 4), 1)) })
876 bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) })
877 bad(func() { clear(Field(v, 5)) })
878 bad(func() { clear(Field(Field(v, 5), 0)) })
879 bad(func() { clear(Field(Field(v, 5), 1)) })
880 bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) })
881 bad(func() { clear(Field(v, 6)) })
882 bad(func() { clear(Field(Field(v, 6), 0)) })
883 bad(func() { clear(Field(Field(v, 6), 1)) })
884 bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) })
885
886
887 v = ValueOf(&T{}).Elem()
888 ok(func() { clear(Field(v, 0)) })
889 bad(func() { clear(Field(v, 1)) })
890 ok(func() { clear(Field(Field(v, 1), 0)) })
891 bad(func() { clear(Field(Field(v, 1), 1)) })
892 ok(func() { clear(Field(Field(Field(v, 1), 1), 0)) })
893 ok(func() { clear(Field(v, 2)) })
894 ok(func() { clear(Field(Field(v, 2), 0)) })
895 bad(func() { clear(Field(Field(v, 2), 1)) })
896 bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) })
897 ok(func() { clear(Field(v, 3)) })
898 ok(func() { clear(Field(Field(v, 3), 0)) })
899 bad(func() { clear(Field(Field(v, 3), 1)) })
900 ok(func() { clear(Field(Field(Field(v, 3), 1), 0)) })
901 ok(func() { clear(Field(v, 4)) })
902 ok(func() { clear(Field(Field(v, 4), 0)) })
903 bad(func() { clear(Field(Field(v, 4), 1)) })
904 bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) })
905 bad(func() { clear(Field(v, 5)) })
906 bad(func() { clear(Field(Field(v, 5), 0)) })
907 bad(func() { clear(Field(Field(v, 5), 1)) })
908 bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) })
909 bad(func() { clear(Field(v, 6)) })
910 bad(func() { clear(Field(Field(v, 6), 0)) })
911 bad(func() { clear(Field(Field(v, 6), 1)) })
912 bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) })
913 }
914
915 func shouldPanic(f func()) {
916 defer func() {
917 if recover() == nil {
918 panic("did not panic")
919 }
920 }()
921 f()
922 }
923
924 type S struct {
925 i1 int64
926 i2 int64
927 }
928
929 func TestBigZero(t *testing.T) {
930 const size = 1 << 10
931 var v [size]byte
932 z := ToInterface(Zero(ValueOf(v).Type())).([size]byte)
933 for i := 0; i < size; i++ {
934 if z[i] != 0 {
935 t.Fatalf("Zero object not all zero, index %d", i)
936 }
937 }
938 }
939
940 func TestInvalid(t *testing.T) {
941
942 type T struct{ v any }
943
944 v := Field(ValueOf(T{}), 0)
945 if v.IsValid() != true || v.Kind() != Interface {
946 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
947 }
948 v = v.Elem()
949 if v.IsValid() != false || v.Kind() != Invalid {
950 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
951 }
952 }
953
954 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
955
956 type nameTest struct {
957 v any
958 want string
959 }
960
961 var nameTests = []nameTest{
962 {(*int32)(nil), "int32"},
963 {(*D1)(nil), "D1"},
964 {(*[]D1)(nil), ""},
965 {(*chan D1)(nil), ""},
966 {(*func() D1)(nil), ""},
967 {(*<-chan D1)(nil), ""},
968 {(*chan<- D1)(nil), ""},
969 {(*any)(nil), ""},
970 {(*interface {
971 F()
972 })(nil), ""},
973 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
974 }
975
976 func TestNames(t *testing.T) {
977 for _, test := range nameTests {
978 typ := TypeOf(test.v).Elem()
979 if got := typ.Name(); got != test.want {
980 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
981 }
982 }
983 }
984
985
986
987
988
989
990 func TestUnaddressableField(t *testing.T) {
991 var b Buffer
992 var localBuffer struct {
993 buf []byte
994 }
995 lv := ValueOf(&localBuffer).Elem()
996 rv := ValueOf(b)
997 shouldPanic(func() {
998 lv.Set(rv)
999 })
1000 }
1001
1002 type Tint int
1003
1004 type Tint2 = Tint
1005
1006 type Talias1 struct {
1007 byte
1008 uint8
1009 int
1010 int32
1011 rune
1012 }
1013
1014 type Talias2 struct {
1015 Tint
1016 Tint2
1017 }
1018
1019 func TestAliasNames(t *testing.T) {
1020 t1 := Talias1{byte: 1, uint8: 2, int: 3, int32: 4, rune: 5}
1021 out := fmt.Sprintf("%#v", t1)
1022 want := "reflectlite_test.Talias1{byte:0x1, uint8:0x2, int:3, int32:4, rune:5}"
1023 if out != want {
1024 t.Errorf("Talias1 print:\nhave: %s\nwant: %s", out, want)
1025 }
1026
1027 t2 := Talias2{Tint: 1, Tint2: 2}
1028 out = fmt.Sprintf("%#v", t2)
1029 want = "reflectlite_test.Talias2{Tint:1, Tint2:2}"
1030 if out != want {
1031 t.Errorf("Talias2 print:\nhave: %s\nwant: %s", out, want)
1032 }
1033 }
1034
View as plain text