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