1
0
mirror of https://github.com/golang/go synced 2024-10-01 10:38:33 -06:00
go/internal/lsp/cmd/test/format.go
Ian Cottrell 0ae87fff1b internal/lsp: fix a race in the command line tests
except the race was a symptom of a larger problem, so the fix
actually invovles cleaning up the way we run command line tests
totally to have common shared infrastructure, and also to clean up
the way we handle errors and paths into the temporary directory

Fixes: golang/go#35436
Change-Id: I4c5602607bb70e082056132baa3d4b0f8df6b13b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/208269
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2019-11-22 16:15:56 +00:00

87 lines
2.5 KiB
Go

// Copyright 2019 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 cmdtest
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strings"
"testing"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/testenv"
)
func (r *runner) Format(t *testing.T, spn span.Span) {
tag := "gofmt"
uri := spn.URI()
filename := uri.Filename()
expect := string(r.data.Golden(tag, filename, func() ([]byte, error) {
cmd := exec.Command("gofmt", filename)
contents, _ := cmd.Output() // ignore error, sometimes we have intentionally ungofmt-able files
contents = []byte(r.Normalize(fixFileHeader(string(contents))))
return contents, nil
}))
if expect == "" {
//TODO: our error handling differs, for now just skip unformattable files
t.Skip("Unformattable file")
}
got, _ := r.NormalizeGoplsCmd(t, "format", filename)
if expect != got {
t.Errorf("format failed for %s expected:\n%s\ngot:\n%s", filename, expect, got)
}
// now check we can build a valid unified diff
unified, _ := r.NormalizeGoplsCmd(t, "format", "-d", filename)
checkUnified(t, filename, expect, unified)
}
var unifiedHeader = regexp.MustCompile(`^diff -u.*\n(---\s+\S+\.go\.orig)\s+[\d-:. ]+(\n\+\+\+\s+\S+\.go)\s+[\d-:. ]+(\n@@)`)
func fixFileHeader(s string) string {
match := unifiedHeader.FindStringSubmatch(s)
if match == nil {
return s
}
return strings.Join(append(match[1:], s[len(match[0]):]), "")
}
func checkUnified(t *testing.T, filename string, expect string, patch string) {
testenv.NeedsTool(t, "patch")
if strings.Count(patch, "\n+++ ") > 1 {
// TODO(golang/go/#34580)
t.Skip("multi-file patch tests not supported yet")
}
applied := ""
if patch == "" {
applied = expect
} else {
temp, err := ioutil.TempFile("", "applied")
if err != nil {
t.Fatal(err)
}
temp.Close()
defer os.Remove(temp.Name())
cmd := exec.Command("patch", "-u", "-p0", "-o", temp.Name(), filename)
cmd.Stdin = bytes.NewBuffer([]byte(patch))
msg, err := cmd.CombinedOutput()
if err != nil {
t.Errorf("failed applying patch to %s: %v\ngot:\n%s\npatch:\n%s", filename, err, msg, patch)
return
}
out, err := ioutil.ReadFile(temp.Name())
if err != nil {
t.Errorf("failed reading patched output for %s: %v\n", filename, err)
return
}
applied = string(out)
}
if expect != applied {
t.Errorf("apply unified gave wrong result for %s expected:\n%s\ngot:\n%s\npatch:\n%s", filename, expect, applied, patch)
}
}