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 5package regtest 6 7import ( 8 "strings" 9 "testing" 10 11 "golang.org/x/tools/internal/lsp" 12 "golang.org/x/tools/internal/lsp/tests" 13) 14 15const unformattedProgram = ` 16-- main.go -- 17package main 18import "fmt" 19func main( ) { 20 fmt.Println("Hello World.") 21} 22-- main.go.golden -- 23package main 24 25import "fmt" 26 27func main() { 28 fmt.Println("Hello World.") 29} 30` 31 32func TestFormatting(t *testing.T) { 33 runner.Run(t, unformattedProgram, func(t *testing.T, env *Env) { 34 env.OpenFile("main.go") 35 env.FormatBuffer("main.go") 36 got := env.Editor.BufferText("main.go") 37 want := env.ReadWorkspaceFile("main.go.golden") 38 if got != want { 39 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 40 } 41 }) 42} 43 44// Tests golang/go#36824. 45func TestFormattingOneLine36824(t *testing.T) { 46 const onelineProgram = ` 47-- a.go -- 48package main; func f() {} 49 50-- a.go.formatted -- 51package main 52 53func f() {} 54` 55 runner.Run(t, onelineProgram, func(t *testing.T, env *Env) { 56 env.OpenFile("a.go") 57 env.FormatBuffer("a.go") 58 got := env.Editor.BufferText("a.go") 59 want := env.ReadWorkspaceFile("a.go.formatted") 60 if got != want { 61 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 62 } 63 }) 64} 65 66// Tests golang/go#36824. 67func TestFormattingOneLineImports36824(t *testing.T) { 68 const onelineProgramA = ` 69-- a.go -- 70package x; func f() {fmt.Println()} 71 72-- a.go.imported -- 73package x 74 75import "fmt" 76 77func f() { fmt.Println() } 78` 79 runner.Run(t, onelineProgramA, func(t *testing.T, env *Env) { 80 env.OpenFile("a.go") 81 env.OrganizeImports("a.go") 82 got := env.Editor.BufferText("a.go") 83 want := env.ReadWorkspaceFile("a.go.imported") 84 if got != want { 85 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 86 } 87 }) 88} 89 90func TestFormattingOneLineRmImports36824(t *testing.T) { 91 const onelineProgramB = ` 92-- a.go -- 93package x; import "os"; func f() {} 94 95-- a.go.imported -- 96package x 97 98func f() {} 99` 100 runner.Run(t, onelineProgramB, func(t *testing.T, env *Env) { 101 env.OpenFile("a.go") 102 env.OrganizeImports("a.go") 103 got := env.Editor.BufferText("a.go") 104 want := env.ReadWorkspaceFile("a.go.imported") 105 if got != want { 106 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 107 } 108 }) 109} 110 111const disorganizedProgram = ` 112-- main.go -- 113package main 114 115import ( 116 "fmt" 117 "errors" 118) 119func main( ) { 120 fmt.Println(errors.New("bad")) 121} 122-- main.go.organized -- 123package main 124 125import ( 126 "errors" 127 "fmt" 128) 129func main( ) { 130 fmt.Println(errors.New("bad")) 131} 132-- main.go.formatted -- 133package main 134 135import ( 136 "errors" 137 "fmt" 138) 139 140func main() { 141 fmt.Println(errors.New("bad")) 142} 143` 144 145func TestOrganizeImports(t *testing.T) { 146 runner.Run(t, disorganizedProgram, func(t *testing.T, env *Env) { 147 env.OpenFile("main.go") 148 env.OrganizeImports("main.go") 149 got := env.Editor.BufferText("main.go") 150 want := env.ReadWorkspaceFile("main.go.organized") 151 if got != want { 152 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 153 } 154 }) 155} 156 157func TestFormattingOnSave(t *testing.T) { 158 runner.Run(t, disorganizedProgram, func(t *testing.T, env *Env) { 159 env.OpenFile("main.go") 160 env.SaveBuffer("main.go") 161 got := env.Editor.BufferText("main.go") 162 want := env.ReadWorkspaceFile("main.go.formatted") 163 if got != want { 164 t.Errorf("unexpected formatting result:\n%s", tests.Diff(t, want, got)) 165 } 166 }) 167} 168 169// Tests various possibilities for comments in files with CRLF line endings. 170// Import organization in these files has historically been a source of bugs. 171func TestCRLFLineEndings(t *testing.T) { 172 for _, tt := range []struct { 173 issue, want string 174 }{ 175 { 176 issue: "41057", 177 want: `package main 178 179/* 180Hi description 181*/ 182func Hi() { 183} 184`, 185 }, 186 { 187 issue: "42646", 188 want: `package main 189 190import ( 191 "fmt" 192) 193 194/* 195func upload(c echo.Context) error { 196 if err := r.ParseForm(); err != nil { 197 fmt.Fprintf(w, "ParseForm() err: %v", err) 198 return 199 } 200 fmt.Fprintf(w, "POST request successful") 201 path_ver := r.FormValue("path_ver") 202 ukclin_ver := r.FormValue("ukclin_ver") 203 204 fmt.Fprintf(w, "Name = %s\n", path_ver) 205 fmt.Fprintf(w, "Address = %s\n", ukclin_ver) 206} 207*/ 208 209func main() { 210 const server_port = 8080 211 fmt.Printf("port: %d\n", server_port) 212} 213`, 214 }, 215 { 216 issue: "42923", 217 want: `package main 218 219// Line 1. 220// aa 221type Tree struct { 222 arr []string 223} 224`, 225 }, 226 } { 227 t.Run(tt.issue, func(t *testing.T) { 228 run(t, "-- main.go --", func(t *testing.T, env *Env) { 229 crlf := strings.ReplaceAll(tt.want, "\n", "\r\n") 230 env.CreateBuffer("main.go", crlf) 231 env.Await(CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidOpen), 1)) 232 env.OrganizeImports("main.go") 233 got := env.Editor.BufferText("main.go") 234 got = strings.ReplaceAll(got, "\r\n", "\n") // convert everything to LF for simplicity 235 if tt.want != got { 236 t.Errorf("unexpected content after save:\n%s", tests.Diff(t, tt.want, got)) 237 } 238 }) 239 }) 240 } 241} 242