...

Source file src/reflect/set_test.go

Documentation: reflect

		 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  }
	 227  

View as plain text