github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/types/typestring_test.go (about) 1 // Copyright 2012 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 types_test 6 7 import ( 8 "go/ast" 9 "go/importer" 10 "go/parser" 11 "go/token" 12 "testing" 13 14 . "go/types" 15 ) 16 17 const filename = "<src>" 18 19 func makePkg(t *testing.T, src string) (*Package, error) { 20 fset := token.NewFileSet() 21 file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) 22 if err != nil { 23 return nil, err 24 } 25 // use the package name as package path 26 conf := Config{Importer: importer.Default()} 27 return conf.Check(file.Name.Name, fset, []*ast.File{file}, nil) 28 } 29 30 type testEntry struct { 31 src, str string 32 } 33 34 // dup returns a testEntry where both src and str are the same. 35 func dup(s string) testEntry { 36 return testEntry{s, s} 37 } 38 39 // types that don't depend on any other type declarations 40 var independentTestTypes = []testEntry{ 41 // basic types 42 dup("int"), 43 dup("float32"), 44 dup("string"), 45 46 // arrays 47 dup("[10]int"), 48 49 // slices 50 dup("[]int"), 51 dup("[][]int"), 52 53 // structs 54 dup("struct{}"), 55 dup("struct{x int}"), 56 {`struct { 57 x, y int 58 z float32 "foo" 59 }`, `struct{x int; y int; z float32 "foo"}`}, 60 {`struct { 61 string 62 elems []complex128 63 }`, `struct{string; elems []complex128}`}, 64 65 // pointers 66 dup("*int"), 67 dup("***struct{}"), 68 dup("*struct{a int; b float32}"), 69 70 // functions 71 dup("func()"), 72 dup("func(x int)"), 73 {"func(x, y int)", "func(x int, y int)"}, 74 {"func(x, y int, z string)", "func(x int, y int, z string)"}, 75 dup("func(int)"), 76 {"func(int, string, byte)", "func(int, string, byte)"}, 77 78 dup("func() int"), 79 {"func() (string)", "func() string"}, 80 dup("func() (u int)"), 81 {"func() (u, v int, w string)", "func() (u int, v int, w string)"}, 82 83 dup("func(int) string"), 84 dup("func(x int) string"), 85 dup("func(x int) (u string)"), 86 {"func(x, y int) (u string)", "func(x int, y int) (u string)"}, 87 88 dup("func(...int) string"), 89 dup("func(x ...int) string"), 90 dup("func(x ...int) (u string)"), 91 {"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"}, 92 93 // interfaces 94 dup("interface{}"), 95 dup("interface{m()}"), 96 dup(`interface{String() string; m(int) float32}`), 97 98 // maps 99 dup("map[string]int"), 100 {"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"}, 101 102 // channels 103 dup("chan<- chan int"), 104 dup("chan<- <-chan int"), 105 dup("<-chan <-chan int"), 106 dup("chan (<-chan int)"), 107 dup("chan<- func()"), 108 dup("<-chan []func() int"), 109 } 110 111 // types that depend on other type declarations (src in TestTypes) 112 var dependentTestTypes = []testEntry{ 113 // interfaces 114 dup(`interface{io.Reader; io.Writer}`), 115 dup(`interface{m() int; io.Writer}`), 116 {`interface{m() interface{T}}`, `interface{m() interface{p.T}}`}, 117 } 118 119 func TestTypeString(t *testing.T) { 120 skipSpecialPlatforms(t) 121 122 var tests []testEntry 123 tests = append(tests, independentTestTypes...) 124 tests = append(tests, dependentTestTypes...) 125 126 for _, test := range tests { 127 src := `package p; import "io"; type _ io.Writer; type T ` + test.src 128 pkg, err := makePkg(t, src) 129 if err != nil { 130 t.Errorf("%s: %s", src, err) 131 continue 132 } 133 typ := pkg.Scope().Lookup("T").Type().Underlying() 134 if got := typ.String(); got != test.str { 135 t.Errorf("%s: got %s, want %s", test.src, got, test.str) 136 } 137 } 138 } 139 140 func TestQualifiedTypeString(t *testing.T) { 141 p, _ := pkgFor("p.go", "package p; type T int", nil) 142 q, _ := pkgFor("q.go", "package q", nil) 143 144 pT := p.Scope().Lookup("T").Type() 145 for _, test := range []struct { 146 typ Type 147 this *Package 148 want string 149 }{ 150 {pT, nil, "p.T"}, 151 {pT, p, "T"}, 152 {pT, q, "p.T"}, 153 {NewPointer(pT), p, "*T"}, 154 {NewPointer(pT), q, "*p.T"}, 155 } { 156 if got := TypeString(test.this, test.typ); got != test.want { 157 t.Errorf("TypeString(%s, %s) = %s, want %s", 158 test.this, test.typ, got, test.want) 159 } 160 } 161 }