1
0
mirror of https://github.com/golang/go synced 2024-11-19 00:54:42 -07:00
go/internal/lsp/mod/mod_test.go
Rebecca Stambler f04f2c82d0 internal/lsp/cache: refactor initialization for builtins
This change combines the two packages.Load calls that happen on view
creation. Builtins can be loaded along with the rest of the workspace.

To avoid race conditions, create a builtinPackageHandle type for
builtins and use it to create the data.

Updates golang/go#36531

Change-Id: I7aa342c463a0b7718e1ad5fee507622310d8443b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/214877
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
2020-01-15 21:04:26 +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(ctx)
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(ctx)
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, 17)},
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, 4)},
Severity: protocol.SeverityError,
},
},
},
{
testdir: "unknowndirective",
want: []source.Diagnostic{
{
Message: "unknown directive: yo",
Source: "syntax",
Range: protocol.Range{Start: getRawPos(6, 0), End: getRawPos(6, 2)},
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.ModFiles(ctx)
return t != nil
}
func getRawPos(line, character int) protocol.Position {
return protocol.Position{
Line: float64(line),
Character: float64(character),
}
}