golang.org/x/tools/gopls@v0.15.3/internal/test/integration/misc/fix_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package misc 6 7 import ( 8 "testing" 9 10 "golang.org/x/tools/gopls/internal/test/compare" 11 . "golang.org/x/tools/gopls/internal/test/integration" 12 13 "golang.org/x/tools/gopls/internal/protocol" 14 ) 15 16 // A basic test for fillstruct, now that it uses a command and supports resolve edits. 17 func TestFillStruct(t *testing.T) { 18 tc := []struct { 19 name string 20 capabilities string 21 wantCommand bool 22 }{ 23 {"default", "{}", true}, 24 {"no data", `{ "textDocument": {"codeAction": { "resolveSupport": { "properties": ["edit"] } } } }`, true}, 25 {"resolve support", `{ "textDocument": {"codeAction": { "dataSupport": true, "resolveSupport": { "properties": ["edit"] } } } }`, false}, 26 } 27 28 const basic = ` 29 -- go.mod -- 30 module mod.com 31 32 go 1.14 33 -- main.go -- 34 package main 35 36 type Info struct { 37 WordCounts map[string]int 38 Words []string 39 } 40 41 func Foo() { 42 _ = Info{} 43 } 44 ` 45 46 for _, tt := range tc { 47 t.Run(tt.name, func(t *testing.T) { 48 runner := WithOptions(CapabilitiesJSON([]byte(tt.capabilities))) 49 50 runner.Run(t, basic, func(t *testing.T, env *Env) { 51 env.OpenFile("main.go") 52 fixes, err := env.Editor.CodeActions(env.Ctx, env.RegexpSearch("main.go", "Info{}"), nil, protocol.RefactorRewrite) 53 if err != nil { 54 t.Fatal(err) 55 } 56 if len(fixes) != 1 { 57 t.Fatalf("expected 1 code action, got %v", len(fixes)) 58 } 59 if tt.wantCommand { 60 if fixes[0].Command == nil || fixes[0].Data != nil { 61 t.Errorf("expected code action to have command not data, got %v", fixes[0]) 62 } 63 } else { 64 if fixes[0].Command != nil || fixes[0].Data == nil { 65 t.Errorf("expected code action to have command not data, got %v", fixes[0]) 66 } 67 } 68 69 // Apply the code action (handles resolving the code action), and check that the result is correct. 70 if err := env.Editor.RefactorRewrite(env.Ctx, env.RegexpSearch("main.go", "Info{}")); err != nil { 71 t.Fatal(err) 72 } 73 want := `package main 74 75 type Info struct { 76 WordCounts map[string]int 77 Words []string 78 } 79 80 func Foo() { 81 _ = Info{ 82 WordCounts: map[string]int{}, 83 Words: []string{}, 84 } 85 } 86 ` 87 if got := env.BufferText("main.go"); got != want { 88 t.Fatalf("TestFillStruct failed:\n%s", compare.Text(want, got)) 89 } 90 }) 91 }) 92 } 93 } 94 95 func TestFillReturns(t *testing.T) { 96 const files = ` 97 -- go.mod -- 98 module mod.com 99 100 go 1.12 101 -- main.go -- 102 package main 103 104 func Foo() error { 105 return 106 } 107 ` 108 Run(t, files, func(t *testing.T, env *Env) { 109 env.OpenFile("main.go") 110 var d protocol.PublishDiagnosticsParams 111 env.AfterChange( 112 // The error message here changed in 1.18; "return values" covers both forms. 113 Diagnostics(env.AtRegexp("main.go", `return`), WithMessage("return values")), 114 ReadDiagnostics("main.go", &d), 115 ) 116 codeActions := env.CodeAction("main.go", d.Diagnostics) 117 if len(codeActions) != 1 { 118 t.Fatalf("expected 1 code actions, got %v\n%v", len(codeActions), codeActions) 119 } 120 var foundQuickFix bool 121 for _, a := range codeActions { 122 if a.Kind == protocol.QuickFix { 123 foundQuickFix = true 124 } 125 } 126 if !foundQuickFix { 127 t.Fatalf("expected quickfix code action, got none") 128 } 129 env.ApplyQuickFixes("main.go", d.Diagnostics) 130 env.AfterChange(NoDiagnostics(ForFile("main.go"))) 131 }) 132 } 133 134 func TestUnusedParameter_Issue63755(t *testing.T) { 135 // This test verifies the fix for #63755, where codeActions panicked on parameters 136 // of functions with no function body. 137 138 // We should not detect parameters as unused for external functions. 139 140 const files = ` 141 -- go.mod -- 142 module unused.mod 143 144 go 1.18 145 146 -- external.go -- 147 package external 148 149 func External(z int) //@codeaction("refactor.rewrite", "z", "z", recursive) 150 151 func _() { 152 External(1) 153 } 154 ` 155 Run(t, files, func(t *testing.T, env *Env) { 156 env.OpenFile("external.go") 157 actions, err := env.Editor.CodeAction(env.Ctx, env.RegexpSearch("external.go", "z"), nil) 158 if err != nil { 159 t.Fatal(err) 160 } 161 if len(actions) > 0 { 162 t.Errorf("CodeAction(): got %d code actions, want 0", len(actions)) 163 } 164 }) 165 }