github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/go/internal/srcimporter/srcimporter_test.go (about) 1 // Copyright 2017 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 srcimporter 6 7 import ( 8 "go/build" 9 "go/token" 10 "go/types" 11 "internal/testenv" 12 "io/ioutil" 13 "path" 14 "path/filepath" 15 "runtime" 16 "strings" 17 "testing" 18 "time" 19 ) 20 21 const maxTime = 2 * time.Second 22 23 var importer = New(&build.Default, token.NewFileSet(), make(map[string]*types.Package)) 24 25 func doImport(t *testing.T, path, srcDir string) { 26 t0 := time.Now() 27 if _, err := importer.ImportFrom(path, srcDir, 0); err != nil { 28 // don't report an error if there's no buildable Go files 29 if _, nogo := err.(*build.NoGoError); !nogo { 30 t.Errorf("import %q failed (%v)", path, err) 31 } 32 return 33 } 34 t.Logf("import %q: %v", path, time.Since(t0)) 35 } 36 37 // walkDir imports the all the packages with the given path 38 // prefix recursively. It returns the number of packages 39 // imported and whether importing was aborted because time 40 // has passed endTime. 41 func walkDir(t *testing.T, path string, endTime time.Time) (int, bool) { 42 if time.Now().After(endTime) { 43 t.Log("testing time used up") 44 return 0, true 45 } 46 47 // ignore fake packages and testdata directories 48 if path == "builtin" || path == "unsafe" || strings.HasSuffix(path, "testdata") { 49 return 0, false 50 } 51 52 list, err := ioutil.ReadDir(filepath.Join(runtime.GOROOT(), "src", path)) 53 if err != nil { 54 t.Fatalf("walkDir %s failed (%v)", path, err) 55 } 56 57 nimports := 0 58 hasGoFiles := false 59 for _, f := range list { 60 if f.IsDir() { 61 n, abort := walkDir(t, filepath.Join(path, f.Name()), endTime) 62 nimports += n 63 if abort { 64 return nimports, true 65 } 66 } else if strings.HasSuffix(f.Name(), ".go") { 67 hasGoFiles = true 68 } 69 } 70 71 if hasGoFiles { 72 doImport(t, path, "") 73 nimports++ 74 } 75 76 return nimports, false 77 } 78 79 func TestImportStdLib(t *testing.T) { 80 if !testenv.HasSrc() { 81 t.Skip("no source code available") 82 } 83 84 dt := maxTime 85 if testing.Short() && testenv.Builder() == "" { 86 dt = 500 * time.Millisecond 87 } 88 nimports, _ := walkDir(t, "", time.Now().Add(dt)) // installed packages 89 t.Logf("tested %d imports", nimports) 90 } 91 92 var importedObjectTests = []struct { 93 name string 94 want string 95 }{ 96 {"flag.Bool", "func Bool(name string, value bool, usage string) *bool"}, 97 {"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"}, 98 {"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"}, // go/types.gcCompatibilityMode is off => interface not flattened 99 {"math.Pi", "const Pi untyped float"}, 100 {"math.Sin", "func Sin(x float64) float64"}, 101 {"math/big.Int", "type Int struct{neg bool; abs nat}"}, 102 {"golang_org/x/text/unicode/norm.MaxSegmentSize", "const MaxSegmentSize untyped int"}, 103 } 104 105 func TestImportedTypes(t *testing.T) { 106 if !testenv.HasSrc() { 107 t.Skip("no source code available") 108 } 109 110 for _, test := range importedObjectTests { 111 s := strings.Split(test.name, ".") 112 if len(s) != 2 { 113 t.Fatal("invalid test data format") 114 } 115 importPath := s[0] 116 objName := s[1] 117 118 pkg, err := importer.ImportFrom(importPath, ".", 0) 119 if err != nil { 120 t.Error(err) 121 continue 122 } 123 124 obj := pkg.Scope().Lookup(objName) 125 if obj == nil { 126 t.Errorf("%s: object not found", test.name) 127 continue 128 } 129 130 got := types.ObjectString(obj, types.RelativeTo(pkg)) 131 if got != test.want { 132 t.Errorf("%s: got %q; want %q", test.name, got, test.want) 133 } 134 } 135 } 136 137 func TestReimport(t *testing.T) { 138 if !testenv.HasSrc() { 139 t.Skip("no source code available") 140 } 141 142 // Reimporting a partially imported (incomplete) package is not supported (see issue #19337). 143 // Make sure we recognize the situation and report an error. 144 145 mathPkg := types.NewPackage("math", "math") // incomplete package 146 importer := New(&build.Default, token.NewFileSet(), map[string]*types.Package{mathPkg.Path(): mathPkg}) 147 _, err := importer.ImportFrom("math", ".", 0) 148 if err == nil || !strings.HasPrefix(err.Error(), "reimport") { 149 t.Errorf("got %v; want reimport error", err) 150 } 151 } 152 153 func TestIssue20855(t *testing.T) { 154 if !testenv.HasSrc() { 155 t.Skip("no source code available") 156 } 157 158 pkg, err := importer.ImportFrom("go/internal/srcimporter/testdata/issue20855", ".", 0) 159 if err == nil || !strings.Contains(err.Error(), "missing function body") { 160 t.Fatalf("got unexpected or no error: %v", err) 161 } 162 if pkg == nil { 163 t.Error("got no package despite no hard errors") 164 } 165 } 166 167 func testImportPath(t *testing.T, pkgPath string) { 168 if !testenv.HasSrc() { 169 t.Skip("no source code available") 170 } 171 172 pkgName := path.Base(pkgPath) 173 174 pkg, err := importer.Import(pkgPath) 175 if err != nil { 176 t.Fatal(err) 177 } 178 179 if pkg.Name() != pkgName { 180 t.Errorf("got %q; want %q", pkg.Name(), pkgName) 181 } 182 183 if pkg.Path() != pkgPath { 184 t.Errorf("got %q; want %q", pkg.Path(), pkgPath) 185 } 186 } 187 188 // TestIssue23092 tests relative imports. 189 func TestIssue23092(t *testing.T) { 190 testImportPath(t, "./testdata/issue23092") 191 } 192 193 // TestIssue24392 tests imports against a path containing 'testdata'. 194 func TestIssue24392(t *testing.T) { 195 testImportPath(t, "go/internal/srcimporter/testdata/issue24392") 196 }