--- /dev/null
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package misc
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ . "golang.org/x/tools/gopls/internal/regtest"
+
+ "golang.org/x/tools/internal/lsp/protocol"
+ "golang.org/x/tools/internal/testenv"
+)
+
+// Tests golang/go#38815.
+func TestIssue38815(t *testing.T) {
+ const needs = `
+-- go.mod --
+module foo
+
+go 1.12
+-- a.go --
+package main
+func f() {}
+`
+ const ntest = `package main
+func TestZ(t *testing.T) {
+ f()
+}
+`
+ const want = `package main
+
+import "testing"
+
+func TestZ(t *testing.T) {
+ f()
+}
+`
+
+ // it was returning
+ // "package main\nimport \"testing\"\npackage main..."
+ Run(t, needs, func(t *testing.T, env *Env) {
+ env.CreateBuffer("a_test.go", ntest)
+ env.SaveBuffer("a_test.go")
+ got := env.Editor.BufferText("a_test.go")
+ if want != got {
+ t.Errorf("got\n%q, wanted\n%q", got, want)
+ }
+ })
+}
+
+func TestVim1(t *testing.T) {
+ const vim1 = `package main
+
+import "fmt"
+
+var foo = 1
+var bar = 2
+
+func main() {
+ fmt.Printf("This is a test %v\n", foo)
+ fmt.Printf("This is another test %v\n", foo)
+ fmt.Printf("This is also a test %v\n", foo)
+}
+`
+
+ // The file remains unchanged, but if there are any CodeActions returned, they confuse vim.
+ // Therefore check for no CodeActions
+ Run(t, "", func(t *testing.T, env *Env) {
+ env.CreateBuffer("main.go", vim1)
+ env.OrganizeImports("main.go")
+ actions := env.CodeAction("main.go")
+ if len(actions) > 0 {
+ got := env.Editor.BufferText("main.go")
+ t.Errorf("unexpected actions %#v", actions)
+ if got == vim1 {
+ t.Errorf("no changes")
+ } else {
+ t.Errorf("got\n%q", got)
+ t.Errorf("was\n%q", vim1)
+ }
+ }
+ })
+}
+
+func TestVim2(t *testing.T) {
+ const vim2 = `package main
+
+import (
+ "fmt"
+
+ "example.com/blah"
+
+ "rubbish.com/useless"
+)
+
+func main() {
+ fmt.Println(blah.Name, useless.Name)
+}
+`
+
+ Run(t, "", func(t *testing.T, env *Env) {
+ env.CreateBuffer("main.go", vim2)
+ env.OrganizeImports("main.go")
+ actions := env.CodeAction("main.go")
+ if len(actions) > 0 {
+ t.Errorf("unexpected actions %#v", actions)
+ }
+ })
+}
+
+func TestGOMODCACHE(t *testing.T) {
+ const proxy = `
+-- example.com@v1.2.3/go.mod --
+module example.com
+
+go 1.12
+-- example.com@v1.2.3/x/x.go --
+package x
+
+const X = 1
+-- example.com@v1.2.3/y/y.go --
+package y
+
+const Y = 2
+`
+ const files = `
+-- go.mod --
+module mod.com
+
+go 1.12
+
+require example.com v1.2.3
+-- go.sum --
+example.com v1.2.3 h1:6vTQqzX+pnwngZF1+5gcO3ZEWmix1jJ/h+pWS8wUxK0=
+example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
+-- main.go --
+package main
+
+import "example.com/x"
+
+var _, _ = x.X, y.Y
+`
+ testenv.NeedsGo1Point(t, 15)
+
+ modcache, err := ioutil.TempDir("", "TestGOMODCACHE-modcache")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(modcache)
+ editorConfig := EditorConfig{Env: map[string]string{"GOMODCACHE": modcache}}
+ WithOptions(
+ editorConfig,
+ ProxyFiles(proxy),
+ ).Run(t, files, func(t *testing.T, env *Env) {
+ env.OpenFile("main.go")
+ env.Await(env.DiagnosticAtRegexp("main.go", `y.Y`))
+ env.SaveBuffer("main.go")
+ env.Await(EmptyDiagnostics("main.go"))
+ path, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `y.(Y)`))
+ if !strings.HasPrefix(path, filepath.ToSlash(modcache)) {
+ t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache))
+ }
+ })
+}
+
+// Tests golang/go#40685.
+func TestAcceptImportsQuickFixTestVariant(t *testing.T) {
+ const pkg = `
+-- go.mod --
+module mod.com
+
+go 1.12
+-- a/a.go --
+package a
+
+import (
+ "fmt"
+)
+
+func _() {
+ fmt.Println("")
+ os.Stat("")
+}
+-- a/a_test.go --
+package a
+
+import (
+ "os"
+ "testing"
+)
+
+func TestA(t *testing.T) {
+ os.Stat("")
+}
+`
+ Run(t, pkg, func(t *testing.T, env *Env) {
+ env.OpenFile("a/a.go")
+ var d protocol.PublishDiagnosticsParams
+ env.Await(
+ OnceMet(
+ env.DiagnosticAtRegexp("a/a.go", "os.Stat"),
+ ReadDiagnostics("a/a.go", &d),
+ ),
+ )
+ env.ApplyQuickFixes("a/a.go", d.Diagnostics)
+ env.Await(
+ EmptyDiagnostics("a/a.go"),
+ )
+ })
+}