Skip to content

Commit 95dc314

Browse files
committed
add tests for code action
1 parent c37ae11 commit 95dc314

File tree

9 files changed

+186
-23
lines changed

9 files changed

+186
-23
lines changed

gopls/doc/codelenses.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ Default: on
4040

4141
File type: Go
4242

43+
## `go_to_test`: Go to the functions's Test, Example, Benchmark, or Fuzz declarations
44+
45+
46+
This codelens source annotates function and method declarations
47+
with their corresponding Test, Example, Benchmark, and Fuzz functions.
48+
49+
50+
Default: off
51+
52+
File type: Go
53+
4354
## `regenerate_cgo`: Re-generate cgo declarations
4455

4556

gopls/internal/cache/testfuncs/tests.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"go/ast"
99
"go/constant"
1010
"go/types"
11+
"iter"
1112
"strings"
1213
"unicode"
1314
"unicode/utf8"
@@ -35,14 +36,16 @@ func (index *Index) Encode() []byte {
3536
return packageCodec.Encode(index.pkg)
3637
}
3738

38-
func (index *Index) All() []Result {
39-
var results []Result
40-
for _, file := range index.pkg.Files {
41-
for _, test := range file.Tests {
42-
results = append(results, test.result())
39+
func (index *Index) All() iter.Seq[Result] {
40+
return func(yield func(Result) bool) {
41+
for _, file := range index.pkg.Files {
42+
for _, test := range file.Tests {
43+
if !yield(test.result()) {
44+
return
45+
}
46+
}
4347
}
4448
}
45-
return results
4649
}
4750

4851
// A Result reports a test function

gopls/internal/doc/api.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,12 @@
19171917
"Default": "true",
19181918
"Status": ""
19191919
},
1920+
{
1921+
"Name": "\"go_to_test\"",
1922+
"Doc": "`\"go_to_test\"`: Go to the functions's Test, Example, Benchmark, or Fuzz declarations\n\nThis codelens source annotates function and method declarations\nwith their corresponding Test, Example, Benchmark, and Fuzz functions.\n",
1923+
"Default": "false",
1924+
"Status": ""
1925+
},
19201926
{
19211927
"Name": "\"regenerate_cgo\"",
19221928
"Doc": "`\"regenerate_cgo\"`: Re-generate cgo declarations\n\nThis codelens source annotates an `import \"C\"` declaration\nwith a command to re-run the [cgo\ncommand](https://pkg.go.dev/cmd/cgo) to regenerate the\ncorresponding Go declarations.\n\nUse this after editing the C code in comments attached to\nthe import, or in C header files included by it.\n",
@@ -2104,6 +2110,14 @@
21042110
"Default": true,
21052111
"Status": ""
21062112
},
2113+
{
2114+
"FileType": "Go",
2115+
"Lens": "go_to_test",
2116+
"Title": "Go to the functions's Test, Example, Benchmark, or Fuzz declarations",
2117+
"Doc": "\nThis codelens source annotates function and method declarations\nwith their corresponding Test, Example, Benchmark, and Fuzz functions.\n",
2118+
"Default": false,
2119+
"Status": ""
2120+
},
21072121
{
21082122
"FileType": "Go",
21092123
"Lens": "regenerate_cgo",

gopls/internal/golang/code_lens.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ func regenerateCgoLens(ctx context.Context, snapshot *cache.Snapshot, fh file.Ha
214214
}
215215

216216
func goToTestCodeLens(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle) ([]protocol.CodeLens, error) {
217+
if !snapshot.Options().ClientOptions.ShowDocumentSupported {
218+
// GoToTest command uses 'window/showDocument' request. Don't generate
219+
// code lenses for clients that won't be able to use them.
220+
return nil, nil
221+
}
222+
217223
matches, err := matchFunctionsWithTests(ctx, snapshot, fh)
218224
if err != nil {
219225
return nil, err
@@ -298,7 +304,7 @@ func matchFunctionsWithTests(ctx context.Context, snapshot *cache.Snapshot, fh f
298304
return nil, fmt.Errorf("couldn't request all tests for packages %v: %w", pkgIDs, err)
299305
}
300306
for _, tests := range allTests {
301-
for _, test := range tests.All() {
307+
for test := range tests.All() {
302308
if test.Subtest {
303309
continue
304310
}
@@ -310,9 +316,9 @@ func matchFunctionsWithTests(ctx context.Context, snapshot *cache.Snapshot, fh f
310316
var matchedFunc Func
311317
for _, fn := range fileFuncs {
312318
var matched bool
313-
for _, n := range potentialFuncNames {
314-
// Check the prefix to be able to match 'TestDeletePanics' with 'Delete'.
315-
if strings.HasPrefix(n, fn.Name) {
319+
for _, potentialName := range potentialFuncNames {
320+
// Check the prefix to match 'TestDeletePanics' with 'Delete'.
321+
if strings.HasPrefix(potentialName, fn.Name) {
316322
matched = true
317323
break
318324
}
@@ -373,13 +379,13 @@ func getPotentialFuncNames(test testfuncs.Result) []string {
373379
if name == "" {
374380
return nil
375381
}
376-
name = strings.TrimPrefix(name, "_")
377-
378-
lowerCasedName := []rune(name)
379-
lowerCasedName[0] = unicode.ToLower(lowerCasedName[0])
382+
name = strings.TrimPrefix(name, "_") // 'Foo' for 'TestFoo', 'foo' for 'Test_foo'
380383

381-
return []string{
382-
name, // 'Foo' for 'TestFoo', 'foo' for 'Test_foo'
383-
string(lowerCasedName), // 'foo' for 'TestFoo'
384+
names := []string{name}
385+
if token.IsExported(name) {
386+
unexportedName := []rune(name)
387+
unexportedName[0] = unicode.ToLower(unexportedName[0])
388+
names = append(names, string(unexportedName)) // 'foo' for 'TestFoo'
384389
}
390+
return names
385391
}

gopls/internal/golang/codeaction.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ var codeActionProducers = [...]codeActionProducer{
266266
{kind: settings.RefactorRewriteEliminateDotImport, fn: refactorRewriteEliminateDotImport, needPkg: true},
267267
{kind: settings.RefactorRewriteAddTags, fn: refactorRewriteAddStructTags, needPkg: true},
268268
{kind: settings.RefactorRewriteRemoveTags, fn: refactorRewriteRemoveStructTags, needPkg: true},
269-
{kind: settings.GoToTest, fn: goToTest, needPkg: true},
269+
{kind: settings.GoToTest, fn: goToTestCodeAction, needPkg: true},
270270
{kind: settings.GoplsDocFeatures, fn: goplsDocFeatures}, // offer this one last (#72742)
271271

272272
// Note: don't forget to update the allow-list in Server.CodeAction
@@ -1131,10 +1131,14 @@ func toggleCompilerOptDetails(ctx context.Context, req *codeActionsRequest) erro
11311131
return nil
11321132
}
11331133

1134-
// goToTest produces "Go to TestXxx" code action.
1134+
// goToTestCodeAction produces "Go to TestXxx" code action.
11351135
// See [server.commandHandler.GoToTest] for command implementation.
1136-
func goToTest(ctx context.Context, req *codeActionsRequest) error {
1137-
// TODO: add tests.
1136+
func goToTestCodeAction(ctx context.Context, req *codeActionsRequest) error {
1137+
if !req.snapshot.Options().ClientOptions.ShowDocumentSupported {
1138+
// GoToTest command uses 'window/showDocument' request. Don't generate
1139+
// code actions for clients that won't be able to use them.
1140+
return nil
1141+
}
11381142

11391143
path, _ := astutil.PathEnclosingInterval(req.pgf.File, req.start, req.end)
11401144
if len(path) < 2 {

gopls/internal/server/command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func (h *commandHandler) Packages(ctx context.Context, args command.PackagesArgs
234234
for i, tests := range allTests {
235235
pkg := &result.Packages[start+i]
236236
fileByPath := map[protocol.DocumentURI]*command.TestFile{}
237-
for _, test := range tests.All() {
237+
for test := range tests.All() {
238238
test := command.TestCase{
239239
Name: test.Name,
240240
Loc: test.Location,

gopls/internal/settings/settings.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ const (
359359

360360
// Go to the functions's Test, Example, Benchmark, or Fuzz declarations
361361
//
362-
// This codelens source annotates the function and method declarations
362+
// This codelens source annotates function and method declarations
363363
// with their corresponding Test, Example, Benchmark, and Fuzz functions.
364364
CodeLensGoToTest CodeLensSource = "go_to_test"
365365
)

gopls/internal/test/integration/misc/codeactions_test.go

Lines changed: 115 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gopls/internal/test/marker/testdata/codelens/go_to_test.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@ func bar() {} //@codelens(re"()func bar", "Go to Test_bar"),codelens(re"()func b
1616

1717
func xyz() {} //@codelens(re"()func xyz", "Go to TestXyz")
1818

19+
func Translate() { //@codelens(re"()func Translate", "Go to TestTranslate")
20+
translate()
21+
}
22+
23+
func translate() {}
24+
1925
-- a1_test.go --
2026
package codelenses
2127

2228
import "testing"
2329

2430
func TestFoo(*testing.T) {}
2531

32+
func TestTranslate(*testing.T) {
33+
translate()
34+
}
35+
2636
-- a2_test.go --
2737
package codelenses
2838

0 commit comments

Comments
 (0)