blob: 359a7804ec4a040d787b8c06f25d011be5141543 [file] [log] [blame] [edit]
// 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 codelens
import (
"runtime"
"testing"
"golang.org/x/tools/gopls/internal/protocol"
"golang.org/x/tools/gopls/internal/protocol/command"
"golang.org/x/tools/gopls/internal/server"
. "golang.org/x/tools/gopls/internal/test/integration"
"golang.org/x/tools/gopls/internal/test/integration/fake"
"golang.org/x/tools/gopls/internal/util/bug"
"golang.org/x/tools/internal/testenv"
)
func TestGCDetails_Toggle(t *testing.T) {
if runtime.GOOS == "android" {
t.Skipf("the gc details code lens doesn't work on Android")
}
// The overlay portion of the test fails with go1.19.
// I'm not sure why and not inclined to investigate.
testenv.NeedsGo1Point(t, 20)
const mod = `
-- go.mod --
module mod.com
go 1.15
-- main.go --
package main
import "fmt"
func main() {
fmt.Println(42)
}
`
WithOptions(
Settings{
"codelenses": map[string]bool{
"gc_details": true,
},
},
).Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil)
env.OnceMet(
CompletedWork(server.DiagnosticWorkTitle(server.FromToggleGCDetails), 1, true),
Diagnostics(
ForFile("main.go"),
WithMessage("42 escapes"),
WithSeverityTags("optimizer details", protocol.SeverityInformation, nil),
),
)
// GCDetails diagnostics should be reported even on unsaved
// edited buffers, thanks to the magic of overlays.
env.SetBufferContent("main.go", `
package main
func main() {}
func f(x int) *int { return &x }`)
env.AfterChange(Diagnostics(
ForFile("main.go"),
WithMessage("x escapes"),
WithSeverityTags("optimizer details", protocol.SeverityInformation, nil),
))
// Toggle the GC details code lens again so now it should be off.
env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil)
env.OnceMet(
CompletedWork(server.DiagnosticWorkTitle(server.FromToggleGCDetails), 2, true),
NoDiagnostics(ForFile("main.go")),
)
})
}
// Test for the crasher in golang/go#54199
func TestGCDetails_NewFile(t *testing.T) {
bug.PanicOnBugs = false
const src = `
-- go.mod --
module mod.test
go 1.12
`
WithOptions(
Settings{
"codelenses": map[string]bool{
"gc_details": true,
},
},
).Run(t, src, func(t *testing.T, env *Env) {
env.CreateBuffer("p_test.go", "")
hasGCDetails := func() bool {
lenses := env.CodeLens("p_test.go") // should not crash
for _, lens := range lenses {
if lens.Command.Command == command.GCDetails.String() {
return true
}
}
return false
}
// With an empty file, we shouldn't get the gc_details codelens because
// there is nowhere to position it (it needs a package name).
if hasGCDetails() {
t.Errorf("got the gc_details codelens for an empty file")
}
// Edit to provide a package name.
env.EditBuffer("p_test.go", fake.NewEdit(0, 0, 0, 0, "package p"))
// Now we should get the gc_details codelens.
if !hasGCDetails() {
t.Errorf("didn't get the gc_details codelens for a valid non-empty Go file")
}
})
}