github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/go/internal/gccgoimporter/importer_test.go (about) 1 // Copyright 2013 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 gccgoimporter 6 7 import ( 8 "go/types" 9 "internal/testenv" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "path/filepath" 14 "runtime" 15 "testing" 16 ) 17 18 type importerTest struct { 19 pkgpath, name, want, wantval string 20 wantinits []string 21 } 22 23 func runImporterTest(t *testing.T, imp Importer, initmap map[*types.Package]InitData, test *importerTest) { 24 pkg, err := imp(make(map[string]*types.Package), test.pkgpath, ".", nil) 25 if err != nil { 26 t.Error(err) 27 return 28 } 29 30 if test.name != "" { 31 obj := pkg.Scope().Lookup(test.name) 32 if obj == nil { 33 t.Errorf("%s: object not found", test.name) 34 return 35 } 36 37 got := types.ObjectString(obj, types.RelativeTo(pkg)) 38 if got != test.want { 39 t.Errorf("%s: got %q; want %q", test.name, got, test.want) 40 } 41 42 if test.wantval != "" { 43 gotval := obj.(*types.Const).Val().String() 44 if gotval != test.wantval { 45 t.Errorf("%s: got val %q; want val %q", test.name, gotval, test.wantval) 46 } 47 } 48 } 49 50 if len(test.wantinits) > 0 { 51 initdata := initmap[pkg] 52 found := false 53 // Check that the package's own init function has the package's priority 54 for _, pkginit := range initdata.Inits { 55 if pkginit.InitFunc == test.wantinits[0] { 56 if initdata.Priority != pkginit.Priority { 57 t.Errorf("%s: got self priority %d; want %d", test.pkgpath, pkginit.Priority, initdata.Priority) 58 } 59 found = true 60 break 61 } 62 } 63 64 if !found { 65 t.Errorf("%s: could not find expected function %q", test.pkgpath, test.wantinits[0]) 66 } 67 68 // Each init function in the list other than the first one is a 69 // dependency of the function immediately before it. Check that 70 // the init functions appear in descending priority order. 71 priority := initdata.Priority 72 for _, wantdepinit := range test.wantinits[1:] { 73 found = false 74 for _, pkginit := range initdata.Inits { 75 if pkginit.InitFunc == wantdepinit { 76 if priority <= pkginit.Priority { 77 t.Errorf("%s: got dep priority %d; want less than %d", test.pkgpath, pkginit.Priority, priority) 78 } 79 found = true 80 priority = pkginit.Priority 81 break 82 } 83 } 84 85 if !found { 86 t.Errorf("%s: could not find expected function %q", test.pkgpath, wantdepinit) 87 } 88 } 89 } 90 } 91 92 var importerTests = [...]importerTest{ 93 {pkgpath: "pointer", name: "Int8Ptr", want: "type Int8Ptr *int8"}, 94 {pkgpath: "complexnums", name: "NN", want: "const NN untyped complex", wantval: "(-1 + -1i)"}, 95 {pkgpath: "complexnums", name: "NP", want: "const NP untyped complex", wantval: "(-1 + 1i)"}, 96 {pkgpath: "complexnums", name: "PN", want: "const PN untyped complex", wantval: "(1 + -1i)"}, 97 {pkgpath: "complexnums", name: "PP", want: "const PP untyped complex", wantval: "(1 + 1i)"}, 98 {pkgpath: "conversions", name: "Bits", want: "const Bits Units", wantval: `"bits"`}, 99 {pkgpath: "time", name: "Duration", want: "type Duration int64"}, 100 {pkgpath: "time", name: "Nanosecond", want: "const Nanosecond Duration", wantval: "1"}, 101 {pkgpath: "unicode", name: "IsUpper", want: "func IsUpper(r rune) bool"}, 102 {pkgpath: "unicode", name: "MaxRune", want: "const MaxRune untyped rune", wantval: "1114111"}, 103 {pkgpath: "imports", wantinits: []string{"imports..import", "fmt..import", "math..import"}}, 104 {pkgpath: "alias", name: "IntAlias2", want: "type IntAlias2 = Int"}, 105 } 106 107 func TestGoxImporter(t *testing.T) { 108 testenv.MustHaveGoBuild(t) 109 110 initmap := make(map[*types.Package]InitData) 111 imp := GetImporter([]string{"testdata"}, initmap) 112 113 for _, test := range importerTests { 114 runImporterTest(t, imp, initmap, &test) 115 } 116 } 117 118 func TestObjImporter(t *testing.T) { 119 testenv.MustHaveGoBuild(t) 120 121 // This test relies on gccgo being around, which it most likely will be if we 122 // were compiled with gccgo. 123 if runtime.Compiler != "gccgo" { 124 t.Skip("This test needs gccgo") 125 } 126 127 tmpdir, err := ioutil.TempDir("", "") 128 if err != nil { 129 t.Fatal(err) 130 } 131 initmap := make(map[*types.Package]InitData) 132 imp := GetImporter([]string{tmpdir}, initmap) 133 134 artmpdir, err := ioutil.TempDir("", "") 135 if err != nil { 136 t.Fatal(err) 137 } 138 arinitmap := make(map[*types.Package]InitData) 139 arimp := GetImporter([]string{artmpdir}, arinitmap) 140 141 for _, test := range importerTests { 142 gofile := filepath.Join("testdata", test.pkgpath+".go") 143 ofile := filepath.Join(tmpdir, test.pkgpath+".o") 144 afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a") 145 146 cmd := exec.Command("gccgo", "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile) 147 out, err := cmd.CombinedOutput() 148 if err != nil { 149 t.Logf("%s", out) 150 t.Fatalf("gccgo %s failed: %s", gofile, err) 151 } 152 153 runImporterTest(t, imp, initmap, &test) 154 155 cmd = exec.Command("ar", "cr", afile, ofile) 156 out, err = cmd.CombinedOutput() 157 if err != nil { 158 t.Logf("%s", out) 159 t.Fatalf("ar cr %s %s failed: %s", afile, ofile, err) 160 } 161 162 runImporterTest(t, arimp, arinitmap, &test) 163 164 if err = os.Remove(ofile); err != nil { 165 t.Fatal(err) 166 } 167 if err = os.Remove(afile); err != nil { 168 t.Fatal(err) 169 } 170 } 171 172 if err = os.Remove(tmpdir); err != nil { 173 t.Fatal(err) 174 } 175 }