golang.org/x/tools/gopls@v0.15.3/internal/test/integration/misc/imports_test.go (about)

     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  
     5  package misc
     6  
     7  import (
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"golang.org/x/tools/gopls/internal/test/compare"
    14  	. "golang.org/x/tools/gopls/internal/test/integration"
    15  
    16  	"golang.org/x/tools/gopls/internal/protocol"
    17  )
    18  
    19  // Tests golang/go#38815.
    20  func TestIssue38815(t *testing.T) {
    21  	const needs = `
    22  -- go.mod --
    23  module foo
    24  
    25  go 1.12
    26  -- a.go --
    27  package main
    28  func f() {}
    29  `
    30  	const ntest = `package main
    31  func TestZ(t *testing.T) {
    32  	f()
    33  }
    34  `
    35  	const want = `package main
    36  
    37  import "testing"
    38  
    39  func TestZ(t *testing.T) {
    40  	f()
    41  }
    42  `
    43  
    44  	// it was returning
    45  	// "package main\nimport \"testing\"\npackage main..."
    46  	Run(t, needs, func(t *testing.T, env *Env) {
    47  		env.CreateBuffer("a_test.go", ntest)
    48  		env.SaveBuffer("a_test.go")
    49  		got := env.BufferText("a_test.go")
    50  		if want != got {
    51  			t.Errorf("got\n%q, wanted\n%q", got, want)
    52  		}
    53  	})
    54  }
    55  
    56  func TestIssue59124(t *testing.T) {
    57  	const stuff = `
    58  -- go.mod --
    59  module foo
    60  go 1.19
    61  -- a.go --
    62  //line foo.y:102
    63  package main
    64  
    65  import "fmt"
    66  
    67  //this comment is necessary for failure
    68  func a() {
    69  	fmt.Println("hello")
    70  }
    71  `
    72  	Run(t, stuff, func(t *testing.T, env *Env) {
    73  		env.OpenFile("a.go")
    74  		was := env.BufferText("a.go")
    75  		env.Await(NoDiagnostics())
    76  		env.OrganizeImports("a.go")
    77  		is := env.BufferText("a.go")
    78  		if diff := compare.Text(was, is); diff != "" {
    79  			t.Errorf("unexpected diff after organizeImports:\n%s", diff)
    80  		}
    81  	})
    82  }
    83  
    84  func TestVim1(t *testing.T) {
    85  	const vim1 = `package main
    86  
    87  import "fmt"
    88  
    89  var foo = 1
    90  var bar = 2
    91  
    92  func main() {
    93  	fmt.Printf("This is a test %v\n", foo)
    94  	fmt.Printf("This is another test %v\n", foo)
    95  	fmt.Printf("This is also a test %v\n", foo)
    96  }
    97  `
    98  
    99  	// The file remains unchanged, but if there are any CodeActions returned, they confuse vim.
   100  	// Therefore check for no CodeActions
   101  	Run(t, "", func(t *testing.T, env *Env) {
   102  		env.CreateBuffer("main.go", vim1)
   103  		env.OrganizeImports("main.go")
   104  		actions := env.CodeAction("main.go", nil)
   105  		if len(actions) > 0 {
   106  			got := env.BufferText("main.go")
   107  			t.Errorf("unexpected actions %#v", actions)
   108  			if got == vim1 {
   109  				t.Errorf("no changes")
   110  			} else {
   111  				t.Errorf("got\n%q", got)
   112  				t.Errorf("was\n%q", vim1)
   113  			}
   114  		}
   115  	})
   116  }
   117  
   118  func TestVim2(t *testing.T) {
   119  	const vim2 = `package main
   120  
   121  import (
   122  	"fmt"
   123  
   124  	"example.com/blah"
   125  
   126  	"rubbish.com/useless"
   127  )
   128  
   129  func main() {
   130  	fmt.Println(blah.Name, useless.Name)
   131  }
   132  `
   133  
   134  	Run(t, "", func(t *testing.T, env *Env) {
   135  		env.CreateBuffer("main.go", vim2)
   136  		env.OrganizeImports("main.go")
   137  		actions := env.CodeAction("main.go", nil)
   138  		if len(actions) > 0 {
   139  			t.Errorf("unexpected actions %#v", actions)
   140  		}
   141  	})
   142  }
   143  
   144  func TestGOMODCACHE(t *testing.T) {
   145  	const proxy = `
   146  -- example.com@v1.2.3/go.mod --
   147  module example.com
   148  
   149  go 1.12
   150  -- example.com@v1.2.3/x/x.go --
   151  package x
   152  
   153  const X = 1
   154  -- example.com@v1.2.3/y/y.go --
   155  package y
   156  
   157  const Y = 2
   158  `
   159  	const files = `
   160  -- go.mod --
   161  module mod.com
   162  
   163  go 1.12
   164  
   165  require example.com v1.2.3
   166  -- go.sum --
   167  example.com v1.2.3 h1:6vTQqzX+pnwngZF1+5gcO3ZEWmix1jJ/h+pWS8wUxK0=
   168  example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
   169  -- main.go --
   170  package main
   171  
   172  import "example.com/x"
   173  
   174  var _, _ = x.X, y.Y
   175  `
   176  	modcache, err := os.MkdirTemp("", "TestGOMODCACHE-modcache")
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	defer os.RemoveAll(modcache)
   181  	WithOptions(
   182  		EnvVars{"GOMODCACHE": modcache},
   183  		ProxyFiles(proxy),
   184  	).Run(t, files, func(t *testing.T, env *Env) {
   185  		env.OpenFile("main.go")
   186  		env.AfterChange(Diagnostics(env.AtRegexp("main.go", `y.Y`)))
   187  		env.SaveBuffer("main.go")
   188  		env.AfterChange(NoDiagnostics(ForFile("main.go")))
   189  		loc := env.GoToDefinition(env.RegexpSearch("main.go", `y.(Y)`))
   190  		path := env.Sandbox.Workdir.URIToPath(loc.URI)
   191  		if !strings.HasPrefix(path, filepath.ToSlash(modcache)) {
   192  			t.Errorf("found module dependency outside of GOMODCACHE: got %v, wanted subdir of %v", path, filepath.ToSlash(modcache))
   193  		}
   194  	})
   195  }
   196  
   197  // Tests golang/go#40685.
   198  func TestAcceptImportsQuickFixTestVariant(t *testing.T) {
   199  	const pkg = `
   200  -- go.mod --
   201  module mod.com
   202  
   203  go 1.12
   204  -- a/a.go --
   205  package a
   206  
   207  import (
   208  	"fmt"
   209  )
   210  
   211  func _() {
   212  	fmt.Println("")
   213  	os.Stat("")
   214  }
   215  -- a/a_test.go --
   216  package a
   217  
   218  import (
   219  	"os"
   220  	"testing"
   221  )
   222  
   223  func TestA(t *testing.T) {
   224  	os.Stat("")
   225  }
   226  `
   227  	Run(t, pkg, func(t *testing.T, env *Env) {
   228  		env.OpenFile("a/a.go")
   229  		var d protocol.PublishDiagnosticsParams
   230  		env.AfterChange(
   231  			Diagnostics(env.AtRegexp("a/a.go", "os.Stat")),
   232  			ReadDiagnostics("a/a.go", &d),
   233  		)
   234  		env.ApplyQuickFixes("a/a.go", d.Diagnostics)
   235  		env.AfterChange(
   236  			NoDiagnostics(ForFile("a/a.go")),
   237  		)
   238  	})
   239  }
   240  
   241  // Test for golang/go#52784
   242  func TestGoWorkImports(t *testing.T) {
   243  	const pkg = `
   244  -- go.work --
   245  go 1.19
   246  
   247  use (
   248          ./caller
   249          ./mod
   250  )
   251  -- caller/go.mod --
   252  module caller.com
   253  
   254  go 1.18
   255  
   256  require mod.com v0.0.0
   257  
   258  replace mod.com => ../mod
   259  -- caller/caller.go --
   260  package main
   261  
   262  func main() {
   263          a.Test()
   264  }
   265  -- mod/go.mod --
   266  module mod.com
   267  
   268  go 1.18
   269  -- mod/a/a.go --
   270  package a
   271  
   272  func Test() {
   273  }
   274  `
   275  	Run(t, pkg, func(t *testing.T, env *Env) {
   276  		env.OpenFile("caller/caller.go")
   277  		env.AfterChange(Diagnostics(env.AtRegexp("caller/caller.go", "a.Test")))
   278  
   279  		// Saving caller.go should trigger goimports, which should find a.Test in
   280  		// the mod.com module, thanks to the go.work file.
   281  		env.SaveBuffer("caller/caller.go")
   282  		env.AfterChange(NoDiagnostics(ForFile("caller/caller.go")))
   283  	})
   284  }