blob: 39d582298960d236969ca0e1c76edcb93a5c03de [file] [log] [blame]
// 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 misc
import (
"strings"
"testing"
. "golang.org/x/tools/gopls/internal/lsp/regtest"
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
"golang.org/x/tools/internal/testenv"
)
const unformattedProgram = `
-- main.go --
package main
import "fmt"
func main( ) {
fmt.Println("Hello World.")
}
-- main.go.golden --
package main
import "fmt"
func main() {
fmt.Println("Hello World.")
}
`
func TestFormatting(t *testing.T) {
Run(t, unformattedProgram, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.FormatBuffer("main.go")
got := env.Editor.BufferText("main.go")
want := env.ReadWorkspaceFile("main.go.golden")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
// Tests golang/go#36824.
func TestFormattingOneLine36824(t *testing.T) {
const onelineProgram = `
-- a.go --
package main; func f() {}
-- a.go.formatted --
package main
func f() {}
`
Run(t, onelineProgram, func(t *testing.T, env *Env) {
env.OpenFile("a.go")
env.FormatBuffer("a.go")
got := env.Editor.BufferText("a.go")
want := env.ReadWorkspaceFile("a.go.formatted")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
// Tests golang/go#36824.
func TestFormattingOneLineImports36824(t *testing.T) {
const onelineProgramA = `
-- a.go --
package x; func f() {fmt.Println()}
-- a.go.imported --
package x
import "fmt"
func f() { fmt.Println() }
`
Run(t, onelineProgramA, func(t *testing.T, env *Env) {
env.OpenFile("a.go")
env.OrganizeImports("a.go")
got := env.Editor.BufferText("a.go")
want := env.ReadWorkspaceFile("a.go.imported")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
func TestFormattingOneLineRmImports36824(t *testing.T) {
const onelineProgramB = `
-- a.go --
package x; import "os"; func f() {}
-- a.go.imported --
package x
func f() {}
`
Run(t, onelineProgramB, func(t *testing.T, env *Env) {
env.OpenFile("a.go")
env.OrganizeImports("a.go")
got := env.Editor.BufferText("a.go")
want := env.ReadWorkspaceFile("a.go.imported")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
const disorganizedProgram = `
-- main.go --
package main
import (
"fmt"
"errors"
)
func main( ) {
fmt.Println(errors.New("bad"))
}
-- main.go.organized --
package main
import (
"errors"
"fmt"
)
func main( ) {
fmt.Println(errors.New("bad"))
}
-- main.go.formatted --
package main
import (
"errors"
"fmt"
)
func main() {
fmt.Println(errors.New("bad"))
}
`
func TestOrganizeImports(t *testing.T) {
Run(t, disorganizedProgram, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.OrganizeImports("main.go")
got := env.Editor.BufferText("main.go")
want := env.ReadWorkspaceFile("main.go.organized")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
func TestFormattingOnSave(t *testing.T) {
Run(t, disorganizedProgram, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
env.SaveBuffer("main.go")
got := env.Editor.BufferText("main.go")
want := env.ReadWorkspaceFile("main.go.formatted")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}
// Tests various possibilities for comments in files with CRLF line endings.
// Import organization in these files has historically been a source of bugs.
func TestCRLFLineEndings(t *testing.T) {
for _, tt := range []struct {
issue, input, want string
}{
{
issue: "41057",
want: `package main
/*
Hi description
*/
func Hi() {
}
`,
},
{
issue: "42646",
want: `package main
import (
"fmt"
)
/*
func upload(c echo.Context) error {
if err := r.ParseForm(); err != nil {
fmt.Fprintf(w, "ParseForm() err: %v", err)
return
}
fmt.Fprintf(w, "POST request successful")
path_ver := r.FormValue("path_ver")
ukclin_ver := r.FormValue("ukclin_ver")
fmt.Fprintf(w, "Name = %s\n", path_ver)
fmt.Fprintf(w, "Address = %s\n", ukclin_ver)
}
*/
func main() {
const server_port = 8080
fmt.Printf("port: %d\n", server_port)
}
`,
},
{
issue: "42923",
want: `package main
// Line 1.
// aa
type Tree struct {
arr []string
}
`,
},
{
issue: "47200",
input: `package main
import "fmt"
func main() {
math.Sqrt(9)
fmt.Println("hello")
}
`,
want: `package main
import (
"fmt"
"math"
)
func main() {
math.Sqrt(9)
fmt.Println("hello")
}
`,
},
} {
t.Run(tt.issue, func(t *testing.T) {
Run(t, "-- main.go --", func(t *testing.T, env *Env) {
input := tt.input
if input == "" {
input = tt.want
}
crlf := strings.ReplaceAll(input, "\n", "\r\n")
env.CreateBuffer("main.go", crlf)
env.Await(env.DoneWithOpen())
env.OrganizeImports("main.go")
got := env.Editor.BufferText("main.go")
got = strings.ReplaceAll(got, "\r\n", "\n") // convert everything to LF for simplicity
if tt.want != got {
t.Errorf("unexpected content after save:\n%s", compare.Text(tt.want, got))
}
})
})
}
}
func TestFormattingOfGeneratedFile_Issue49555(t *testing.T) {
const input = `
-- main.go --
// Code generated by generator.go. DO NOT EDIT.
package main
import "fmt"
func main() {
fmt.Print("hello")
}
`
Run(t, input, func(t *testing.T, env *Env) {
wantErrSuffix := "file is generated"
env.OpenFile("main.go")
err := env.Editor.FormatBuffer(env.Ctx, "main.go")
if err == nil {
t.Fatal("expected error, got nil")
}
// Check only the suffix because an error contains a dynamic path to main.go
if !strings.HasSuffix(err.Error(), wantErrSuffix) {
t.Fatalf("unexpected error %q, want suffix %q", err.Error(), wantErrSuffix)
}
})
}
func TestGofumptFormatting(t *testing.T) {
testenv.NeedsGo1Point(t, 18)
// Exercise some gofumpt formatting rules:
// - No empty lines following an assignment operator
// - Octal integer literals should use the 0o prefix on modules using Go
// 1.13 and later. Requires LangVersion to be correctly resolved.
// - std imports must be in a separate group at the top. Requires ModulePath
// to be correctly resolved.
const input = `
-- go.mod --
module foo
go 1.17
-- foo.go --
package foo
import (
"foo/bar"
"fmt"
)
const perm = 0755
func foo() {
foo :=
"bar"
fmt.Println(foo, bar.Bar)
}
-- foo.go.formatted --
package foo
import (
"fmt"
"foo/bar"
)
const perm = 0o755
func foo() {
foo := "bar"
fmt.Println(foo, bar.Bar)
}
-- bar/bar.go --
package bar
const Bar = 42
`
WithOptions(
Settings{
"gofumpt": true,
},
).Run(t, input, func(t *testing.T, env *Env) {
env.OpenFile("foo.go")
env.FormatBuffer("foo.go")
got := env.Editor.BufferText("foo.go")
want := env.ReadWorkspaceFile("foo.go.formatted")
if got != want {
t.Errorf("unexpected formatting result:\n%s", compare.Text(want, got))
}
})
}