1// Copyright 2020 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 5package misc 6 7import ( 8 "io/ioutil" 9 "os" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 . "golang.org/x/tools/internal/lsp/regtest" 15 16 "golang.org/x/tools/internal/lsp/protocol" 17 "golang.org/x/tools/internal/testenv" 18) 19 20// Tests golang/go#38815. 21func TestIssue38815(t *testing.T) { 22 const needs = ` 23-- go.mod -- 24module foo 25 26go 1.12 27-- a.go -- 28package main 29func f() {} 30` 31 const ntest = `package main 32func TestZ(t *testing.T) { 33 f() 34} 35` 36 const want = `package main 37 38import "testing" 39 40func TestZ(t *testing.T) { 41 f() 42} 43` 44 45 // it was returning 46 // "package main\nimport \"testing\"\npackage main..." 47 Run(t, needs, func(t *testing.T, env *Env) { 48 env.CreateBuffer("a_test.go", ntest) 49 env.SaveBuffer("a_test.go") 50 got := env.Editor.BufferText("a_test.go") 51 if want != got { 52 t.Errorf("got\n%q, wanted\n%q", got, want) 53 } 54 }) 55} 56 57func TestVim1(t *testing.T) { 58 const vim1 = `package main 59 60import "fmt" 61 62var foo = 1 63var bar = 2 64 65func main() { 66 fmt.Printf("This is a test %v\n", foo) 67 fmt.Printf("This is another test %v\n", foo) 68 fmt.Printf("This is also a test %v\n", foo) 69} 70` 71 72 // The file remains unchanged, but if there are any CodeActions returned, they confuse vim. 73 // Therefore check for no CodeActions 74 Run(t, "", func(t *testing.T, env *Env) { 75 env.CreateBuffer("main.go", vim1) 76 env.OrganizeImports("main.go") 77 actions := env.CodeAction("main.go", nil) 78 if len(actions) > 0 { 79 got := env.Editor.BufferText("main.go") 80 t.Errorf("unexpected actions %#v", actions) 81 if got == vim1 { 82 t.Errorf("no changes") 83 } else { 84 t.Errorf("got\n%q", got) 85 t.Errorf("was\n%q", vim1) 86 } 87 } 88 }) 89} 90 91func TestVim2(t *testing.T) { 92 const vim2 = `package main 93 94import ( 95 "fmt" 96 97 "example.com/blah" 98 99 "rubbish.com/useless" 100) 101 102func main() { 103 fmt.Println(blah.Name, useless.Name) 104} 105` 106 107 Run(t, "", func(t *testing.T, env *Env) { 108 env.CreateBuffer("main.go", vim2) 109 env.OrganizeImports("main.go") 110 actions := env.CodeAction("main.go", nil) 111 if len(actions) > 0 { 112 t.Errorf("unexpected actions %#v", actions) 113 } 114 }) 115} 116 117func TestGOMODCACHE(t *testing.T) { 118 const proxy = ` 119-- example.com@v1.2.3/go.mod -- 120module example.com 121 122go 1.12 123-- example.com@v1.2.3/x/x.go -- 124package x 125 126const X = 1 127-- example.com@v1.2.3/y/y.go -- 128package y 129 130const Y = 2 131` 132 const files = ` 133-- go.mod -- 134module mod.com 135 136go 1.12 137 138require example.com v1.2.3 139-- go.sum -- 140example.com v1.2.3 h1:6vTQqzX+pnwngZF1+5gcO3ZEWmix1jJ/h+pWS8wUxK0= 141example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= 142-- main.go -- 143package main 144 145import "example.com/x" 146 147var _, _ = x.X, y.Y 148` 149 testenv.NeedsGo1Point(t, 15) 150 151 modcache, err := ioutil.TempDir("", "TestGOMODCACHE-modcache") 152 if err != nil { 153 t.Fatal(err) 154 } 155 defer os.RemoveAll(modcache) 156 editorConfig := EditorConfig{Env: map[string]string{"GOMODCACHE": modcache}} 157 WithOptions( 158 editorConfig, 159 ProxyFiles(proxy), 160 ).Run(t, files, func(t *testing.T, env *Env) { 161 env.OpenFile("main.go") 162 env.Await(env.DiagnosticAtRegexp("main.go", `y.Y`)) 163 env.SaveBuffer("main.go") 164 env.Await(EmptyDiagnostics("main.go")) 165 path, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `y.(Y)`)) 166 if !strings.HasPrefix(path, filepath.ToSlash(modcache)) { 167 t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache)) 168 } 169 }) 170} 171 172// Tests golang/go#40685. 173func TestAcceptImportsQuickFixTestVariant(t *testing.T) { 174 const pkg = ` 175-- go.mod -- 176module mod.com 177 178go 1.12 179-- a/a.go -- 180package a 181 182import ( 183 "fmt" 184) 185 186func _() { 187 fmt.Println("") 188 os.Stat("") 189} 190-- a/a_test.go -- 191package a 192 193import ( 194 "os" 195 "testing" 196) 197 198func TestA(t *testing.T) { 199 os.Stat("") 200} 201` 202 Run(t, pkg, func(t *testing.T, env *Env) { 203 env.OpenFile("a/a.go") 204 var d protocol.PublishDiagnosticsParams 205 env.Await( 206 OnceMet( 207 env.DiagnosticAtRegexp("a/a.go", "os.Stat"), 208 ReadDiagnostics("a/a.go", &d), 209 ), 210 ) 211 env.ApplyQuickFixes("a/a.go", d.Diagnostics) 212 env.Await( 213 EmptyDiagnostics("a/a.go"), 214 ) 215 }) 216} 217