blob: b71c79124d4725f54911b2ff9c3b2397dba26041 [file] [log] [blame]
// Copyright 2009 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 printer
import (
"bytes";
"flag";
"io";
"go/ast";
"go/parser";
"path";
"testing";
)
const (
dataDir = "testdata";
tabwidth = 4;
)
var update = flag.Bool("update", false, "update golden files");
func lineString(text []byte, i int) string {
i0 := i;
for i < len(text) && text[i] != '\n' {
i++;
}
return string(text[i0 : i]);
}
func check(t *testing.T, source, golden string, exports bool) {
// parse source
prog, err := parser.ParseFile(source, nil, parser.ParseComments);
if err != nil {
t.Error(err);
return;
}
// filter exports if necessary
if exports {
ast.FileExports(prog); // ignore result
prog.Comments = nil; // don't print comments that are not in AST
}
// format source
var buf bytes.Buffer;
if _, err := Fprint(&buf, prog, 0, tabwidth); err != nil {
t.Error(err);
}
res := buf.Bytes();
// update golden files if necessary
if *update {
if err := io.WriteFile(golden, res, 0644); err != nil {
t.Error(err);
}
return;
}
// get golden
gld, err := io.ReadFile(golden);
if err != nil {
t.Error(err);
return;
}
// compare lengths
if len(res) != len(gld) {
t.Errorf("len = %d, expected %d (= len(%s))", len(res), len(gld), golden);
}
// compare contents
for i, line, offs := 0, 1, 0; i < len(res) && i < len(gld); i++ {
ch := res[i];
if ch != gld[i] {
t.Errorf("%s:%d:%d: %s", source, line, i-offs+1, lineString(res, offs));
t.Errorf("%s:%d:%d: %s", golden, line, i-offs+1, lineString(gld, offs));
t.Error();
return;
}
if ch == '\n' {
line++;
offs = i+1;
}
}
}
type entry struct {
source, golden string;
exports bool;
}
// Use gotest -update to create/update the respective golden files.
var data = []entry{
entry{ "comments.go", "comments.golden", false },
entry{ "comments.go", "comments.x", true },
entry{ "linebreaks.go", "linebreaks.golden", false },
entry{ "expressions.go", "expressions.golden", false },
entry{ "declarations.go", "declarations.golden", false },
}
func Test(t *testing.T) {
for _, e := range data {
source := path.Join(dataDir, e.source);
golden := path.Join(dataDir, e.golden);
check(t, source, golden, e.exports);
// TODO(gri) check that golden is idempotent
//check(t, golden, golden, e.exports);
}
}