2020-05-06 20:54:50 -06:00
|
|
|
// 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 regtest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"golang.org/x/tools/internal/lsp/fake"
|
2020-06-07 14:04:51 -06:00
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
2020-05-06 20:54:50 -06:00
|
|
|
"golang.org/x/tools/internal/lsp/source"
|
2020-06-16 15:52:35 -06:00
|
|
|
"golang.org/x/tools/internal/testenv"
|
2020-05-06 20:54:50 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestDisablingCodeLens(t *testing.T) {
|
|
|
|
const workspace = `
|
|
|
|
-- go.mod --
|
|
|
|
module codelens.test
|
|
|
|
-- lib.go --
|
|
|
|
package lib
|
|
|
|
|
|
|
|
type Number int
|
|
|
|
|
|
|
|
const (
|
|
|
|
Zero Number = iota
|
|
|
|
One
|
|
|
|
Two
|
|
|
|
)
|
|
|
|
|
|
|
|
//go:generate stringer -type=Number
|
|
|
|
`
|
|
|
|
tests := []struct {
|
|
|
|
label string
|
|
|
|
enabled map[string]bool
|
|
|
|
wantCodeLens bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
label: "default",
|
|
|
|
wantCodeLens: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: "generate disabled",
|
|
|
|
enabled: map[string]bool{source.CommandGenerate: false},
|
|
|
|
wantCodeLens: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(test.label, func(t *testing.T) {
|
|
|
|
runner.Run(t, workspace, func(t *testing.T, env *Env) {
|
|
|
|
env.OpenFile("lib.go")
|
|
|
|
lens := env.CodeLens("lib.go")
|
|
|
|
if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens {
|
|
|
|
t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens)
|
|
|
|
}
|
|
|
|
}, WithEditorConfig(fake.EditorConfig{CodeLens: test.enabled}))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2020-06-07 14:04:51 -06:00
|
|
|
|
|
|
|
// This test confirms the full functionality of the code lenses for updating
|
|
|
|
// dependencies in a go.mod file. It checks for the code lens that suggests an
|
|
|
|
// update and then executes the command associated with that code lens.
|
|
|
|
// A regression test for golang/go#39446.
|
|
|
|
func TestUpdateCodelens(t *testing.T) {
|
|
|
|
const proxyWithLatest = `
|
|
|
|
-- golang.org/x/hello@v1.3.3/go.mod --
|
|
|
|
module golang.org/x/hello
|
|
|
|
|
|
|
|
go 1.14
|
|
|
|
-- golang.org/x/hello@v1.3.3/hi/hi.go --
|
|
|
|
package hi
|
|
|
|
|
|
|
|
var Goodbye error
|
|
|
|
-- golang.org/x/hello@v1.2.3/go.mod --
|
|
|
|
module golang.org/x/hello
|
|
|
|
|
|
|
|
go 1.14
|
|
|
|
-- golang.org/x/hello@v1.2.3/hi/hi.go --
|
|
|
|
package hi
|
|
|
|
|
|
|
|
var Goodbye error
|
|
|
|
`
|
|
|
|
|
|
|
|
const shouldUpdateDep = `
|
|
|
|
-- go.mod --
|
|
|
|
module mod.com
|
|
|
|
|
|
|
|
go 1.14
|
|
|
|
|
|
|
|
require golang.org/x/hello v1.2.3
|
|
|
|
-- main.go --
|
|
|
|
package main
|
|
|
|
|
|
|
|
import "golang.org/x/hello/hi"
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
_ = hi.Goodbye
|
|
|
|
}
|
|
|
|
`
|
|
|
|
runner.Run(t, shouldUpdateDep, func(t *testing.T, env *Env) {
|
|
|
|
env.OpenFile("go.mod")
|
2020-06-21 21:21:15 -06:00
|
|
|
before := env.ReadWorkspaceFile("go.mod")
|
2020-06-07 14:04:51 -06:00
|
|
|
lenses := env.CodeLens("go.mod")
|
|
|
|
want := "Upgrade dependency to v1.3.3"
|
|
|
|
var found *protocol.CodeLens
|
|
|
|
for _, lens := range lenses {
|
|
|
|
if lens.Command.Title == want {
|
|
|
|
found = &lens
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if found == nil {
|
|
|
|
t.Fatalf("did not find lens %q, got %v", want, lenses)
|
|
|
|
}
|
|
|
|
if _, err := env.Editor.Server.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{
|
|
|
|
Command: found.Command.Command,
|
|
|
|
Arguments: found.Command.Arguments,
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-06-21 21:21:15 -06:00
|
|
|
after := env.ReadWorkspaceFile("go.mod")
|
|
|
|
if before == after {
|
|
|
|
t.Fatalf("go.mod file was unchanged by upgrade command")
|
|
|
|
}
|
2020-06-07 14:04:51 -06:00
|
|
|
}, WithProxy(proxyWithLatest))
|
|
|
|
}
|
2020-06-16 15:52:35 -06:00
|
|
|
|
|
|
|
func TestRegenerateCgo(t *testing.T) {
|
|
|
|
testenv.NeedsTool(t, "cgo")
|
|
|
|
testenv.NeedsGo1Point(t, 15)
|
|
|
|
|
|
|
|
const workspace = `
|
|
|
|
-- go.mod --
|
|
|
|
module example.com
|
|
|
|
-- cgo.go --
|
|
|
|
package x
|
|
|
|
|
|
|
|
/*
|
|
|
|
int fortythree() { return 42; }
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
|
|
|
|
func Foo() {
|
|
|
|
print(C.fortytwo())
|
|
|
|
}
|
|
|
|
`
|
|
|
|
runner.Run(t, workspace, func(t *testing.T, env *Env) {
|
|
|
|
// Open the file. We should have a nonexistant symbol.
|
|
|
|
env.OpenFile("cgo.go")
|
|
|
|
env.Await(env.DiagnosticAtRegexp("cgo.go", `C\.(fortytwo)`)) // could not determine kind of name for C.fortytwo
|
|
|
|
|
|
|
|
// Fix the C function name. We haven't regenerated cgo, so nothing should be fixed.
|
|
|
|
env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo")
|
|
|
|
env.SaveBuffer("cgo.go")
|
|
|
|
env.Await(env.DiagnosticAtRegexp("cgo.go", `C\.(fortytwo)`))
|
|
|
|
|
|
|
|
// Regenerate cgo, fixing the diagnostic.
|
|
|
|
lenses := env.CodeLens("cgo.go")
|
|
|
|
var lens protocol.CodeLens
|
|
|
|
for _, l := range lenses {
|
|
|
|
if l.Command.Command == source.CommandRegenerateCgo {
|
|
|
|
lens = l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if _, err := env.Editor.Server.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{
|
|
|
|
Command: lens.Command.Command,
|
|
|
|
Arguments: lens.Command.Arguments,
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
env.Await(EmptyDiagnostics("cgo.go"))
|
|
|
|
})
|
|
|
|
}
|