1
0
mirror of https://github.com/golang/go synced 2024-10-01 04:08:32 -06:00
go/internal/lsp/mod/mod_test.go
Rohan Challa c4cbd3b08f internal/lsp: add diagnostics in .go files for missing deps in go.mod
This change adds diagnostics to imports in .go files that are missing the dependency in the go.mod file. The quick fix that adds the appropriate require statement is coming in a follow up CL.

Updates golang/go#31999

Change-Id: I314cdbe8e3dd27da744ca0391e7a6e5dc1ebaa77
Reviewed-on: https://go-review.googlesource.com/c/tools/+/216277
Run-TryBot: Rohan Challa <rohan@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2020-02-03 17:57:15 +00:00

180 lines
4.9 KiB
Go

// Copyright 2019 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 mod
import (
"context"
"io/ioutil"
"os"
"path/filepath"
"testing"
"golang.org/x/tools/internal/lsp/cache"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/lsp/tests"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/testenv"
)
func TestMain(m *testing.M) {
testenv.ExitIfSmallMachine()
os.Exit(m.Run())
}
// TODO(golang/go#36091): This file can be refactored to look like lsp_test.go
// when marker support gets added for go.mod files.
func TestModfileRemainsUnchanged(t *testing.T) {
ctx := tests.Context(t)
cache := cache.New(nil)
session := cache.NewSession()
options := tests.DefaultOptions()
options.TempModfile = true
options.Env = append(os.Environ(), "GOPACKAGESDRIVER=off", "GOROOT=")
// Make sure to copy the test directory to a temporary directory so we do not
// modify the test code or add go.sum files when we run the tests.
folder, err := tests.CopyFolderToTempDir(filepath.Join("testdata", "unchanged"))
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(folder)
before, err := ioutil.ReadFile(filepath.Join(folder, "go.mod"))
if err != nil {
t.Fatal(err)
}
_, snapshot, err := session.NewView(ctx, "diagnostics_test", span.FileURI(folder), options)
if err != nil {
t.Fatal(err)
}
if !hasTempModfile(ctx, snapshot) {
return
}
after, err := ioutil.ReadFile(filepath.Join(folder, "go.mod"))
if err != nil {
t.Fatal(err)
}
if string(before) != string(after) {
t.Errorf("the real go.mod file was changed even when tempModfile=true")
}
}
// TODO(golang/go#36091): This file can be refactored to look like lsp_test.go
// when marker support gets added for go.mod files.
func TestDiagnostics(t *testing.T) {
ctx := tests.Context(t)
cache := cache.New(nil)
session := cache.NewSession()
options := tests.DefaultOptions()
options.TempModfile = true
options.Env = append(os.Environ(), "GOPACKAGESDRIVER=off", "GOROOT=")
for _, tt := range []struct {
testdir string
want []source.Diagnostic
}{
{
testdir: "indirect",
want: []source.Diagnostic{
{
Message: "golang.org/x/tools should be a direct dependency.",
Source: "go mod tidy",
// TODO(golang/go#36091): When marker support gets added for go.mod files, we
// can remove these hard coded positions.
Range: protocol.Range{Start: getRawPos(4, 62), End: getRawPos(4, 73)},
Severity: protocol.SeverityWarning,
},
},
},
{
testdir: "unused",
want: []source.Diagnostic{
{
Message: "golang.org/x/tools is not used in this module.",
Source: "go mod tidy",
Range: protocol.Range{Start: getRawPos(4, 0), End: getRawPos(4, 61)},
Severity: protocol.SeverityWarning,
},
},
},
{
testdir: "invalidrequire",
want: []source.Diagnostic{
{
Message: "usage: require module/path v1.2.3",
Source: "syntax",
Range: protocol.Range{Start: getRawPos(4, 0), End: getRawPos(4, 16)},
Severity: protocol.SeverityError,
},
},
},
{
testdir: "invalidgo",
want: []source.Diagnostic{
{
Message: "usage: go 1.23",
Source: "syntax",
Range: protocol.Range{Start: getRawPos(2, 0), End: getRawPos(2, 3)},
Severity: protocol.SeverityError,
},
},
},
{
testdir: "unknowndirective",
want: []source.Diagnostic{
{
Message: "unknown directive: yo",
Source: "syntax",
Range: protocol.Range{Start: getRawPos(6, 0), End: getRawPos(6, 1)},
Severity: protocol.SeverityError,
},
},
},
} {
t.Run(tt.testdir, func(t *testing.T) {
// TODO: Once we refactor this to work with go/packages/packagestest. We do not
// need to copy to a temporary directory.
folder, err := tests.CopyFolderToTempDir(filepath.Join("testdata", tt.testdir))
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(folder)
_, snapshot, err := session.NewView(ctx, "diagnostics_test", span.FileURI(folder), options)
if err != nil {
t.Fatal(err)
}
// TODO: Add testing for when the -modfile flag is turned off and we still get diagnostics.
if !hasTempModfile(ctx, snapshot) {
return
}
reports, _, err := Diagnostics(ctx, snapshot)
if err != nil {
t.Fatal(err)
}
if len(reports) != 1 {
t.Errorf("expected 1 diagnostic, got %d", len(reports))
}
for fh, got := range reports {
if diff := tests.DiffDiagnostics(fh.URI, tt.want, got); diff != "" {
t.Error(diff)
}
}
})
}
}
func hasTempModfile(ctx context.Context, snapshot source.Snapshot) bool {
_, t := snapshot.View().ModFiles()
return t != ""
}
func getRawPos(line, character int) protocol.Position {
return protocol.Position{
Line: float64(line),
Character: float64(character),
}
}