mirror of https://github.com/golang/go.git
go/packages: move all overlay tests into overlay_test.go
It's hard to see what tests we have for overlays right now. Centralize them all in overlay_test.go. Change-Id: I8e48c2332771a9b73997775780ab14a798a4086b Reviewed-on: https://go-review.googlesource.com/c/tools/+/240184 Reviewed-by: Michael Matloob <matloob@golang.org> Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
b2d8b03366
commit
c138986dd9
|
|
@ -2,13 +2,17 @@ package packages_test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
"golang.org/x/tools/internal/testenv"
|
||||
)
|
||||
|
||||
const commonMode = packages.NeedName | packages.NeedFiles |
|
||||
|
|
@ -212,6 +216,537 @@ func TestHello(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOverlay(t *testing.T) { packagestest.TestAll(t, testOverlay) }
|
||||
func testOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"c/c_test.go": `package c; import "testing"; func TestC(t *testing.T) {}`,
|
||||
"d/d.go": `package d; const D = "d"`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
for i, test := range []struct {
|
||||
overlay map[string][]byte
|
||||
want string // expected value of a.A
|
||||
wantErrs []string
|
||||
}{
|
||||
{nil, `"abc"`, nil}, // default
|
||||
{map[string][]byte{}, `"abc"`, nil}, // empty overlay
|
||||
{map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; const C = "C"`)}, `"abC"`, nil},
|
||||
{map[string][]byte{exported.File("golang.org/fake", "b/b.go"): []byte(`package b; import "golang.org/fake/c"; const B = "B" + c.C`)}, `"aBc"`, nil},
|
||||
// Overlay with an existing file in an existing package adding a new import.
|
||||
{map[string][]byte{exported.File("golang.org/fake", "b/b.go"): []byte(`package b; import "golang.org/fake/d"; const B = "B" + d.D`)}, `"aBd"`, nil},
|
||||
// Overlay with an existing file in an existing package.
|
||||
{map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; import "net/http"; const C = http.MethodGet`)}, `"abGET"`, nil},
|
||||
// Overlay with a new file in an existing package.
|
||||
{map[string][]byte{
|
||||
exported.File("golang.org/fake", "c/c.go"): []byte(`package c;`),
|
||||
filepath.Join(filepath.Dir(exported.File("golang.org/fake", "c/c.go")), "c_new_file.go"): []byte(`package c; const C = "Ç"`)},
|
||||
`"abÇ"`, nil},
|
||||
// Overlay with a new file in an existing package, adding a new dependency to that package.
|
||||
{map[string][]byte{
|
||||
exported.File("golang.org/fake", "c/c.go"): []byte(`package c;`),
|
||||
filepath.Join(filepath.Dir(exported.File("golang.org/fake", "c/c.go")), "c_new_file.go"): []byte(`package c; import "golang.org/fake/d"; const C = "c" + d.D`)},
|
||||
`"abcd"`, nil},
|
||||
} {
|
||||
exported.Config.Overlay = test.overlay
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
initial, err := packages.Load(exported.Config, "golang.org/fake/a")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check value of a.A.
|
||||
a := initial[0]
|
||||
aA := constant(a, "A")
|
||||
if aA == nil {
|
||||
t.Errorf("%d. a.A: got nil", i)
|
||||
continue
|
||||
}
|
||||
got := aA.Val().String()
|
||||
if got != test.want {
|
||||
t.Errorf("%d. a.A: got %s, want %s", i, got, test.want)
|
||||
}
|
||||
|
||||
// Check errors.
|
||||
var errors []packages.Error
|
||||
packages.Visit(initial, nil, func(pkg *packages.Package) {
|
||||
errors = append(errors, pkg.Errors...)
|
||||
})
|
||||
if errs := errorMessages(errors); !reflect.DeepEqual(errs, test.wantErrs) {
|
||||
t.Errorf("%d. got errors %s, want %s", i, errs, test.wantErrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlayDeps(t *testing.T) { packagestest.TestAll(t, testOverlayDeps) }
|
||||
func testOverlayDeps(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"c/c_test.go": `package c; import "testing"; func TestC(t *testing.T) {}`,
|
||||
},
|
||||
}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
exported.Config.Overlay = map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; import "net/http"; const C = http.MethodGet`)}
|
||||
exported.Config.Mode = packages.NeedName |
|
||||
packages.NeedFiles |
|
||||
packages.NeedCompiledGoFiles |
|
||||
packages.NeedImports |
|
||||
packages.NeedDeps |
|
||||
packages.NeedTypesSizes
|
||||
pkgs, err := packages.Load(exported.Config, fmt.Sprintf("file=%s", exported.File("golang.org/fake", "c/c.go")))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Find package golang.org/fake/c
|
||||
sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].ID < pkgs[j].ID })
|
||||
pkgc := pkgs[0]
|
||||
if pkgc.ID != "golang.org/fake/c" {
|
||||
t.Errorf("expected first package in sorted list to be \"golang.org/fake/c\", got %v", pkgc.ID)
|
||||
}
|
||||
|
||||
// Make sure golang.org/fake/c imports net/http, as per the overlay.
|
||||
contains := func(imports map[string]*packages.Package, wantImport string) bool {
|
||||
for imp := range imports {
|
||||
if imp == wantImport {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if !contains(pkgc.Imports, "net/http") {
|
||||
t.Errorf("expected import of %s in package %s, got the following imports: %v",
|
||||
"net/http", pkgc.ID, pkgc.Imports)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewPackagesInOverlay(t *testing.T) { packagestest.TestAll(t, testNewPackagesInOverlay) }
|
||||
func testNewPackagesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"d/d.go": `package d; const D = "d"`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "example.com/extramodule",
|
||||
Files: map[string]interface{}{
|
||||
"pkg/x.go": "package pkg\n",
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
overlay map[string][]byte
|
||||
want string // expected value of e.E
|
||||
}{
|
||||
{"one_file",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/a"; const E = "e" + a.A`)},
|
||||
`"eabc"`},
|
||||
{"multiple_files_same_package",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/a"; const E = "e" + a.A + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
},
|
||||
`"eabc_"`},
|
||||
{"multiple_files_two_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; const F = "f"`),
|
||||
},
|
||||
`"ef_"`},
|
||||
{"multiple_files_three_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; const G = "g"`),
|
||||
},
|
||||
`"efg_"`},
|
||||
{"multiple_files_four_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; import "golang.org/fake/h"; const E = "e" + f.F + h.H + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; const G = "g"`),
|
||||
filepath.Join(dir, "h", "h.go"): []byte(`package h; const H = "h"`),
|
||||
},
|
||||
`"efgh_"`},
|
||||
{"multiple_files_four_packages_again",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; import "golang.org/fake/h"; const G = "g" + h.H`),
|
||||
filepath.Join(dir, "h", "h.go"): []byte(`package h; const H = "h"`),
|
||||
},
|
||||
`"efgh_"`},
|
||||
{"main_overlay",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "main.go"): []byte(`package main; import "golang.org/fake/a"; const E = "e" + a.A; func main(){}`)},
|
||||
`"eabc"`},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
exported.Config.Overlay = test.overlay
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
exported.Config.Logf = t.Logf
|
||||
|
||||
// With an overlay, we don't know the expected import path,
|
||||
// so load with the absolute path of the directory.
|
||||
initial, err := packages.Load(exported.Config, filepath.Join(dir, "e"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check value of e.E.
|
||||
e := initial[0]
|
||||
eE := constant(e, "E")
|
||||
if eE == nil {
|
||||
t.Fatalf("e.E: was nil in %#v", e)
|
||||
}
|
||||
got := eE.Val().String()
|
||||
if got != test.want {
|
||||
t.Fatalf("e.E: got %s, want %s", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can create a package and its test package in an overlay.
|
||||
func TestOverlayNewPackageAndTest(t *testing.T) {
|
||||
packagestest.TestAll(t, testOverlayNewPackageAndTest)
|
||||
}
|
||||
func testOverlayNewPackageAndTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"foo.txt": "placeholder",
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(exported.File("golang.org/fake", "foo.txt"))
|
||||
exported.Config.Overlay = map[string][]byte{
|
||||
filepath.Join(dir, "a.go"): []byte(`package a;`),
|
||||
filepath.Join(dir, "a_test.go"): []byte(`package a; import "testing";`),
|
||||
}
|
||||
initial, err := packages.Load(exported.Config, "file="+filepath.Join(dir, "a.go"), "file="+filepath.Join(dir, "a_test.go"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(initial) != 2 {
|
||||
t.Errorf("got %v packages, wanted %v", len(initial), 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdHocOverlays(t *testing.T) {
|
||||
testenv.NeedsTool(t, "go")
|
||||
|
||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||
// which are outside of $GOPATH and outside of a module.
|
||||
tmp, err := ioutil.TempDir("", "testAdHocOverlays")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
filename := filepath.Join(tmp, "a.go")
|
||||
content := []byte(`package a
|
||||
const A = 1
|
||||
`)
|
||||
|
||||
// Make sure that the user's value of GO111MODULE does not affect test results.
|
||||
for _, go111module := range []string{"off", "auto", "on"} {
|
||||
t.Run("GO111MODULE="+go111module, func(t *testing.T) {
|
||||
config := &packages.Config{
|
||||
Dir: tmp,
|
||||
Env: append(os.Environ(), "GOPACKAGESDRIVER=off", fmt.Sprintf("GO111MODULE=%s", go111module)),
|
||||
Mode: packages.LoadAllSyntax,
|
||||
Overlay: map[string][]byte{
|
||||
filename: content,
|
||||
},
|
||||
Logf: t.Logf,
|
||||
}
|
||||
initial, err := packages.Load(config, fmt.Sprintf("file=%s", filename))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(initial) == 0 {
|
||||
t.Fatalf("no packages for %s", filename)
|
||||
}
|
||||
// Check value of a.A.
|
||||
a := initial[0]
|
||||
if a.Errors != nil {
|
||||
t.Fatalf("a: got errors %+v, want no error", err)
|
||||
}
|
||||
aA := constant(a, "A")
|
||||
if aA == nil {
|
||||
t.Errorf("a.A: got nil")
|
||||
return
|
||||
}
|
||||
got := aA.Val().String()
|
||||
if want := "1"; got != want {
|
||||
t.Errorf("a.A: got %s, want %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestOverlayModFileChanges tests the behavior resulting from having files from
|
||||
// multiple modules in overlays.
|
||||
func TestOverlayModFileChanges(t *testing.T) {
|
||||
testenv.NeedsTool(t, "go")
|
||||
|
||||
// Create two unrelated modules in a temporary directory.
|
||||
tmp, err := ioutil.TempDir("", "tmp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
// mod1 has a dependency on golang.org/x/xerrors.
|
||||
mod1, err := ioutil.TempDir(tmp, "mod1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(mod1, "go.mod"), []byte(`module mod1
|
||||
|
||||
require (
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
)
|
||||
`), 0775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// mod2 does not have any dependencies.
|
||||
mod2, err := ioutil.TempDir(tmp, "mod2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
want := `module mod2
|
||||
|
||||
go 1.11
|
||||
`
|
||||
if err := ioutil.WriteFile(filepath.Join(mod2, "go.mod"), []byte(want), 0775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Run packages.Load on mod2, while passing the contents over mod1/main.go in the overlay.
|
||||
config := &packages.Config{
|
||||
Dir: mod2,
|
||||
Env: append(os.Environ(), "GOPACKAGESDRIVER=off"),
|
||||
Mode: packages.LoadImports,
|
||||
Overlay: map[string][]byte{
|
||||
filepath.Join(mod1, "main.go"): []byte(`package main
|
||||
import "golang.org/x/xerrors"
|
||||
func main() {
|
||||
_ = errors.New("")
|
||||
}
|
||||
`),
|
||||
filepath.Join(mod2, "main.go"): []byte(`package main
|
||||
func main() {}
|
||||
`),
|
||||
},
|
||||
}
|
||||
if _, err := packages.Load(config, fmt.Sprintf("file=%s", filepath.Join(mod2, "main.go"))); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check that mod2/go.mod has not been modified.
|
||||
got, err := ioutil.ReadFile(filepath.Join(mod2, "go.mod"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != want {
|
||||
t.Errorf("expected %s, got %s", want, string(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlayGOPATHVendoring(t *testing.T) {
|
||||
exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"vendor/vendor.com/foo/foo.go": `package foo; const X = "hi"`,
|
||||
"user/user.go": `package user`,
|
||||
},
|
||||
}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
exported.Config.Logf = t.Logf
|
||||
exported.Config.Overlay = map[string][]byte{
|
||||
exported.File("golang.org/fake", "user/user.go"): []byte(`package user; import "vendor.com/foo"; var x = foo.X`),
|
||||
}
|
||||
initial, err := packages.Load(exported.Config, "golang.org/fake/user")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
user := initial[0]
|
||||
if len(user.Imports) != 1 {
|
||||
t.Fatal("no imports for user")
|
||||
}
|
||||
if user.Imports["vendor.com/foo"].Name != "foo" {
|
||||
t.Errorf("failed to load vendored package foo, imports: %#v", user.Imports["vendor.com/foo"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsOverlay(t *testing.T) { packagestest.TestAll(t, testContainsOverlay) }
|
||||
func testContainsOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"`,
|
||||
"c/c.go": `package c`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
bOverlayFile := filepath.Join(filepath.Dir(exported.File("golang.org/fake", "b/b.go")), "b_overlay.go")
|
||||
exported.Config.Mode = packages.LoadImports
|
||||
exported.Config.Overlay = map[string][]byte{bOverlayFile: []byte(`package b;`)}
|
||||
initial, err := packages.Load(exported.Config, "file="+bOverlayFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
graph, _ := importGraph(initial)
|
||||
wantGraph := `
|
||||
* golang.org/fake/b
|
||||
golang.org/fake/c
|
||||
golang.org/fake/b -> golang.org/fake/c
|
||||
`[1:]
|
||||
if graph != wantGraph {
|
||||
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsOverlayXTest(t *testing.T) { packagestest.TestAll(t, testContainsOverlayXTest) }
|
||||
func testContainsOverlayXTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"`,
|
||||
"c/c.go": `package c`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
bOverlayXTestFile := filepath.Join(filepath.Dir(exported.File("golang.org/fake", "b/b.go")), "b_overlay_x_test.go")
|
||||
exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedImports
|
||||
exported.Config.Overlay = map[string][]byte{bOverlayXTestFile: []byte(`package b_test; import "golang.org/fake/b"`)}
|
||||
initial, err := packages.Load(exported.Config, "file="+bOverlayXTestFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
graph, _ := importGraph(initial)
|
||||
wantGraph := `
|
||||
golang.org/fake/b
|
||||
* golang.org/fake/b_test [golang.org/fake/b.test]
|
||||
golang.org/fake/c
|
||||
golang.org/fake/b -> golang.org/fake/c
|
||||
golang.org/fake/b_test [golang.org/fake/b.test] -> golang.org/fake/b
|
||||
`[1:]
|
||||
if graph != wantGraph {
|
||||
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests golang/go#35973, fixed in Go 1.14.
|
||||
func TestInvalidFilesInOverlay(t *testing.T) { packagestest.TestAll(t, testInvalidFilesInOverlay) }
|
||||
func testInvalidFilesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
testenv.NeedsGo1Point(t, 14)
|
||||
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"d/d.go": `package d; import "net/http"; const d = http.MethodGet;`,
|
||||
"d/util.go": ``,
|
||||
"d/d_test.go": ``,
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "d/d.go")))
|
||||
|
||||
// Additional tests for test variants.
|
||||
for i, tt := range []struct {
|
||||
name string
|
||||
overlay map[string][]byte
|
||||
want string // expected value of d.D
|
||||
|
||||
}{
|
||||
// Overlay with a test variant.
|
||||
{"test_variant",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "d", "d_test.go"): []byte(`package d; import "testing"; const D = d + "_test"; func TestD(t *testing.T) {};`)},
|
||||
`"GET_test"`},
|
||||
// Overlay in package.
|
||||
{"second_file",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "d", "util.go"): []byte(`package d; const D = d + "_util";`)},
|
||||
`"GET_util"`},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exported.Config.Overlay = tt.overlay
|
||||
exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
|
||||
packages.NeedDeps | packages.NeedTypes | packages.NeedTypesSizes
|
||||
exported.Config.Tests = true
|
||||
|
||||
for f := range tt.overlay {
|
||||
initial, err := packages.Load(exported.Config, fmt.Sprintf("file=%s", f))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d := initial[0]
|
||||
var containsFile bool
|
||||
for _, goFile := range d.CompiledGoFiles {
|
||||
if f == goFile {
|
||||
containsFile = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !containsFile {
|
||||
t.Fatalf("expected %s in CompiledGoFiles, got %v", f, d.CompiledGoFiles)
|
||||
}
|
||||
// Check value of d.D.
|
||||
dD := constant(d, "D")
|
||||
if dD == nil {
|
||||
t.Fatalf("%d. d.D: got nil", i)
|
||||
}
|
||||
got := dD.Val().String()
|
||||
if got != tt.want {
|
||||
t.Fatalf("%d. d.D: got %s, want %s", i, got, tt.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func checkPkg(t *testing.T, p *packages.Package, id, name string, syntax int) bool {
|
||||
t.Helper()
|
||||
if p.ID == id && p.Name == name && len(p.Syntax) == syntax {
|
||||
|
|
|
|||
|
|
@ -886,251 +886,6 @@ func testParseFileModifyAST(t *testing.T, exporter packagestest.Exporter) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOverlay(t *testing.T) { packagestest.TestAll(t, testOverlay) }
|
||||
func testOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"c/c_test.go": `package c; import "testing"; func TestC(t *testing.T) {}`,
|
||||
"d/d.go": `package d; const D = "d"`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
for i, test := range []struct {
|
||||
overlay map[string][]byte
|
||||
want string // expected value of a.A
|
||||
wantErrs []string
|
||||
}{
|
||||
{nil, `"abc"`, nil}, // default
|
||||
{map[string][]byte{}, `"abc"`, nil}, // empty overlay
|
||||
{map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; const C = "C"`)}, `"abC"`, nil},
|
||||
{map[string][]byte{exported.File("golang.org/fake", "b/b.go"): []byte(`package b; import "golang.org/fake/c"; const B = "B" + c.C`)}, `"aBc"`, nil},
|
||||
// Overlay with an existing file in an existing package adding a new import.
|
||||
{map[string][]byte{exported.File("golang.org/fake", "b/b.go"): []byte(`package b; import "golang.org/fake/d"; const B = "B" + d.D`)}, `"aBd"`, nil},
|
||||
// Overlay with an existing file in an existing package.
|
||||
{map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; import "net/http"; const C = http.MethodGet`)}, `"abGET"`, nil},
|
||||
// Overlay with a new file in an existing package.
|
||||
{map[string][]byte{
|
||||
exported.File("golang.org/fake", "c/c.go"): []byte(`package c;`),
|
||||
filepath.Join(filepath.Dir(exported.File("golang.org/fake", "c/c.go")), "c_new_file.go"): []byte(`package c; const C = "Ç"`)},
|
||||
`"abÇ"`, nil},
|
||||
// Overlay with a new file in an existing package, adding a new dependency to that package.
|
||||
{map[string][]byte{
|
||||
exported.File("golang.org/fake", "c/c.go"): []byte(`package c;`),
|
||||
filepath.Join(filepath.Dir(exported.File("golang.org/fake", "c/c.go")), "c_new_file.go"): []byte(`package c; import "golang.org/fake/d"; const C = "c" + d.D`)},
|
||||
`"abcd"`, nil},
|
||||
} {
|
||||
exported.Config.Overlay = test.overlay
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
initial, err := packages.Load(exported.Config, "golang.org/fake/a")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check value of a.A.
|
||||
a := initial[0]
|
||||
aA := constant(a, "A")
|
||||
if aA == nil {
|
||||
t.Errorf("%d. a.A: got nil", i)
|
||||
continue
|
||||
}
|
||||
got := aA.Val().String()
|
||||
if got != test.want {
|
||||
t.Errorf("%d. a.A: got %s, want %s", i, got, test.want)
|
||||
}
|
||||
|
||||
// Check errors.
|
||||
var errors []packages.Error
|
||||
packages.Visit(initial, nil, func(pkg *packages.Package) {
|
||||
errors = append(errors, pkg.Errors...)
|
||||
})
|
||||
if errs := errorMessages(errors); !reflect.DeepEqual(errs, test.wantErrs) {
|
||||
t.Errorf("%d. got errors %s, want %s", i, errs, test.wantErrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlayDeps(t *testing.T) { packagestest.TestAll(t, testOverlayDeps) }
|
||||
func testOverlayDeps(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"c/c_test.go": `package c; import "testing"; func TestC(t *testing.T) {}`,
|
||||
},
|
||||
}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
exported.Config.Overlay = map[string][]byte{exported.File("golang.org/fake", "c/c.go"): []byte(`package c; import "net/http"; const C = http.MethodGet`)}
|
||||
exported.Config.Mode = packages.NeedName |
|
||||
packages.NeedFiles |
|
||||
packages.NeedCompiledGoFiles |
|
||||
packages.NeedImports |
|
||||
packages.NeedDeps |
|
||||
packages.NeedTypesSizes
|
||||
pkgs, err := packages.Load(exported.Config, fmt.Sprintf("file=%s", exported.File("golang.org/fake", "c/c.go")))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Find package golang.org/fake/c
|
||||
sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].ID < pkgs[j].ID })
|
||||
pkgc := pkgs[0]
|
||||
if pkgc.ID != "golang.org/fake/c" {
|
||||
t.Errorf("expected first package in sorted list to be \"golang.org/fake/c\", got %v", pkgc.ID)
|
||||
}
|
||||
|
||||
// Make sure golang.org/fake/c imports net/http, as per the overlay.
|
||||
contains := func(imports map[string]*packages.Package, wantImport string) bool {
|
||||
for imp := range imports {
|
||||
if imp == wantImport {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if !contains(pkgc.Imports, "net/http") {
|
||||
t.Errorf("expected import of %s in package %s, got the following imports: %v",
|
||||
"net/http", pkgc.ID, pkgc.Imports)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestNewPackagesInOverlay(t *testing.T) { packagestest.TestAll(t, testNewPackagesInOverlay) }
|
||||
func testNewPackagesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"; const A = "a" + b.B`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"; const B = "b" + c.C`,
|
||||
"c/c.go": `package c; const C = "c"`,
|
||||
"d/d.go": `package d; const D = "d"`,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "example.com/extramodule",
|
||||
Files: map[string]interface{}{
|
||||
"pkg/x.go": "package pkg\n",
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "a/a.go")))
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
overlay map[string][]byte
|
||||
want string // expected value of e.E
|
||||
}{
|
||||
{"one_file",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/a"; const E = "e" + a.A`)},
|
||||
`"eabc"`},
|
||||
{"multiple_files_same_package",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/a"; const E = "e" + a.A + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
},
|
||||
`"eabc_"`},
|
||||
{"multiple_files_two_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; const F = "f"`),
|
||||
},
|
||||
`"ef_"`},
|
||||
{"multiple_files_three_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; const G = "g"`),
|
||||
},
|
||||
`"efg_"`},
|
||||
{"multiple_files_four_packages",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; import "golang.org/fake/h"; const E = "e" + f.F + h.H + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; const G = "g"`),
|
||||
filepath.Join(dir, "h", "h.go"): []byte(`package h; const H = "h"`),
|
||||
},
|
||||
`"efgh_"`},
|
||||
{"multiple_files_four_packages_again",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "e.go"): []byte(`package e; import "golang.org/fake/f"; const E = "e" + f.F + underscore`),
|
||||
filepath.Join(dir, "e", "e_util.go"): []byte(`package e; const underscore = "_"`),
|
||||
filepath.Join(dir, "f", "f.go"): []byte(`package f; import "golang.org/fake/g"; const F = "f" + g.G`),
|
||||
filepath.Join(dir, "g", "g.go"): []byte(`package g; import "golang.org/fake/h"; const G = "g" + h.H`),
|
||||
filepath.Join(dir, "h", "h.go"): []byte(`package h; const H = "h"`),
|
||||
},
|
||||
`"efgh_"`},
|
||||
{"main_overlay",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "e", "main.go"): []byte(`package main; import "golang.org/fake/a"; const E = "e" + a.A; func main(){}`)},
|
||||
`"eabc"`},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
exported.Config.Overlay = test.overlay
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
exported.Config.Logf = t.Logf
|
||||
|
||||
// With an overlay, we don't know the expected import path,
|
||||
// so load with the absolute path of the directory.
|
||||
initial, err := packages.Load(exported.Config, filepath.Join(dir, "e"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check value of e.E.
|
||||
e := initial[0]
|
||||
eE := constant(e, "E")
|
||||
if eE == nil {
|
||||
t.Fatalf("e.E: was nil in %#v", e)
|
||||
}
|
||||
got := eE.Val().String()
|
||||
if got != test.want {
|
||||
t.Fatalf("e.E: got %s, want %s", got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Test that we can create a package and its test package in an overlay.
|
||||
func TestOverlayNewPackageAndTest(t *testing.T) {
|
||||
packagestest.TestAll(t, testOverlayNewPackageAndTest)
|
||||
}
|
||||
func testOverlayNewPackageAndTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"foo.txt": "placeholder",
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(exported.File("golang.org/fake", "foo.txt"))
|
||||
exported.Config.Overlay = map[string][]byte{
|
||||
filepath.Join(dir, "a.go"): []byte(`package a;`),
|
||||
filepath.Join(dir, "a_test.go"): []byte(`package a; import "testing";`),
|
||||
}
|
||||
initial, err := packages.Load(exported.Config, "file="+filepath.Join(dir, "a.go"), "file="+filepath.Join(dir, "a_test.go"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(initial) != 2 {
|
||||
t.Errorf("got %v packages, wanted %v", len(initial), 2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdHocPackagesBadImport(t *testing.T) {
|
||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||
// which are outside of $GOPATH and outside of a module.
|
||||
|
|
@ -1179,158 +934,6 @@ const A = 1
|
|||
}
|
||||
}
|
||||
|
||||
func TestAdHocOverlays(t *testing.T) {
|
||||
testenv.NeedsTool(t, "go")
|
||||
|
||||
// This test doesn't use packagestest because we are testing ad-hoc packages,
|
||||
// which are outside of $GOPATH and outside of a module.
|
||||
tmp, err := ioutil.TempDir("", "testAdHocOverlays")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
filename := filepath.Join(tmp, "a.go")
|
||||
content := []byte(`package a
|
||||
const A = 1
|
||||
`)
|
||||
|
||||
// Make sure that the user's value of GO111MODULE does not affect test results.
|
||||
for _, go111module := range []string{"off", "auto", "on"} {
|
||||
t.Run("GO111MODULE="+go111module, func(t *testing.T) {
|
||||
config := &packages.Config{
|
||||
Dir: tmp,
|
||||
Env: append(os.Environ(), "GOPACKAGESDRIVER=off", fmt.Sprintf("GO111MODULE=%s", go111module)),
|
||||
Mode: packages.LoadAllSyntax,
|
||||
Overlay: map[string][]byte{
|
||||
filename: content,
|
||||
},
|
||||
Logf: t.Logf,
|
||||
}
|
||||
initial, err := packages.Load(config, fmt.Sprintf("file=%s", filename))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(initial) == 0 {
|
||||
t.Fatalf("no packages for %s", filename)
|
||||
}
|
||||
// Check value of a.A.
|
||||
a := initial[0]
|
||||
if a.Errors != nil {
|
||||
t.Fatalf("a: got errors %+v, want no error", err)
|
||||
}
|
||||
aA := constant(a, "A")
|
||||
if aA == nil {
|
||||
t.Errorf("a.A: got nil")
|
||||
return
|
||||
}
|
||||
got := aA.Val().String()
|
||||
if want := "1"; got != want {
|
||||
t.Errorf("a.A: got %s, want %s", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestOverlayModFileChanges tests the behavior resulting from having files from
|
||||
// multiple modules in overlays.
|
||||
func TestOverlayModFileChanges(t *testing.T) {
|
||||
testenv.NeedsTool(t, "go")
|
||||
|
||||
// Create two unrelated modules in a temporary directory.
|
||||
tmp, err := ioutil.TempDir("", "tmp")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
// mod1 has a dependency on golang.org/x/xerrors.
|
||||
mod1, err := ioutil.TempDir(tmp, "mod1")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(mod1, "go.mod"), []byte(`module mod1
|
||||
|
||||
require (
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
|
||||
)
|
||||
`), 0775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// mod2 does not have any dependencies.
|
||||
mod2, err := ioutil.TempDir(tmp, "mod2")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
want := `module mod2
|
||||
|
||||
go 1.11
|
||||
`
|
||||
if err := ioutil.WriteFile(filepath.Join(mod2, "go.mod"), []byte(want), 0775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Run packages.Load on mod2, while passing the contents over mod1/main.go in the overlay.
|
||||
config := &packages.Config{
|
||||
Dir: mod2,
|
||||
Env: append(os.Environ(), "GOPACKAGESDRIVER=off"),
|
||||
Mode: packages.LoadImports,
|
||||
Overlay: map[string][]byte{
|
||||
filepath.Join(mod1, "main.go"): []byte(`package main
|
||||
import "golang.org/x/xerrors"
|
||||
func main() {
|
||||
_ = errors.New("")
|
||||
}
|
||||
`),
|
||||
filepath.Join(mod2, "main.go"): []byte(`package main
|
||||
func main() {}
|
||||
`),
|
||||
},
|
||||
}
|
||||
if _, err := packages.Load(config, fmt.Sprintf("file=%s", filepath.Join(mod2, "main.go"))); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Check that mod2/go.mod has not been modified.
|
||||
got, err := ioutil.ReadFile(filepath.Join(mod2, "go.mod"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(got) != want {
|
||||
t.Errorf("expected %s, got %s", want, string(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlayGOPATHVendoring(t *testing.T) {
|
||||
exported := packagestest.Export(t, packagestest.GOPATH, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"vendor/vendor.com/foo/foo.go": `package foo; const X = "hi"`,
|
||||
"user/user.go": `package user`,
|
||||
},
|
||||
}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
exported.Config.Mode = packages.LoadAllSyntax
|
||||
exported.Config.Logf = t.Logf
|
||||
exported.Config.Overlay = map[string][]byte{
|
||||
exported.File("golang.org/fake", "user/user.go"): []byte(`package user; import "vendor.com/foo"; var x = foo.X`),
|
||||
}
|
||||
initial, err := packages.Load(exported.Config, "golang.org/fake/user")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
user := initial[0]
|
||||
if len(user.Imports) != 1 {
|
||||
t.Fatal("no imports for user")
|
||||
}
|
||||
if user.Imports["vendor.com/foo"].Name != "foo" {
|
||||
t.Errorf("failed to load vendored package foo, imports: %#v", user.Imports["vendor.com/foo"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadAllSyntaxImportErrors(t *testing.T) {
|
||||
packagestest.TestAll(t, testLoadAllSyntaxImportErrors)
|
||||
}
|
||||
|
|
@ -1521,67 +1124,6 @@ func testContains(t *testing.T, exporter packagestest.Exporter) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContainsOverlay(t *testing.T) { packagestest.TestAll(t, testContainsOverlay) }
|
||||
func testContainsOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"`,
|
||||
"c/c.go": `package c`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
bOverlayFile := filepath.Join(filepath.Dir(exported.File("golang.org/fake", "b/b.go")), "b_overlay.go")
|
||||
exported.Config.Mode = packages.LoadImports
|
||||
exported.Config.Overlay = map[string][]byte{bOverlayFile: []byte(`package b;`)}
|
||||
initial, err := packages.Load(exported.Config, "file="+bOverlayFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
graph, _ := importGraph(initial)
|
||||
wantGraph := `
|
||||
* golang.org/fake/b
|
||||
golang.org/fake/c
|
||||
golang.org/fake/b -> golang.org/fake/c
|
||||
`[1:]
|
||||
if graph != wantGraph {
|
||||
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsOverlayXTest(t *testing.T) { packagestest.TestAll(t, testContainsOverlayXTest) }
|
||||
func testContainsOverlayXTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"a/a.go": `package a; import "golang.org/fake/b"`,
|
||||
"b/b.go": `package b; import "golang.org/fake/c"`,
|
||||
"c/c.go": `package c`,
|
||||
}}})
|
||||
defer exported.Cleanup()
|
||||
|
||||
bOverlayXTestFile := filepath.Join(filepath.Dir(exported.File("golang.org/fake", "b/b.go")), "b_overlay_x_test.go")
|
||||
exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedImports
|
||||
exported.Config.Overlay = map[string][]byte{bOverlayXTestFile: []byte(`package b_test; import "golang.org/fake/b"`)}
|
||||
initial, err := packages.Load(exported.Config, "file="+bOverlayXTestFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
graph, _ := importGraph(initial)
|
||||
wantGraph := `
|
||||
golang.org/fake/b
|
||||
* golang.org/fake/b_test [golang.org/fake/b.test]
|
||||
golang.org/fake/c
|
||||
golang.org/fake/b -> golang.org/fake/c
|
||||
golang.org/fake/b_test [golang.org/fake/b.test] -> golang.org/fake/b
|
||||
`[1:]
|
||||
if graph != wantGraph {
|
||||
t.Errorf("wrong import graph: got <<%s>>, want <<%s>>", graph, wantGraph)
|
||||
}
|
||||
}
|
||||
|
||||
// This test ensures that the effective GOARCH variable in the
|
||||
// application determines the Sizes function used by the type checker.
|
||||
// This behavior is a stop-gap until we make the build system's query
|
||||
|
|
@ -2799,78 +2341,6 @@ func testIssue37529(t *testing.T, exporter packagestest.Exporter) {
|
|||
}
|
||||
}
|
||||
|
||||
// Tests golang/go#35973, fixed in Go 1.14.
|
||||
func TestInvalidFilesInOverlay(t *testing.T) { packagestest.TestAll(t, testInvalidFilesInOverlay) }
|
||||
func testInvalidFilesInOverlay(t *testing.T, exporter packagestest.Exporter) {
|
||||
testenv.NeedsGo1Point(t, 14)
|
||||
exported := packagestest.Export(t, exporter, []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/fake",
|
||||
Files: map[string]interface{}{
|
||||
"d/d.go": `package d; import "net/http"; const d = http.MethodGet;`,
|
||||
"d/util.go": ``,
|
||||
"d/d_test.go": ``,
|
||||
},
|
||||
},
|
||||
})
|
||||
defer exported.Cleanup()
|
||||
|
||||
dir := filepath.Dir(filepath.Dir(exported.File("golang.org/fake", "d/d.go")))
|
||||
|
||||
// Additional tests for test variants.
|
||||
for i, tt := range []struct {
|
||||
name string
|
||||
overlay map[string][]byte
|
||||
want string // expected value of d.D
|
||||
|
||||
}{
|
||||
// Overlay with a test variant.
|
||||
{"test_variant",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "d", "d_test.go"): []byte(`package d; import "testing"; const D = d + "_test"; func TestD(t *testing.T) {};`)},
|
||||
`"GET_test"`},
|
||||
// Overlay in package.
|
||||
{"second_file",
|
||||
map[string][]byte{
|
||||
filepath.Join(dir, "d", "util.go"): []byte(`package d; const D = d + "_util";`)},
|
||||
`"GET_util"`},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exported.Config.Overlay = tt.overlay
|
||||
exported.Config.Mode = packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
|
||||
packages.NeedDeps | packages.NeedTypes | packages.NeedTypesSizes
|
||||
exported.Config.Tests = true
|
||||
|
||||
for f := range tt.overlay {
|
||||
initial, err := packages.Load(exported.Config, fmt.Sprintf("file=%s", f))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d := initial[0]
|
||||
var containsFile bool
|
||||
for _, goFile := range d.CompiledGoFiles {
|
||||
if f == goFile {
|
||||
containsFile = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !containsFile {
|
||||
t.Fatalf("expected %s in CompiledGoFiles, got %v", f, d.CompiledGoFiles)
|
||||
}
|
||||
// Check value of d.D.
|
||||
dD := constant(d, "D")
|
||||
if dD == nil {
|
||||
t.Fatalf("%d. d.D: got nil", i)
|
||||
}
|
||||
got := dD.Val().String()
|
||||
if got != tt.want {
|
||||
t.Fatalf("%d. d.D: got %s, want %s", i, got, tt.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestInvalidFilesInXTest checks the fix for golang/go#37971 in Go 1.15.
|
||||
func TestInvalidFilesInXTest(t *testing.T) { packagestest.TestAll(t, testInvalidFilesInXTest) }
|
||||
func testInvalidFilesInXTest(t *testing.T, exporter packagestest.Exporter) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue