1 // Copyright 2009 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.
24 var update = flag.Bool("update", false, "update golden files")
26 var fset = token.NewFileSet()
28 func lineString(text []byte, i int) string {
30 for i < len(text) && text[i] != '\n' {
33 return string(text[i0:i])
39 export checkMode = 1 << iota
43 func runcheck(t *testing.T, source, golden string, mode checkMode) {
45 prog, err := parser.ParseFile(fset, source, nil, parser.ParseComments)
51 // filter exports if necessary
53 ast.FileExports(prog) // ignore result
54 prog.Comments = nil // don't print comments that are not in AST
57 // determine printer configuration
58 cfg := Config{Tabwidth: tabwidth}
59 if mode&rawFormat != 0 {
65 if err := cfg.Fprint(&buf, fset, prog); err != nil {
70 // update golden files if necessary
72 if err := ioutil.WriteFile(golden, res, 0644); err != nil {
79 gld, err := ioutil.ReadFile(golden)
86 if len(res) != len(gld) {
87 t.Errorf("len = %d, expected %d (= len(%s))", len(res), len(gld), golden)
91 for i, line, offs := 0, 1, 0; i < len(res) && i < len(gld); i++ {
94 t.Errorf("%s:%d:%d: %s", source, line, i-offs+1, lineString(res, offs))
95 t.Errorf("%s:%d:%d: %s", golden, line, i-offs+1, lineString(gld, offs))
106 func check(t *testing.T, source, golden string, mode checkMode) {
107 // start a timer to produce a time-out signal
110 time.Sleep(10 * time.Second) // plenty of a safety margin, even for very slow machines
117 runcheck(t, source, golden, mode)
121 // wait for the first finisher
124 // test running past time out
125 t.Errorf("%s: running too slowly", source)
127 // test finished within alloted time margin
132 source, golden string
136 // Use gotest -update to create/update the respective golden files.
138 {"empty.input", "empty.golden", 0},
139 {"comments.input", "comments.golden", 0},
140 {"comments.input", "comments.x", export},
141 {"linebreaks.input", "linebreaks.golden", 0},
142 {"expressions.input", "expressions.golden", 0},
143 {"expressions.input", "expressions.raw", rawFormat},
144 {"declarations.input", "declarations.golden", 0},
145 {"statements.input", "statements.golden", 0},
146 {"slow.input", "slow.golden", 0},
149 func TestFiles(t *testing.T) {
150 for i, e := range data {
151 source := filepath.Join(dataDir, e.source)
152 golden := filepath.Join(dataDir, e.golden)
153 check(t, source, golden, e.mode)
154 // TODO(gri) check that golden is idempotent
155 //check(t, golden, golden, e.mode)
156 if testing.Short() && i >= 3 {
162 // TestLineComments, using a simple test case, checks that consequtive line
163 // comments are properly terminated with a newline even if the AST position
164 // information is incorrect.
166 func TestLineComments(t *testing.T) {
167 const src = `// comment 1
173 fset := token.NewFileSet()
174 ast1, err1 := parser.ParseFile(fset, "", src, parser.ParseComments)
180 fset = token.NewFileSet() // use the wrong file set
181 Fprint(&buf, fset, ast1)
184 for _, ch := range buf.Bytes() {
191 if nlines < expected {
192 t.Errorf("got %d, expected %d\n", nlines, expected)
196 // Verify that the printer can be invoked during initialization.
198 const name = "foobar"
200 if err := Fprint(&buf, fset, &ast.Ident{Name: name}); err != nil {
203 if s := buf.String(); s != name {
204 panic("got " + s + ", want " + name)