imports: port tests to packagestest

I tried to introduce new modules where it made sense. I deleted the
weird goroot test because I removed the optimization it was testing in
an earlier CL.

Change-Id: I219ddaa4f462a4aeb640f62215d16f246511a5fe
Reviewed-on: https://go-review.googlesource.com/c/144497
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/go/packages/packagestest/gopath.go b/go/packages/packagestest/gopath.go
index 149d73e..090f49a 100644
--- a/go/packages/packagestest/gopath.go
+++ b/go/packages/packagestest/gopath.go
@@ -27,7 +27,7 @@
 //             └── golang.org
 //                 └── repob
 //                     └── b
-//     										└── b.go
+//                         └── b.go
 // GOPATH would be set to
 //     /sometemporarydirectory/repoa;/sometemporarydirectory/repob
 // and the working directory would be
diff --git a/imports/fix.go b/imports/fix.go
index 1e3bd09..187bc7d 100644
--- a/imports/fix.go
+++ b/imports/fix.go
@@ -932,15 +932,3 @@
 	}
 	return importPath, importPath != ""
 }
-
-// fileInDir reports whether the provided file path looks like
-// it's in dir. (without hitting the filesystem)
-func fileInDir(file, dir string) bool {
-	rest := strings.TrimPrefix(file, dir)
-	if len(rest) == len(file) {
-		// dir is not a prefix of file.
-		return false
-	}
-	// Check for boundary: either nothing (file == dir), or a slash.
-	return len(rest) == 0 || rest[0] == '/' || rest[0] == '\\'
-}
diff --git a/imports/fix_test.go b/imports/fix_test.go
index ede39c9..64f5eb5 100644
--- a/imports/fix_test.go
+++ b/imports/fix_test.go
@@ -7,13 +7,13 @@
 import (
 	"fmt"
 	"go/build"
-	"io/ioutil"
-	"os"
 	"path/filepath"
 	"runtime"
 	"strings"
 	"sync"
 	"testing"
+
+	"golang.org/x/tools/go/packages/packagestest"
 )
 
 var tests = []struct {
@@ -1122,17 +1122,30 @@
 				// Skeleton non-stdlib packages for use during testing.
 				// Each includes one arbitrary symbol, e.g. the first declaration in the first file.
 				// Try not to add more without a good reason.
-				gopathFiles: map[string]string{
-					"appengine/x.go":                          "package appengine\nfunc Main(){}\n",
-					"appengine/datastore/x.go":                "package datastore\nvar ErrInvalidEntityType error\n",
-					"rsc.io/p/x.go":                           "package p\nfunc P(){}\n",
-					"code.google.com/p/snappy-go/snappy/x.go": "package snappy\nvar ErrCorrupt error\n",
-					"x/x.go": tt.in,
+				modules: []packagestest.Module{
+					{
+						Name: "appengine",
+						Files: fm{
+							"x.go":           "package appengine\nfunc Main(){}\n",
+							"datastore/x.go": "package datastore\nvar ErrInvalidEntityType error\n",
+						},
+					},
+					{
+						Name:  "rsc.io",
+						Files: fm{"p/x.go": "package p\nfunc P(){}\n"},
+					},
+					{
+						Name:  "code.google.com/p/snappy-go",
+						Files: fm{"snappy/x.go": "package snappy\nvar ErrCorrupt error\n"},
+					},
+					{
+						Name:  "golang.org/fake",
+						Files: fm{"x.go": tt.in},
+					},
 				},
-			}.processTest(t, "x/x.go", nil, options, tt.out)
+			}.processTest(t, "golang.org/fake", "x.go", nil, options, tt.out)
 		})
 	}
-
 }
 
 func TestReadFromFilesystem(t *testing.T) {
@@ -1182,10 +1195,11 @@
 				Fragment:  true,
 			}
 			testConfig{
-				gopathFiles: map[string]string{
-					"x.go": tt.in,
+				module: packagestest.Module{
+					Name:  "golang.org/fake",
+					Files: fm{"x.go": tt.in},
 				},
-			}.processTest(t, "x.go", nil, options, tt.out)
+			}.processTest(t, "golang.org/fake", "x.go", nil, options, tt.out)
 		})
 	}
 
@@ -1210,7 +1224,8 @@
 
 import (
 	"fmt"
-	"x/mypkg"
+
+	"golang.org/fake/x/y/mypkg"
 )
 
 var (
@@ -1220,13 +1235,16 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"../target/f.go":             "package mypkg\nvar Foo = 123\n",
-			"x/mypkg":                    "LINK:../../target", // valid symlink
-			"x/apkg":                     "LINK:..",           // symlink loop
-			"myotherpackage/toformat.go": input,
+		module: packagestest.Module{
+			Name: "golang.org/fake",
+			Files: fm{
+				"target/f.go":                "package mypkg\nvar Foo = 123\n",
+				"x/y/mypkg":                  packagestest.Symlink("../../target"), // valid symlink
+				"x/y/apkg":                   packagestest.Symlink(".."),           // symlink loop
+				"myotherpackage/toformat.go": input,
+			},
 		},
-	}.processTest(t, "myotherpackage/toformat.go", nil, nil, want)
+	}.processTest(t, "golang.org/fake", "myotherpackage/toformat.go", nil, nil, want)
 }
 
 func TestImportSymlinksWithIgnore(t *testing.T) {
@@ -1253,14 +1271,17 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"../target/f.go":         "package mypkg\nvar Foo = 123\n",
-			"x/mypkg":                "LINK:../../target", // valid symlink
-			"x/apkg":                 "LINK:..",           // symlink loop
-			"myotherpkg/toformat.go": input,
-			".goimportsignore":       "x/mypkg\n",
+		module: packagestest.Module{
+			Name: "golang.org/fake",
+			Files: fm{
+				"target/f.go":            "package mypkg\nvar Foo = 123\n",
+				"x/y/mypkg":              packagestest.Symlink("../../target"), // valid symlink
+				"x/y/apkg":               packagestest.Symlink(".."),           // symlink loop
+				"myotherpkg/toformat.go": input,
+				"../../.goimportsignore": "golang.org/fake/x/y/mypkg\n",
+			},
 		},
-	}.processTest(t, "myotherpkg/toformat.go", nil, nil, want)
+	}.processTest(t, "golang.org/fake", "myotherpkg/toformat.go", nil, nil, want)
 }
 
 // Test for x/y/v2 convention for package y.
@@ -1280,10 +1301,11 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"mypkg.com/outpkg/toformat.go": input,
+		module: packagestest.Module{
+			Name:  "mypkg.com/outpkg",
+			Files: fm{"toformat.go": input},
 		},
-	}.processTest(t, "mypkg.com/outpkg/toformat.go", nil, nil, input)
+	}.processTest(t, "mypkg.com/outpkg", "toformat.go", nil, nil, input)
 }
 
 // Test for correctly identifying the name of a vendored package when it
@@ -1305,11 +1327,14 @@
 )
 `
 	testConfig{
-		gopathFiles: map[string]string{
-			"mypkg.com/outpkg/vendor/mypkg.com/mypkg.v1/f.go": "package mypkg\nvar Foo = 123\n",
-			"mypkg.com/outpkg/toformat.go":                    input,
+		module: packagestest.Module{
+			Name: "mypkg.com/outpkg",
+			Files: fm{
+				"vendor/mypkg.com/mypkg.v1/f.go": "package mypkg\nvar Foo = 123\n",
+				"toformat.go":                    input,
+			},
 		},
-	}.processTest(t, "mypkg.com/outpkg/toformat.go", nil, nil, input)
+	}.processTest(t, "mypkg.com/outpkg", "toformat.go", nil, nil, input)
 }
 
 func TestInternal(t *testing.T) {
@@ -1319,26 +1344,35 @@
 `
 	const importAdded = `package bar
 
-import "foo/internal/race"
+import "foo.com/internal/race"
 
 var _ = race.Acquire
 `
 
 	// Packages under the same directory should be able to use internal packages.
 	testConfig{
-		gopathFiles: map[string]string{
-			"foo/internal/race/x.go": "package race\n func Acquire(){}\n",
-			"foo/bar/x.go":           input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"internal/race/x.go": "package race\n func Acquire(){}\n",
+				"bar/x.go":           input,
+			},
 		},
-	}.processTest(t, "foo/bar/x.go", nil, nil, importAdded)
+	}.processTest(t, "foo.com", "bar/x.go", nil, nil, importAdded)
 
 	// Packages outside the same directory should not.
 	testConfig{
-		gopathFiles: map[string]string{
-			"foo/internal/race/x.go": "package race\n func Acquire(){}\n",
-			"bar/x.go":               input,
+		modules: []packagestest.Module{
+			{
+				Name:  "foo.com",
+				Files: fm{"internal/race/x.go": "package race\n func Acquire(){}\n"},
+			},
+			{
+				Name:  "bar.com",
+				Files: fm{"x.go": input},
+			},
 		},
-	}.processTest(t, "bar/x.go", nil, nil, input)
+	}.processTest(t, "bar.com", "x.go", nil, nil, input)
 }
 
 func TestProcessVendor(t *testing.T) {
@@ -1353,11 +1387,14 @@
 var _ = hpack.HuffmanDecode
 `
 	testConfig{
-		gopathFiles: map[string]string{
-			"vendor/golang.org/x/net/http2/hpack/huffman.go": "package hpack\nfunc HuffmanDecode() { }\n",
-			"bar/x.go": input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"vendor/golang.org/x/net/http2/hpack/huffman.go": "package hpack\nfunc HuffmanDecode() { }\n",
+				"bar/x.go": input,
+			},
 		},
-	}.processTest(t, "bar/x.go", nil, nil, want)
+	}.processTest(t, "foo.com", "bar/x.go", nil, nil, want)
 }
 
 func TestFindStdlib(t *testing.T) {
@@ -1388,69 +1425,33 @@
 }
 
 type testConfig struct {
-	// goroot and gopath optionally specifies the path on disk
-	// to use for the GOROOT and GOPATH. If empty, a temp directory
-	// is made if needed.
-	goroot, gopath string
-
-	// gorootFiles optionally specifies the complete contents of GOROOT to use,
-	// If nil, the normal current $GOROOT is used.
-	gorootFiles map[string]string // paths relative to $GOROOT/src to contents
-
-	// gopathFiles is like gorootFiles, but for $GOPATH.
-	// If nil, there is no GOPATH, though.
-	gopathFiles map[string]string // paths relative to $GOPATH/src to contents
+	module  packagestest.Module
+	modules []packagestest.Module
 }
 
-func mustTempDir(t *testing.T, prefix string) string {
-	t.Helper()
-	dir, err := ioutil.TempDir("", prefix)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return dir
-}
-
-func mapToDir(destDir string, files map[string]string) error {
-	for path, contents := range files {
-		file := filepath.Join(destDir, "src", path)
-		if err := os.MkdirAll(filepath.Dir(file), 0755); err != nil {
-			return err
-		}
-		var err error
-		if strings.HasPrefix(contents, "LINK:") {
-			err = os.Symlink(strings.TrimPrefix(contents, "LINK:"), file)
-		} else {
-			err = ioutil.WriteFile(file, []byte(contents), 0644)
-		}
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
+// fm is the type for a packagestest.Module's Files, abbreviated for shorter lines.
+type fm map[string]interface{}
 
 func (c testConfig) test(t *testing.T, fn func(*goimportTest)) {
 	t.Helper()
 
-	goroot := c.goroot
-	gopath := c.gopath
-
-	if c.gorootFiles != nil && goroot == "" {
-		goroot = mustTempDir(t, "goroot-")
-		defer os.RemoveAll(goroot)
-	}
-	if err := mapToDir(goroot, c.gorootFiles); err != nil {
-		t.Fatal(err)
+	var exported *packagestest.Exported
+	if c.module.Name != "" {
+		c.modules = []packagestest.Module{c.module}
 	}
 
-	if c.gopathFiles != nil && gopath == "" {
-		gopath = mustTempDir(t, "gopath-")
-		defer os.RemoveAll(gopath)
+	exported = packagestest.Export(t, packagestest.GOPATH, c.modules)
+	defer exported.Cleanup()
+
+	env := make(map[string]string)
+	for _, kv := range exported.Config.Env {
+		split := strings.Split(kv, "=")
+		k, v := split[0], split[1]
+		env[k] = v
 	}
-	if err := mapToDir(gopath, c.gopathFiles); err != nil {
-		t.Fatal(err)
-	}
+
+	goroot := env["GOROOT"]
+	gopath := env["GOPATH"]
 
 	scanOnce = sync.Once{}
 
@@ -1466,40 +1467,47 @@
 		build.Default.Compiler = oldCompiler
 	}()
 
-	if goroot != "" {
-		build.Default.GOROOT = goroot
-	}
+	build.Default.GOROOT = goroot
 	build.Default.GOPATH = gopath
 
 	it := &goimportTest{
-		T:      t,
-		goroot: build.Default.GOROOT,
-		gopath: gopath,
-		ctx:    &build.Default,
+		T:        t,
+		goroot:   build.Default.GOROOT,
+		gopath:   gopath,
+		ctx:      &build.Default,
+		exported: exported,
 	}
 	fn(it)
 }
 
-func (c testConfig) processTest(t *testing.T, file string, contents []byte, opts *Options, want string) {
+func (c testConfig) processTest(t *testing.T, module, file string, contents []byte, opts *Options, want string) {
 	t.Helper()
 	c.test(t, func(t *goimportTest) {
 		t.Helper()
-		t.process(file, contents, opts, want)
+		f := t.exported.File(module, file)
+		if f == "" {
+			t.Fatalf("%v not found in exported files (typo in filename?)", file)
+		}
+		t.process(f, contents, opts, want)
 	})
 }
 
 type goimportTest struct {
 	*testing.T
-	ctx    *build.Context
-	goroot string
-	gopath string
+	ctx      *build.Context
+	goroot   string
+	gopath   string
+	exported *packagestest.Exported
 }
 
 func (t *goimportTest) process(file string, contents []byte, opts *Options, want string) {
 	t.Helper()
-	buf, err := Process(filepath.Join(t.gopath, "src", file), contents, opts)
+	if !filepath.IsAbs(file) {
+		file = filepath.Join(t.gopath, "src", file)
+	}
+	buf, err := Process(file, contents, opts)
 	if err != nil {
-		t.Fatal(err)
+		t.Fatalf("Process() = %v", err)
 	}
 	if string(buf) != want {
 		t.Errorf("Got:\n%s\nWant:\n%s", buf, want)
@@ -1516,41 +1524,47 @@
 
 	const want = `package main
 
-import bar "foo/bar/v1"
+import bar "foo.com/foo/bar/v1"
 
 const Y = bar.X
 `
 	testConfig{
-		gopathFiles: map[string]string{
-			"foo/bar/v1/x.go": "package bar \n const X = 1",
-			"test/t.go":       input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"foo/bar/v1/x.go": "package bar \n const X = 1",
+				"test/t.go":       input,
+			},
 		},
-	}.processTest(t, "test/t.go", nil, nil, want)
+	}.processTest(t, "foo.com", "test/t.go", nil, nil, want)
 }
 
 // Tests that the LocalPrefix option causes imports
 // to be added into a later group (num=3).
 func TestLocalPrefix(t *testing.T) {
 	tests := []struct {
-		config      testConfig
+		modules     []packagestest.Module
 		localPrefix string
 		src         string
 		want        string
 	}{
 		{
-			config: testConfig{
-				gopathFiles: map[string]string{
-					"foo/bar/bar.go": "package bar \n const X = 1",
+			modules: []packagestest.Module{
+				{
+					Name: "foo.com",
+					Files: fm{
+						"bar/bar.go": "package bar \n const X = 1",
+					},
 				},
 			},
-			localPrefix: "foo/",
+			localPrefix: "foo.com/",
 			src:         "package main \n const Y = bar.X \n const _ = runtime.GOOS",
 			want: `package main
 
 import (
 	"runtime"
 
-	"foo/bar"
+	"foo.com/bar"
 )
 
 const Y = bar.X
@@ -1558,21 +1572,24 @@
 `,
 		},
 		{
-			config: testConfig{
-				gopathFiles: map[string]string{
-					"foo/foo.go":     "package foo \n const X = 1",
-					"foo/bar/bar.go": "package bar \n const X = 1",
+			modules: []packagestest.Module{
+				{
+					Name: "foo.com",
+					Files: fm{
+						"foo/foo.go":     "package foo \n const X = 1",
+						"foo/bar/bar.go": "package bar \n const X = 1",
+					},
 				},
 			},
-			localPrefix: "foo/",
+			localPrefix: "foo.com/foo",
 			src:         "package main \n const Y = bar.X \n const Z = foo.X \n const _ = runtime.GOOS",
 			want: `package main
 
 import (
 	"runtime"
 
-	"foo"
-	"foo/bar"
+	"foo.com/foo"
+	"foo.com/foo/bar"
 )
 
 const Y = bar.X
@@ -1581,14 +1598,21 @@
 `,
 		},
 		{
-			config: testConfig{
-				gopathFiles: map[string]string{
-					"example.org/pkg/pkg.go":          "package pkg \n const A = 1",
-					"foo/bar/bar.go":                  "package bar \n const B = 1",
-					"code.org/r/p/expproj/expproj.go": "package expproj \n const C = 1",
+			modules: []packagestest.Module{
+				{
+					Name:  "example.org/pkg",
+					Files: fm{"pkg.go": "package pkg \n const A = 1"},
+				},
+				{
+					Name:  "foo.com",
+					Files: fm{"bar/bar.go": "package bar \n const B = 1"},
+				},
+				{
+					Name:  "code.org/r/p",
+					Files: fm{"expproj/expproj.go": "package expproj \n const C = 1"},
 				},
 			},
-			localPrefix: "example.org/pkg,foo/,code.org",
+			localPrefix: "example.org/pkg,foo.com/,code.org",
 			src:         "package main \n const X = pkg.A \n const Y = bar.B \n const Z = expproj.C \n const _ = runtime.GOOS",
 			want: `package main
 
@@ -1597,7 +1621,7 @@
 
 	"code.org/r/p/expproj"
 	"example.org/pkg"
-	"foo/bar"
+	"foo.com/bar"
 )
 
 const X = pkg.A
@@ -1609,7 +1633,9 @@
 	}
 
 	for _, tt := range tests {
-		tt.config.test(t, func(t *goimportTest) {
+		testConfig{
+			modules: tt.modules,
+		}.test(t, func(t *goimportTest) {
 			defer func(s string) { LocalPrefix = s }(LocalPrefix)
 			LocalPrefix = tt.localPrefix
 			t.process("test/t.go", []byte(tt.src), nil, tt.want)
@@ -1625,18 +1651,21 @@
 `
 	const want = `package x
 
-import "foo"
+import "foo.com/foo"
 
 const Y = foo.X
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"foo/foo.go": "package foo\nconst X = 1\n",
-			"foo/doc.go": "package documentation \n // just to confuse things\n",
-			"x/x.go":     input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"foo/foo.go": "package foo\nconst X = 1\n",
+				"foo/doc.go": "package documentation \n // just to confuse things\n",
+				"x/x.go":     input,
+			},
 		},
-	}.processTest(t, "x/x.go", nil, nil, want)
+	}.processTest(t, "foo.com", "x/x.go", nil, nil, want)
 }
 
 // Tests importPathToNameGoPathParse and in particular that it stops
@@ -1645,11 +1674,14 @@
 // never make it that far).
 func TestImportPathToNameGoPathParse(t *testing.T) {
 	testConfig{
-		gopathFiles: map[string]string{
-			"example.net/pkg/doc.go": "package documentation\n", // ignored
-			"example.net/pkg/gen.go": "package main\n",          // also ignored
-			"example.net/pkg/pkg.go": "package the_pkg_name_to_find\n  and this syntax error is ignored because of parser.PackageClauseOnly",
-			"example.net/pkg/z.go":   "package inconsistent\n", // inconsistent but ignored
+		module: packagestest.Module{
+			Name: "example.net/pkg",
+			Files: fm{
+				"doc.go": "package documentation\n", // ignored
+				"gen.go": "package main\n",          // also ignored
+				"pkg.go": "package the_pkg_name_to_find\n  and this syntax error is ignored because of parser.PackageClauseOnly",
+				"z.go":   "package inconsistent\n", // inconsistent but ignored
+			},
 		},
 	}.test(t, func(t *goimportTest) {
 		got, err := importPathToNameGoPathParse("example.net/pkg", filepath.Join(t.gopath, "src", "other.net"))
@@ -1670,19 +1702,22 @@
 `
 	const want = `package x
 
-import "otherwise-longer-so-worse.example.net/foo/pkg"
+import "foo.com/otherwise-longer-so-worse-example/foo/pkg"
 
 const _ = pkg.X
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			".goimportsignore":       "# comment line\n\n example.net", // tests comment, blank line, whitespace trimming
-			"example.net/pkg/pkg.go": "package pkg\nconst X = 1",
-			"otherwise-longer-so-worse.example.net/foo/pkg/pkg.go": "package pkg\nconst X = 1",
-			"x/x.go": input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"../.goimportsignore":                              "# comment line\n\n foo.com/example", // tests comment, blank line, whitespace trimming
+				"example/pkg/pkg.go":                               "package pkg\nconst X = 1",
+				"otherwise-longer-so-worse-example/foo/pkg/pkg.go": "package pkg\nconst X = 1",
+				"x/x.go": input,
+			},
 		},
-	}.processTest(t, "x/x.go", nil, nil, want)
+	}.processTest(t, "foo.com", "x/x.go", nil, nil, want)
 }
 
 // Skip "node_modules" directory.
@@ -1693,43 +1728,21 @@
 `
 	const want = `package x
 
-import "otherwise-longer.net/not_modules/pkg"
+import "foo.com/otherwise-longer/not_modules/pkg"
 
 const _ = pkg.X
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"example.net/node_modules/pkg/a.go":         "package pkg\nconst X = 1",
-			"otherwise-longer.net/not_modules/pkg/a.go": "package pkg\nconst X = 1",
-			"x/x.go": input,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"example/node_modules/pkg/a.go":         "package pkg\nconst X = 1",
+				"otherwise-longer/not_modules/pkg/a.go": "package pkg\nconst X = 1",
+				"x/x.go":                                input,
+			},
 		},
-	}.processTest(t, "x/x.go", nil, nil, want)
-}
-
-// golang.org/issue/16458 -- if GOROOT is a prefix of GOPATH, GOPATH is ignored.
-func TestGoRootPrefixOfGoPath(t *testing.T) {
-	const input = `package x
-
-const _ = foo.X
-`
-	const want = `package x
-
-import "example.com/foo"
-
-const _ = foo.X
-`
-
-	dir := mustTempDir(t, "importstest")
-	defer os.RemoveAll(dir)
-	testConfig{
-		goroot: filepath.Join(dir, "go"),
-		gopath: filepath.Join(dir, "gopath"),
-		gopathFiles: map[string]string{
-			"example.com/foo/pkg.go": "package foo\nconst X = 1",
-			"x/x.go":                 input,
-		},
-	}.processTest(t, "x/x.go", nil, nil, want)
+	}.processTest(t, "foo.com", "x/x.go", nil, nil, want)
 }
 
 // Tests that package global variables with the same name and function name as
