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