mirror of
https://github.com/golang/go
synced 2024-11-19 04:54:41 -07:00
cmd/gofmt: make test files self-describing
1) Interpret a comment of the form //gofmt <flags> in test files to drive the respective gofmt command. Eliminates the need to enumerate all test files in the test harness. 2) Added -update flag to make it easier to update test cases. LGTM=josharian R=golang-codereviews, josharian CC=golang-codereviews https://golang.org/cl/130440043
This commit is contained in:
parent
bc64c07825
commit
67812a7cd9
@ -6,18 +6,60 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"text/scanner"
|
||||
)
|
||||
|
||||
func runTest(t *testing.T, in, out, flags string) {
|
||||
var update = flag.Bool("update", false, "update .golden files")
|
||||
|
||||
// gofmtFlags looks for a comment of the form
|
||||
//
|
||||
// //gofmt flags
|
||||
//
|
||||
// within the first maxLines lines of the given file,
|
||||
// and returns the flags string, if any. Otherwise it
|
||||
// returns the empty string.
|
||||
func gofmtFlags(filename string, maxLines int) string {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return "" // ignore errors - they will be found later
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// initialize scanner
|
||||
var s scanner.Scanner
|
||||
s.Init(f)
|
||||
s.Error = func(*scanner.Scanner, string) {} // ignore errors
|
||||
s.Mode = scanner.GoTokens &^ scanner.SkipComments // want comments
|
||||
|
||||
// look for //gofmt comment
|
||||
for s.Line <= maxLines {
|
||||
switch s.Scan() {
|
||||
case scanner.Comment:
|
||||
const prefix = "//gofmt "
|
||||
if t := s.TokenText(); strings.HasPrefix(t, prefix) {
|
||||
return strings.TrimSpace(t[len(prefix):])
|
||||
}
|
||||
case scanner.EOF:
|
||||
return ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func runTest(t *testing.T, in, out string) {
|
||||
// process flags
|
||||
*simplifyAST = false
|
||||
*rewriteRule = ""
|
||||
stdin := false
|
||||
for _, flag := range strings.Split(flags, " ") {
|
||||
for _, flag := range strings.Split(gofmtFlags(in, 20), " ") {
|
||||
elts := strings.SplitN(flag, "=", 2)
|
||||
name := elts[0]
|
||||
value := ""
|
||||
@ -56,6 +98,17 @@ func runTest(t *testing.T, in, out, flags string) {
|
||||
}
|
||||
|
||||
if got := buf.Bytes(); !bytes.Equal(got, expected) {
|
||||
if *update {
|
||||
if in != out {
|
||||
if err := ioutil.WriteFile(out, got, 0666); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
// in == out: don't accidentally destroy input
|
||||
t.Errorf("WARNING: -update did not rewrite input file %s", in)
|
||||
}
|
||||
|
||||
t.Errorf("(gofmt %s) != %s (see %s.gofmt)", in, out, in)
|
||||
d, err := diff(expected, got)
|
||||
if err == nil {
|
||||
@ -67,53 +120,37 @@ func runTest(t *testing.T, in, out, flags string) {
|
||||
}
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
in, flags string
|
||||
}{
|
||||
{"gofmt.go", ""},
|
||||
{"gofmt_test.go", ""},
|
||||
{"testdata/composites.input", "-s"},
|
||||
{"testdata/slices1.input", "-s"},
|
||||
{"testdata/slices2.input", "-s"},
|
||||
{"testdata/ranges.input", "-s"},
|
||||
{"testdata/old.input", ""},
|
||||
{"testdata/rewrite1.input", "-r=Foo->Bar"},
|
||||
{"testdata/rewrite2.input", "-r=int->bool"},
|
||||
{"testdata/rewrite3.input", "-r=x->x"},
|
||||
{"testdata/rewrite4.input", "-r=(x)->x"},
|
||||
{"testdata/rewrite5.input", "-r=x+x->2*x"},
|
||||
{"testdata/rewrite6.input", "-r=fun(x)->Fun(x)"},
|
||||
{"testdata/rewrite7.input", "-r=fun(x...)->Fun(x)"},
|
||||
{"testdata/rewrite8.input", "-r=interface{}->int"},
|
||||
{"testdata/stdin*.input", "-stdin"},
|
||||
{"testdata/comments.input", ""},
|
||||
{"testdata/import.input", ""},
|
||||
{"testdata/crlf.input", ""}, // test case for issue 3961; see also TestCRLF
|
||||
{"testdata/typeswitch.input", ""}, // test case for issue 4470
|
||||
{"testdata/emptydecl.input", "-s"}, // test case for issue 7631
|
||||
// TestRewrite processes testdata/*.input files and compares them to the
|
||||
// corresponding testdata/*.golden files. The gofmt flags used to process
|
||||
// a file must be provided via a comment of the form
|
||||
//
|
||||
// //gofmt flags
|
||||
//
|
||||
// in the processed file within the first 20 lines, if any.
|
||||
func TestRewrite(t *testing.T) {
|
||||
// determine input files
|
||||
match, err := filepath.Glob("testdata/*.input")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
func TestRewrite(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
match, err := filepath.Glob(test.in)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
continue
|
||||
}
|
||||
// add larger examples
|
||||
match = append(match, "gofmt.go", "gofmt_test.go")
|
||||
|
||||
for _, in := range match {
|
||||
out := in
|
||||
out := in // for files where input and output are identical
|
||||
if strings.HasSuffix(in, ".input") {
|
||||
out = in[:len(in)-len(".input")] + ".golden"
|
||||
}
|
||||
runTest(t, in, out, test.flags)
|
||||
runTest(t, in, out)
|
||||
if in != out {
|
||||
// Check idempotence.
|
||||
runTest(t, out, out, test.flags)
|
||||
}
|
||||
runTest(t, out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test case for issue 3961.
|
||||
func TestCRLF(t *testing.T) {
|
||||
const input = "testdata/crlf.input" // must contain CR/LF's
|
||||
const golden = "testdata/crlf.golden" // must not contain any CR's
|
||||
|
2
src/cmd/gofmt/testdata/composites.golden
vendored
2
src/cmd/gofmt/testdata/composites.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
package P
|
||||
|
||||
type T struct {
|
||||
|
2
src/cmd/gofmt/testdata/composites.input
vendored
2
src/cmd/gofmt/testdata/composites.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
package P
|
||||
|
||||
type T struct {
|
||||
|
1
src/cmd/gofmt/testdata/crlf.golden
vendored
1
src/cmd/gofmt/testdata/crlf.golden
vendored
@ -2,6 +2,7 @@
|
||||
Source containing CR/LF line endings.
|
||||
The gofmt'ed output must only have LF
|
||||
line endings.
|
||||
Test case for issue 3961.
|
||||
*/
|
||||
package main
|
||||
|
||||
|
1
src/cmd/gofmt/testdata/crlf.input
vendored
1
src/cmd/gofmt/testdata/crlf.input
vendored
@ -2,6 +2,7 @@
|
||||
Source containing CR/LF line endings.
|
||||
The gofmt'ed output must only have LF
|
||||
line endings.
|
||||
Test case for issue 3961.
|
||||
*/
|
||||
package main
|
||||
|
||||
|
4
src/cmd/gofmt/testdata/emptydecl.golden
vendored
4
src/cmd/gofmt/testdata/emptydecl.golden
vendored
@ -1,3 +1,7 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test case for issue 7631.
|
||||
|
||||
package main
|
||||
|
||||
// Keep this declaration
|
||||
|
4
src/cmd/gofmt/testdata/emptydecl.input
vendored
4
src/cmd/gofmt/testdata/emptydecl.input
vendored
@ -1,3 +1,7 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test case for issue 7631.
|
||||
|
||||
package main
|
||||
|
||||
// Keep this declaration
|
||||
|
2
src/cmd/gofmt/testdata/ranges.golden
vendored
2
src/cmd/gofmt/testdata/ranges.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for range simplification.
|
||||
package p
|
||||
|
||||
|
2
src/cmd/gofmt/testdata/ranges.input
vendored
2
src/cmd/gofmt/testdata/ranges.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for range simplification.
|
||||
package p
|
||||
|
||||
|
2
src/cmd/gofmt/testdata/rewrite1.golden
vendored
2
src/cmd/gofmt/testdata/rewrite1.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=Foo->Bar
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite1.input
vendored
2
src/cmd/gofmt/testdata/rewrite1.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=Foo->Bar
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite2.golden
vendored
2
src/cmd/gofmt/testdata/rewrite2.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=int->bool
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite2.input
vendored
2
src/cmd/gofmt/testdata/rewrite2.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=int->bool
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite3.golden
vendored
2
src/cmd/gofmt/testdata/rewrite3.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=x->x
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite3.input
vendored
2
src/cmd/gofmt/testdata/rewrite3.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=x->x
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite4.golden
vendored
2
src/cmd/gofmt/testdata/rewrite4.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=(x)->x
|
||||
|
||||
// Copyright 2012 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite4.input
vendored
2
src/cmd/gofmt/testdata/rewrite4.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=(x)->x
|
||||
|
||||
// Copyright 2012 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite5.golden
vendored
2
src/cmd/gofmt/testdata/rewrite5.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=x+x->2*x
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite5.input
vendored
2
src/cmd/gofmt/testdata/rewrite5.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=x+x->2*x
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite6.golden
vendored
2
src/cmd/gofmt/testdata/rewrite6.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=fun(x)->Fun(x)
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite6.input
vendored
2
src/cmd/gofmt/testdata/rewrite6.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=fun(x)->Fun(x)
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite7.golden
vendored
2
src/cmd/gofmt/testdata/rewrite7.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=fun(x...)->Fun(x)
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite7.input
vendored
2
src/cmd/gofmt/testdata/rewrite7.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=fun(x...)->Fun(x)
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite8.golden
vendored
2
src/cmd/gofmt/testdata/rewrite8.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=interface{}->int
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/rewrite8.input
vendored
2
src/cmd/gofmt/testdata/rewrite8.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -r=interface{}->int
|
||||
|
||||
// Copyright 2013 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.
|
||||
|
2
src/cmd/gofmt/testdata/slices1.golden
vendored
2
src/cmd/gofmt/testdata/slices1.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for slice expression simplification.
|
||||
package p
|
||||
|
||||
|
2
src/cmd/gofmt/testdata/slices1.input
vendored
2
src/cmd/gofmt/testdata/slices1.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for slice expression simplification.
|
||||
package p
|
||||
|
||||
|
2
src/cmd/gofmt/testdata/slices2.golden
vendored
2
src/cmd/gofmt/testdata/slices2.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for slice expression simplification.
|
||||
// Because of a dot import, these slices must remain untouched.
|
||||
package p
|
||||
|
2
src/cmd/gofmt/testdata/slices2.input
vendored
2
src/cmd/gofmt/testdata/slices2.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -s
|
||||
|
||||
// Test cases for slice expression simplification.
|
||||
// Because of a dot import, these slices must remain untouched.
|
||||
package p
|
||||
|
2
src/cmd/gofmt/testdata/stdin1.golden
vendored
2
src/cmd/gofmt/testdata/stdin1.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -stdin
|
||||
|
||||
if x {
|
||||
y
|
||||
}
|
||||
|
2
src/cmd/gofmt/testdata/stdin1.input
vendored
2
src/cmd/gofmt/testdata/stdin1.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -stdin
|
||||
|
||||
if x {
|
||||
y
|
||||
}
|
||||
|
2
src/cmd/gofmt/testdata/stdin2.golden
vendored
2
src/cmd/gofmt/testdata/stdin2.golden
vendored
@ -1,4 +1,4 @@
|
||||
|
||||
//gofmt -stdin
|
||||
|
||||
var x int
|
||||
|
||||
|
2
src/cmd/gofmt/testdata/stdin2.input
vendored
2
src/cmd/gofmt/testdata/stdin2.input
vendored
@ -1,4 +1,4 @@
|
||||
|
||||
//gofmt -stdin
|
||||
|
||||
var x int
|
||||
|
||||
|
1
src/cmd/gofmt/testdata/stdin3.golden
vendored
1
src/cmd/gofmt/testdata/stdin3.golden
vendored
@ -1,3 +1,4 @@
|
||||
//gofmt -stdin
|
||||
|
||||
/* note: no newline at end of file */
|
||||
for i := 0; i < 10; i++ {
|
||||
|
1
src/cmd/gofmt/testdata/stdin3.input
vendored
1
src/cmd/gofmt/testdata/stdin3.input
vendored
@ -1,3 +1,4 @@
|
||||
//gofmt -stdin
|
||||
|
||||
/* note: no newline at end of file */
|
||||
for i := 0; i < 10; i++ { s += i }
|
||||
|
2
src/cmd/gofmt/testdata/stdin4.golden
vendored
2
src/cmd/gofmt/testdata/stdin4.golden
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -stdin
|
||||
|
||||
// comment
|
||||
|
||||
i := 0
|
||||
|
2
src/cmd/gofmt/testdata/stdin4.input
vendored
2
src/cmd/gofmt/testdata/stdin4.input
vendored
@ -1,3 +1,5 @@
|
||||
//gofmt -stdin
|
||||
|
||||
// comment
|
||||
|
||||
i := 0
|
||||
|
Loading…
Reference in New Issue
Block a user