@@ -1755,11 +1768,14 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"pkg/uses.go":   usesGlobal,
-			"pkg/global.go": declaresGlobal,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"pkg/uses.go":   usesGlobal,
+				"pkg/global.go": declaresGlobal,
+			},
 		},
-	}.processTest(t, "pkg/uses.go", nil, nil, usesGlobal)
+	}.processTest(t, "foo.com", "pkg/uses.go", nil, nil, usesGlobal)
 }
 
 // Tests that sibling files - other files in the same package - can provide an
@@ -1804,11 +1820,14 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"p/needs_import.go":    need,
-			"p/provides_import.go": provide,
+		module: packagestest.Module{
+			Name: "foo.com",
+			Files: fm{
+				"p/needs_import.go":    need,
+				"p/provides_import.go": provide,
+			},
 		},
-	}.processTest(t, "p/needs_import.go", nil, nil, want)
+	}.processTest(t, "foo.com", "p/needs_import.go", nil, nil, want)
 }
 
 func TestPkgIsCandidate(t *testing.T) {
@@ -1978,13 +1997,24 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{
-			"config.net/config/config.go":         "package config\n type SystemConfig struct {}", // Will match but should not be first choice
-			"mycompany.net/config/config.go":      "package config\n type SystemConfig struct {}", // Will match but should not be first choice
-			"mycompany.net/tool/config/config.go": "package config\n type SystemConfig struct {}", // Local package should be promoted over shorter package
-			"mycompany.net/tool/main.go":          input,
+		modules: []packagestest.Module{
+			{
+				Name:  "config.net/config",
+				Files: fm{"config.go": "package config\n type SystemConfig struct {}"}, // Will match but should not be first choice
+			},
+			{
+				Name:  "mycompany.net/config",
+				Files: fm{"config.go": "package config\n type SystemConfig struct {}"}, // Will match but should not be first choice
+			},
+			{
+				Name: "mycompany.net/tool",
+				Files: fm{
+					"config/config.go": "package config\n type SystemConfig struct {}", // Local package should be promoted over shorter package
+					"main.go":          input,
+				},
+			},
 		},
-	}.processTest(t, "mycompany.net/tool/main.go", nil, nil, want)
+	}.processTest(t, "mycompany.net/tool", "main.go", nil, nil, want)
 }
 
 // Tests FindImportInLocalGoFiles looks at the import lines for other Go files in the
