| // Copyright 2023 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package reflect_test | |
| import ( | |
| "reflect" | |
| "testing" | |
| ) | |
| func TestTypeFor(t *testing.T) { | |
| type ( | |
| mystring string | |
| myiface any | |
| ) | |
| testcases := []struct { | |
| wantFrom any | |
| got reflect.Type | |
| }{ | |
| {new(int), reflect.TypeFor[int]()}, | |
| {new(int64), reflect.TypeFor[int64]()}, | |
| {new(string), reflect.TypeFor[string]()}, | |
| {new(mystring), reflect.TypeFor[mystring]()}, | |
| {new(any), reflect.TypeFor[any]()}, | |
| {new(myiface), reflect.TypeFor[myiface]()}, | |
| } | |
| for _, tc := range testcases { | |
| want := reflect.ValueOf(tc.wantFrom).Elem().Type() | |
| if want != tc.got { | |
| t.Errorf("unexpected reflect.Type: got %v; want %v", tc.got, want) | |
| } | |
| } | |
| } | |
| func TestStructOfEmbeddedIfaceMethodCall(t *testing.T) { | |
| type Named interface { | |
| Name() string | |
| } | |
| typ := reflect.StructOf([]reflect.StructField{ | |
| { | |
| Anonymous: true, | |
| Name: "Named", | |
| Type: reflect.TypeFor[Named](), | |
| }, | |
| }) | |
| v := reflect.New(typ).Elem() | |
| v.Field(0).Set( | |
| reflect.ValueOf(reflect.TypeFor[string]()), | |
| ) | |
| x := v.Interface().(Named) | |
| shouldPanic("StructOf does not support methods of embedded interfaces", func() { | |
| _ = x.Name() | |
| }) | |
| } | |
| func TestIsRegularMemory(t *testing.T) { | |
| type args struct { | |
| t reflect.Type | |
| } | |
| type S struct { | |
| int | |
| } | |
| tests := []struct { | |
| name string | |
| args args | |
| want bool | |
| }{ | |
| {"struct{i int}", args{reflect.TypeOf(struct{ i int }{})}, true}, | |
| {"struct{}", args{reflect.TypeOf(struct{}{})}, true}, | |
| {"struct{i int; s S}", args{reflect.TypeOf(struct { | |
| i int | |
| s S | |
| }{})}, true}, | |
| {"map[int][int]", args{reflect.TypeOf(map[int]int{})}, false}, | |
| {"[4]chan int", args{reflect.TypeOf([4]chan int{})}, true}, | |
| {"[0]struct{_ S}", args{reflect.TypeOf([0]struct { | |
| _ S | |
| }{})}, true}, | |
| {"struct{i int; _ S}", args{reflect.TypeOf(struct { | |
| i int | |
| _ S | |
| }{})}, false}, | |
| {"struct{a int16; b int32}", args{reflect.TypeOf(struct { | |
| a int16 | |
| b int32 | |
| }{})}, false}, | |
| {"struct {x int32; y int16}", args{reflect.TypeOf(struct { | |
| x int32 | |
| y int16 | |
| }{})}, false}, | |
| {"struct {_ int32 }", args{reflect.TypeOf(struct{ _ int32 }{})}, false}, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| if got := reflect.IsRegularMemory(tt.args.t); got != tt.want { | |
| t.Errorf("isRegularMemory() = %v, want %v", got, tt.want) | |
| } | |
| }) | |
| } | |
| } | |
| var sinkType reflect.Type | |
| func BenchmarkTypeForString(b *testing.B) { | |
| for i := 0; i < b.N; i++ { | |
| sinkType = reflect.TypeFor[string]() | |
| } | |
| } | |
| func BenchmarkTypeForError(b *testing.B) { | |
| for i := 0; i < b.N; i++ { | |
| sinkType = reflect.TypeFor[error]() | |
| } | |
| } | |
| func TestType_CanSeq(t *testing.T) { | |
| tests := []struct { | |
| name string | |
| tr reflect.Type | |
| want bool | |
| }{ | |
| {"func(func(int) bool)", reflect.TypeOf(func(func(int) bool) {}), true}, | |
| {"func(func(int))", reflect.TypeOf(func(func(int)) {}), false}, | |
| {"methodIter.Seq", reflect.ValueOf(methodIter{}).MethodByName("Seq").Type(), true}, | |
| {"methodIter.NonSeq", reflect.ValueOf(methodIter{}).MethodByName("NonSeq").Type(), false}, | |
| {"int64", reflect.TypeOf(int64(1)), true}, | |
| {"uint64", reflect.TypeOf(uint64(1)), true}, | |
| {"*[4]int", reflect.TypeOf(&[4]int{}), true}, | |
| {"chan int64", reflect.TypeOf(make(chan int64)), true}, | |
| {"map[int]int", reflect.TypeOf(make(map[int]int)), true}, | |
| {"string", reflect.TypeOf(""), true}, | |
| {"[]int", reflect.TypeOf([]int{}), true}, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| if got := tt.tr.CanSeq(); got != tt.want { | |
| t.Errorf("Type.CanSeq() = %v, want %v", got, tt.want) | |
| } | |
| }) | |
| } | |
| } | |
| func TestType_CanSeq2(t *testing.T) { | |
| tests := []struct { | |
| name string | |
| tr reflect.Type | |
| want bool | |
| }{ | |
| {"func(func(int, int) bool)", reflect.TypeOf(func(func(int, int) bool) {}), true}, | |
| {"func(func(int, int))", reflect.TypeOf(func(func(int, int)) {}), false}, | |
| {"methodIter2.Seq2", reflect.ValueOf(methodIter2{}).MethodByName("Seq2").Type(), true}, | |
| {"methodIter2.NonSeq2", reflect.ValueOf(methodIter2{}).MethodByName("NonSeq2").Type(), false}, | |
| {"int64", reflect.TypeOf(int64(1)), false}, | |
| {"uint64", reflect.TypeOf(uint64(1)), false}, | |
| {"*[4]int", reflect.TypeOf(&[4]int{}), true}, | |
| {"chan int64", reflect.TypeOf(make(chan int64)), false}, | |
| {"map[int]int", reflect.TypeOf(make(map[int]int)), true}, | |
| {"string", reflect.TypeOf(""), true}, | |
| {"[]int", reflect.TypeOf([]int{}), true}, | |
| } | |
| for _, tt := range tests { | |
| t.Run(tt.name, func(t *testing.T) { | |
| if got := tt.tr.CanSeq2(); got != tt.want { | |
| t.Errorf("Type.CanSeq2() = %v, want %v", got, tt.want) | |
| } | |
| }) | |
| } | |
| } |