github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/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 {pkgpath: "escapeinfo", name: "NewT", want: "func NewT(data []byte) *T"}, 106 } 107 108 func TestGoxImporter(t *testing.T) { 109 testenv.MustHaveGoBuild(t) 110 111 initmap := make(map[*types.Package]InitData) 112 imp := GetImporter([]string{"testdata"}, initmap) 113 114 for _, test := range importerTests { 115 runImporterTest(t, imp, initmap, &test) 116 } 117 } 118 119 func TestObjImporter(t *testing.T) { 120 testenv.MustHaveGoBuild(t) 121 122 // This test relies on gccgo being around, which it most likely will be if we 123 // were compiled with gccgo. 124 if runtime.Compiler != "gccgo" { 125 t.Skip("This test needs gccgo") 126 } 127 128 tmpdir, err := ioutil.TempDir("", "") 129 if err != nil { 130 t.Fatal(err) 131 } 132 initmap := make(map[*types.Package]InitData) 133 imp := GetImporter([]string{tmpdir}, initmap) 134 135 artmpdir, err := ioutil.TempDir("", "") 136 if err != nil { 137 t.Fatal(err) 138 } 139 arinitmap := make(map[*types.Package]InitData) 140 arimp := GetImporter([]string{artmpdir}, arinitmap) 141 142 for _, test := range importerTests { 143 gofile := filepath.Join("testdata", test.pkgpath+".go") 144 ofile := filepath.Join(tmpdir, test.pkgpath+".o") 145 afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a") 146 147 cmd := exec.Command("gccgo", "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile) 148 out, err := cmd.CombinedOutput() 149 if err != nil { 150 t.Logf("%s", out) 151 t.Fatalf("gccgo %s failed: %s", gofile, err) 152 } 153 154 runImporterTest(t, imp, initmap, &test) 155 156 cmd = exec.Command("ar", "cr", afile, ofile) 157 out, err = cmd.CombinedOutput() 158 if err != nil { 159 t.Logf("%s", out) 160 t.Fatalf("ar cr %s %s failed: %s", afile, ofile, err) 161 } 162 163 runImporterTest(t, arimp, arinitmap, &test) 164 165 if err = os.Remove(ofile); err != nil { 166 t.Fatal(err) 167 } 168 if err = os.Remove(afile); err != nil { 169 t.Fatal(err) 170 } 171 } 172 173 if err = os.Remove(tmpdir); err != nil { 174 t.Fatal(err) 175 } 176 }