Source file src/reflect/type_test.go

     1  // Copyright 2023 The Go 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 reflect_test
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  )
    11  
    12  func TestTypeFor(t *testing.T) {
    13  	type (
    14  		mystring string
    15  		myiface  interface{}
    16  	)
    17  
    18  	testcases := []struct {
    19  		wantFrom any
    20  		got      reflect.Type
    21  	}{
    22  		{new(int), reflect.TypeFor[int]()},
    23  		{new(int64), reflect.TypeFor[int64]()},
    24  		{new(string), reflect.TypeFor[string]()},
    25  		{new(mystring), reflect.TypeFor[mystring]()},
    26  		{new(any), reflect.TypeFor[any]()},
    27  		{new(myiface), reflect.TypeFor[myiface]()},
    28  	}
    29  	for _, tc := range testcases {
    30  		want := reflect.ValueOf(tc.wantFrom).Elem().Type()
    31  		if want != tc.got {
    32  			t.Errorf("unexpected reflect.Type: got %v; want %v", tc.got, want)
    33  		}
    34  	}
    35  }
    36  
    37  func TestStructOfEmbeddedIfaceMethodCall(t *testing.T) {
    38  	type Named interface {
    39  		Name() string
    40  	}
    41  
    42  	typ := reflect.StructOf([]reflect.StructField{
    43  		{
    44  			Anonymous: true,
    45  			Name:      "Named",
    46  			Type:      reflect.TypeFor[Named](),
    47  		},
    48  	})
    49  
    50  	v := reflect.New(typ).Elem()
    51  	v.Field(0).Set(
    52  		reflect.ValueOf(reflect.TypeFor[string]()),
    53  	)
    54  
    55  	x := v.Interface().(Named)
    56  	shouldPanic("StructOf does not support methods of embedded interfaces", func() {
    57  		_ = x.Name()
    58  	})
    59  }
    60  
    61  func TestIsRegularMemory(t *testing.T) {
    62  	type args struct {
    63  		t reflect.Type
    64  	}
    65  	type S struct {
    66  		int
    67  	}
    68  	tests := []struct {
    69  		name string
    70  		args args
    71  		want bool
    72  	}{
    73  		{"struct{i int}", args{reflect.TypeOf(struct{ i int }{})}, true},
    74  		{"struct{}", args{reflect.TypeOf(struct{}{})}, true},
    75  		{"struct{i int; s S}", args{reflect.TypeOf(struct {
    76  			i int
    77  			s S
    78  		}{})}, true},
    79  		{"map[int][int]", args{reflect.TypeOf(map[int]int{})}, false},
    80  		{"[4]chan int", args{reflect.TypeOf([4]chan int{})}, true},
    81  		{"[0]struct{_ S}", args{reflect.TypeOf([0]struct {
    82  			_ S
    83  		}{})}, true},
    84  		{"struct{i int; _ S}", args{reflect.TypeOf(struct {
    85  			i int
    86  			_ S
    87  		}{})}, false},
    88  		{"struct{a int16; b int32}", args{reflect.TypeOf(struct {
    89  			a int16
    90  			b int32
    91  		}{})}, false},
    92  		{"struct {x int32; y int16}", args{reflect.TypeOf(struct {
    93  			x int32
    94  			y int16
    95  		}{})}, false},
    96  		{"struct {_ int32 }", args{reflect.TypeOf(struct{ _ int32 }{})}, false},
    97  	}
    98  	for _, tt := range tests {
    99  		t.Run(tt.name, func(t *testing.T) {
   100  			if got := reflect.IsRegularMemory(tt.args.t); got != tt.want {
   101  				t.Errorf("isRegularMemory() = %v, want %v", got, tt.want)
   102  			}
   103  		})
   104  	}
   105  }
   106  
   107  var sinkType reflect.Type
   108  
   109  func BenchmarkTypeForString(b *testing.B) {
   110  	for i := 0; i < b.N; i++ {
   111  		sinkType = reflect.TypeFor[string]()
   112  	}
   113  }
   114  
   115  func BenchmarkTypeForError(b *testing.B) {
   116  	for i := 0; i < b.N; i++ {
   117  		sinkType = reflect.TypeFor[error]()
   118  	}
   119  }
   120  
   121  func TestType_CanSeq(t *testing.T) {
   122  	tests := []struct {
   123  		name string
   124  		tr   reflect.Type
   125  		want bool
   126  	}{
   127  		{"func(func(int) bool)", reflect.TypeOf(func(func(int) bool) {}), true},
   128  		{"func(func(int))", reflect.TypeOf(func(func(int)) {}), false},
   129  		{"int64", reflect.TypeOf(int64(1)), true},
   130  		{"uint64", reflect.TypeOf(uint64(1)), true},
   131  		{"*[4]int", reflect.TypeOf(&[4]int{}), true},
   132  		{"chan int64", reflect.TypeOf(make(chan int64)), true},
   133  		{"map[int]int", reflect.TypeOf(make(map[int]int)), true},
   134  		{"string", reflect.TypeOf(""), true},
   135  		{"[]int", reflect.TypeOf([]int{}), true},
   136  	}
   137  	for _, tt := range tests {
   138  		t.Run(tt.name, func(t *testing.T) {
   139  			if got := tt.tr.CanSeq(); got != tt.want {
   140  				t.Errorf("Type.CanSeq() = %v, want %v", got, tt.want)
   141  			}
   142  		})
   143  	}
   144  }
   145  
   146  func TestType_CanSeq2(t *testing.T) {
   147  	tests := []struct {
   148  		name string
   149  		tr   reflect.Type
   150  		want bool
   151  	}{
   152  		{"func(func(int, int) bool)", reflect.TypeOf(func(func(int, int) bool) {}), true},
   153  		{"func(func(int, int))", reflect.TypeOf(func(func(int, int)) {}), false},
   154  		{"int64", reflect.TypeOf(int64(1)), false},
   155  		{"uint64", reflect.TypeOf(uint64(1)), false},
   156  		{"*[4]int", reflect.TypeOf(&[4]int{}), true},
   157  		{"chan int64", reflect.TypeOf(make(chan int64)), false},
   158  		{"map[int]int", reflect.TypeOf(make(map[int]int)), true},
   159  		{"string", reflect.TypeOf(""), true},
   160  		{"[]int", reflect.TypeOf([]int{}), true},
   161  	}
   162  	for _, tt := range tests {
   163  		t.Run(tt.name, func(t *testing.T) {
   164  			if got := tt.tr.CanSeq2(); got != tt.want {
   165  				t.Errorf("Type.CanSeq2() = %v, want %v", got, tt.want)
   166  			}
   167  		})
   168  	}
   169  }
   170  

View as plain text