...

Source file src/internal/reflectlite/all_test.go

Documentation: internal/reflectlite

     1  // Copyright 2009 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 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  	// {struct {
   155  	// 	x (interface {
   156  	// 		a(func(func(int) int) func(func(int)) int)
   157  	// 		b()
   158  	// 	})
   159  	// }{},
   160  	// 	"interface { reflectlite_test.a(func(func(int) int) func(func(int)) int); reflectlite_test.b() }",
   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  	// assert(t, TypeString(v2.Type()), "interface {}")
   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  // Simple functions for DeepEqual tests.
   505  var (
   506  	fn1 func()             // nil.
   507  	fn2 func()             // nil.
   508  	fn3 = func() { fn1() } // Not nil.
   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  	// Equalities
   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  	// Inequalities
   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  	// Nil vs empty: not the same.
   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  	// Mismatched types
   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  	// Possible loops.
   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  	// Special case for nil
   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  	// These implement IsNil.
   626  	// Wrap in extra struct to hide interface type.
   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() // panics if not okay to call
   640  	}
   641  
   642  	// Check the implementations
   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  // Indirect returns the value that v points to.
   687  // If v is a nil pointer, Indirect returns a zero Value.
   688  // If v is not a pointer, Indirect returns v.
   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  // This will be index 0.
   708  func (p Point) AnotherMethod(scale int) int {
   709  	return -1
   710  }
   711  
   712  // This will be index 1.
   713  func (p Point) Dist(scale int) int {
   714  	//println("Point.Dist", p.x, p.y, scale)
   715  	return p.x*p.x*scale + p.y*p.y*scale
   716  }
   717  
   718  // This will be index 2.
   719  func (p Point) GCMethod(k int) int {
   720  	runtime.GC()
   721  	return k + p.x
   722  }
   723  
   724  // This will be index 3.
   725  func (p Point) NoArgs() {
   726  	// Exercise no-argument/no-result paths.
   727  }
   728  
   729  // This will be index 4.
   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 // Should call Sqrt, but it's just a test.
   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  	// not addressable
   860  	v := ValueOf(T{})
   861  	bad(func() { clear(Field(v, 0)) })                     // .X
   862  	bad(func() { clear(Field(v, 1)) })                     // .t1
   863  	bad(func() { clear(Field(Field(v, 1), 0)) })           // .t1.Y
   864  	bad(func() { clear(Field(Field(v, 1), 1)) })           // .t1.t0
   865  	bad(func() { clear(Field(Field(Field(v, 1), 1), 0)) }) // .t1.t0.W
   866  	bad(func() { clear(Field(v, 2)) })                     // .T2
   867  	bad(func() { clear(Field(Field(v, 2), 0)) })           // .T2.Z
   868  	bad(func() { clear(Field(Field(v, 2), 1)) })           // .T2.namedT0
   869  	bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) }) // .T2.namedT0.W
   870  	bad(func() { clear(Field(v, 3)) })                     // .NamedT1
   871  	bad(func() { clear(Field(Field(v, 3), 0)) })           // .NamedT1.Y
   872  	bad(func() { clear(Field(Field(v, 3), 1)) })           // .NamedT1.t0
   873  	bad(func() { clear(Field(Field(Field(v, 3), 1), 0)) }) // .NamedT1.t0.W
   874  	bad(func() { clear(Field(v, 4)) })                     // .NamedT2
   875  	bad(func() { clear(Field(Field(v, 4), 0)) })           // .NamedT2.Z
   876  	bad(func() { clear(Field(Field(v, 4), 1)) })           // .NamedT2.namedT0
   877  	bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) }) // .NamedT2.namedT0.W
   878  	bad(func() { clear(Field(v, 5)) })                     // .namedT1
   879  	bad(func() { clear(Field(Field(v, 5), 0)) })           // .namedT1.Y
   880  	bad(func() { clear(Field(Field(v, 5), 1)) })           // .namedT1.t0
   881  	bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) }) // .namedT1.t0.W
   882  	bad(func() { clear(Field(v, 6)) })                     // .namedT2
   883  	bad(func() { clear(Field(Field(v, 6), 0)) })           // .namedT2.Z
   884  	bad(func() { clear(Field(Field(v, 6), 1)) })           // .namedT2.namedT0
   885  	bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) }) // .namedT2.namedT0.W
   886  
   887  	// addressable
   888  	v = ValueOf(&T{}).Elem()
   889  	ok(func() { clear(Field(v, 0)) })                      // .X
   890  	bad(func() { clear(Field(v, 1)) })                     // .t1
   891  	ok(func() { clear(Field(Field(v, 1), 0)) })            // .t1.Y
   892  	bad(func() { clear(Field(Field(v, 1), 1)) })           // .t1.t0
   893  	ok(func() { clear(Field(Field(Field(v, 1), 1), 0)) })  // .t1.t0.W
   894  	ok(func() { clear(Field(v, 2)) })                      // .T2
   895  	ok(func() { clear(Field(Field(v, 2), 0)) })            // .T2.Z
   896  	bad(func() { clear(Field(Field(v, 2), 1)) })           // .T2.namedT0
   897  	bad(func() { clear(Field(Field(Field(v, 2), 1), 0)) }) // .T2.namedT0.W
   898  	ok(func() { clear(Field(v, 3)) })                      // .NamedT1
   899  	ok(func() { clear(Field(Field(v, 3), 0)) })            // .NamedT1.Y
   900  	bad(func() { clear(Field(Field(v, 3), 1)) })           // .NamedT1.t0
   901  	ok(func() { clear(Field(Field(Field(v, 3), 1), 0)) })  // .NamedT1.t0.W
   902  	ok(func() { clear(Field(v, 4)) })                      // .NamedT2
   903  	ok(func() { clear(Field(Field(v, 4), 0)) })            // .NamedT2.Z
   904  	bad(func() { clear(Field(Field(v, 4), 1)) })           // .NamedT2.namedT0
   905  	bad(func() { clear(Field(Field(Field(v, 4), 1), 0)) }) // .NamedT2.namedT0.W
   906  	bad(func() { clear(Field(v, 5)) })                     // .namedT1
   907  	bad(func() { clear(Field(Field(v, 5), 0)) })           // .namedT1.Y
   908  	bad(func() { clear(Field(Field(v, 5), 1)) })           // .namedT1.t0
   909  	bad(func() { clear(Field(Field(Field(v, 5), 1), 0)) }) // .namedT1.t0.W
   910  	bad(func() { clear(Field(v, 6)) })                     // .namedT2
   911  	bad(func() { clear(Field(Field(v, 6), 0)) })           // .namedT2.Z
   912  	bad(func() { clear(Field(Field(v, 6), 1)) })           // .namedT2.namedT0
   913  	bad(func() { clear(Field(Field(Field(v, 6), 1), 0)) }) // .namedT2.namedT0.W
   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  	// Used to have inconsistency between IsValid() and Kind() != Invalid.
   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  // TestUnaddressableField tests that the reflect package will not allow
   992  // a type from another package to be used as a named type with an
   993  // unexported field.
   994  //
   995  // This ensures that unexported fields cannot be modified by other packages.
   996  func TestUnaddressableField(t *testing.T) {
   997  	var b Buffer // type defined in reflect, a different package
   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