github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/reflect/set_test.go (about) 1 // Copyright 2011 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 "bytes" 9 "go/ast" 10 "go/token" 11 "io" 12 . "reflect" 13 "testing" 14 "unsafe" 15 ) 16 17 func TestImplicitMapConversion(t *testing.T) { 18 // Test implicit conversions in MapIndex and SetMapIndex. 19 { 20 // direct 21 m := make(map[int]int) 22 mv := ValueOf(m) 23 mv.SetMapIndex(ValueOf(1), ValueOf(2)) 24 x, ok := m[1] 25 if x != 2 { 26 t.Errorf("#1 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 27 } 28 if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 29 t.Errorf("#1 MapIndex(1) = %d", n) 30 } 31 } 32 { 33 // convert interface key 34 m := make(map[interface{}]int) 35 mv := ValueOf(m) 36 mv.SetMapIndex(ValueOf(1), ValueOf(2)) 37 x, ok := m[1] 38 if x != 2 { 39 t.Errorf("#2 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 40 } 41 if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 42 t.Errorf("#2 MapIndex(1) = %d", n) 43 } 44 } 45 { 46 // convert interface value 47 m := make(map[int]interface{}) 48 mv := ValueOf(m) 49 mv.SetMapIndex(ValueOf(1), ValueOf(2)) 50 x, ok := m[1] 51 if x != 2 { 52 t.Errorf("#3 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 53 } 54 if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 55 t.Errorf("#3 MapIndex(1) = %d", n) 56 } 57 } 58 { 59 // convert both interface key and interface value 60 m := make(map[interface{}]interface{}) 61 mv := ValueOf(m) 62 mv.SetMapIndex(ValueOf(1), ValueOf(2)) 63 x, ok := m[1] 64 if x != 2 { 65 t.Errorf("#4 after SetMapIndex(1,2): %d, %t (map=%v)", x, ok, m) 66 } 67 if n := mv.MapIndex(ValueOf(1)).Interface().(int); n != 2 { 68 t.Errorf("#4 MapIndex(1) = %d", n) 69 } 70 } 71 { 72 // convert both, with non-empty interfaces 73 m := make(map[io.Reader]io.Writer) 74 mv := ValueOf(m) 75 b1 := new(bytes.Buffer) 76 b2 := new(bytes.Buffer) 77 mv.SetMapIndex(ValueOf(b1), ValueOf(b2)) 78 x, ok := m[b1] 79 if x != b2 { 80 t.Errorf("#5 after SetMapIndex(b1, b2): %p (!= %p), %t (map=%v)", x, b2, ok, m) 81 } 82 if p := mv.MapIndex(ValueOf(b1)).Elem().Pointer(); p != uintptr(unsafe.Pointer(b2)) { 83 t.Errorf("#5 MapIndex(b1) = %#x want %p", p, b2) 84 } 85 } 86 { 87 // convert channel direction 88 m := make(map[<-chan int]chan int) 89 mv := ValueOf(m) 90 c1 := make(chan int) 91 c2 := make(chan int) 92 mv.SetMapIndex(ValueOf(c1), ValueOf(c2)) 93 x, ok := m[c1] 94 if x != c2 { 95 t.Errorf("#6 after SetMapIndex(c1, c2): %p (!= %p), %t (map=%v)", x, c2, ok, m) 96 } 97 if p := mv.MapIndex(ValueOf(c1)).Pointer(); p != ValueOf(c2).Pointer() { 98 t.Errorf("#6 MapIndex(c1) = %#x want %p", p, c2) 99 } 100 } 101 { 102 // convert identical underlying types 103 type MyBuffer bytes.Buffer 104 m := make(map[*MyBuffer]*bytes.Buffer) 105 mv := ValueOf(m) 106 b1 := new(MyBuffer) 107 b2 := new(bytes.Buffer) 108 mv.SetMapIndex(ValueOf(b1), ValueOf(b2)) 109 x, ok := m[b1] 110 if x != b2 { 111 t.Errorf("#7 after SetMapIndex(b1, b2): %p (!= %p), %t (map=%v)", x, b2, ok, m) 112 } 113 if p := mv.MapIndex(ValueOf(b1)).Pointer(); p != uintptr(unsafe.Pointer(b2)) { 114 t.Errorf("#7 MapIndex(b1) = %#x want %p", p, b2) 115 } 116 } 117 118 } 119 120 func TestImplicitSetConversion(t *testing.T) { 121 // Assume TestImplicitMapConversion covered the basics. 122 // Just make sure conversions are being applied at all. 123 var r io.Reader 124 b := new(bytes.Buffer) 125 rv := ValueOf(&r).Elem() 126 rv.Set(ValueOf(b)) 127 if r != b { 128 t.Errorf("after Set: r=%T(%v)", r, r) 129 } 130 } 131 132 func TestImplicitSendConversion(t *testing.T) { 133 c := make(chan io.Reader, 10) 134 b := new(bytes.Buffer) 135 ValueOf(c).Send(ValueOf(b)) 136 if bb := <-c; bb != b { 137 t.Errorf("Received %p != %p", bb, b) 138 } 139 } 140 141 func TestImplicitCallConversion(t *testing.T) { 142 // Arguments must be assignable to parameter types. 143 fv := ValueOf(io.WriteString) 144 b := new(bytes.Buffer) 145 fv.Call([]Value{ValueOf(b), ValueOf("hello world")}) 146 if b.String() != "hello world" { 147 t.Errorf("After call: string=%q want %q", b.String(), "hello world") 148 } 149 } 150 151 func TestImplicitAppendConversion(t *testing.T) { 152 // Arguments must be assignable to the slice's element type. 153 s := []io.Reader{} 154 sv := ValueOf(&s).Elem() 155 b := new(bytes.Buffer) 156 sv.Set(Append(sv, ValueOf(b))) 157 if len(s) != 1 || s[0] != b { 158 t.Errorf("after append: s=%v want [%p]", s, b) 159 } 160 } 161 162 var implementsTests = []struct { 163 x interface{} 164 t interface{} 165 b bool 166 }{ 167 {new(*bytes.Buffer), new(io.Reader), true}, 168 {new(bytes.Buffer), new(io.Reader), false}, 169 {new(*bytes.Buffer), new(io.ReaderAt), false}, 170 {new(*ast.Ident), new(ast.Expr), true}, 171 {new(*notAnExpr), new(ast.Expr), false}, 172 {new(*ast.Ident), new(notASTExpr), false}, 173 {new(notASTExpr), new(ast.Expr), false}, 174 {new(ast.Expr), new(notASTExpr), false}, 175 {new(*notAnExpr), new(notASTExpr), true}, 176 } 177 178 type notAnExpr struct{} 179 180 func (notAnExpr) Pos() token.Pos { return token.NoPos } 181 func (notAnExpr) End() token.Pos { return token.NoPos } 182 func (notAnExpr) exprNode() {} 183 184 type notASTExpr interface { 185 Pos() token.Pos 186 End() token.Pos 187 exprNode() 188 } 189 190 func TestImplements(t *testing.T) { 191 for _, tt := range implementsTests { 192 xv := TypeOf(tt.x).Elem() 193 xt := TypeOf(tt.t).Elem() 194 if b := xv.Implements(xt); b != tt.b { 195 t.Errorf("(%s).Implements(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b) 196 } 197 } 198 } 199 200 var assignableTests = []struct { 201 x interface{} 202 t interface{} 203 b bool 204 }{ 205 {new(chan int), new(<-chan int), true}, 206 {new(<-chan int), new(chan int), false}, 207 {new(*int), new(IntPtr), true}, 208 {new(IntPtr), new(*int), true}, 209 {new(IntPtr), new(IntPtr1), false}, 210 {new(Ch), new(<-chan interface{}), true}, 211 // test runs implementsTests too 212 } 213 214 type IntPtr *int 215 type IntPtr1 *int 216 type Ch <-chan interface{} 217 218 func TestAssignableTo(t *testing.T) { 219 for _, tt := range append(assignableTests, implementsTests...) { 220 xv := TypeOf(tt.x).Elem() 221 xt := TypeOf(tt.t).Elem() 222 if b := xv.AssignableTo(xt); b != tt.b { 223 t.Errorf("(%s).AssignableTo(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b) 224 } 225 } 226 }