@@ -2003,13 +2033,21 @@
 var _ = &bytes.Buffer{}
 `
 	testConfig{
-		gopathFiles: map[string]string{
-			"bytes.net/bytes/bytes.go":   "package bytes\n type Buffer struct {}",                               // Should be selected over standard library
-			"mycompany.net/tool/io.go":   "package main\n import \"bytes.net/bytes\"\n var _ = &bytes.Buffer{}", // Contains package import that will cause stdlib to be ignored
-			"mycompany.net/tool/err.go":  "package main\n import \"bogus.net/bytes\"\n var _ = &bytes.Buffer{}", // Contains import which is not resolved, so it is ignored
-			"mycompany.net/tool/main.go": input,
+		modules: []packagestest.Module{
+			{
+				Name:  "bytes.net/bytes",
+				Files: fm{"bytes.go": "package bytes\n type Buffer struct {}"}, // Should be selected over standard library
+			},
+			{
+				Name: "mycompany.net/tool",
+				Files: fm{
+					"io.go":   "package main\n import \"bytes.net/bytes\"\n var _ = &bytes.Buffer{}", // Contains package import that will cause stdlib to be ignored
+					"err.go":  "package main\n import \"bogus.net/bytes\"\n var _ = &bytes.Buffer{}", // Contains import which is not resolved, so it is ignored
+					"main.go": input,
+				},
+			},
 		},
-	}.processTest(t, "mycompany.net/tool/main.go", nil, nil, want)
+	}.processTest(t, "mycompany.net/tool", "main.go", nil, nil, want)
 }
 
 func TestImportNoGoFiles(t *testing.T) {
@@ -2023,7 +2061,13 @@
 var _ = &bytes.Buffer{}
 `
 
-	testConfig{}.processTest(t, "mycompany.net/tool/main.go", []byte(input), nil, want)
+	buf, err := Process("mycompany.net/tool/main.go", []byte(input), nil)
+	if err != nil {
+		t.Fatalf("Process() = %v", err)
+	}
+	if string(buf) != want {
+		t.Errorf("Got:\n%s\nWant:\n%s", buf, want)
+	}
 }
 
 // Ensures a token as large as 500000 bytes can be handled
@@ -2059,6 +2103,9 @@
 `
 
 	testConfig{
-		gopathFiles: map[string]string{"foo.go": input},
-	}.processTest(t, "foo.go", nil, nil, want)
+		module: packagestest.Module{
+			Name:  "foo.com",
+			Files: fm{"foo.go": input},
+		},
+	}.processTest(t, "foo.com", "foo.go", nil, nil, want)
 }