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