diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-05-03 14:07:19 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-05-05 14:01:52 +0200 |
| commit | c07ad91c6bf086ecf058af733995f8e6a185e967 (patch) | |
| tree | cbb72e95e63a207199aa7262f963276e250d68ba /pkg/ast | |
| parent | 577e2c45a7bcaf974ef661442dc4cd52339e8953 (diff) | |
pkg/ast: improve test output
Improve the test utility to group error messages by line.
Diffstat (limited to 'pkg/ast')
| -rw-r--r-- | pkg/ast/scanner.go | 22 | ||||
| -rw-r--r-- | pkg/ast/test_util.go | 52 |
2 files changed, 62 insertions, 12 deletions
diff --git a/pkg/ast/scanner.go b/pkg/ast/scanner.go index 3a6ba9d98..5607e3082 100644 --- a/pkg/ast/scanner.go +++ b/pkg/ast/scanner.go @@ -124,10 +124,32 @@ func LoggingHandler(pos Pos, msg string) { fmt.Fprintf(os.Stderr, "%v: %v\n", pos, msg) } +const BuiltinFile = "BUILTINS" + +func (pos Pos) Builtin() bool { + return pos.File == BuiltinFile +} + func (pos Pos) String() string { + if pos.Builtin() { + return "builtins" + } + if pos.Col == 0 { + return fmt.Sprintf("%v:%v", pos.File, pos.Line) + } return fmt.Sprintf("%v:%v:%v", pos.File, pos.Line, pos.Col) } +func (pos Pos) less(other Pos) bool { + if pos.File != other.File { + return pos.File < other.File + } + if pos.Line != other.Line { + return pos.Line < other.Line + } + return pos.Col < other.Col +} + func (s *scanner) Scan() (tok token, lit string, pos Pos) { s.skipWhitespace() pos = s.pos() diff --git a/pkg/ast/test_util.go b/pkg/ast/test_util.go index 741bed553..697b34505 100644 --- a/pkg/ast/test_util.go +++ b/pkg/ast/test_util.go @@ -6,9 +6,11 @@ package ast import ( "bufio" "bytes" + "fmt" "io/ioutil" "path/filepath" "regexp" + "sort" "strings" "testing" ) @@ -21,9 +23,7 @@ type ErrorMatcher struct { } type errorDesc struct { - file string - line int - col int + pos Pos text string matched bool } @@ -44,8 +44,7 @@ func NewErrorMatcher(t *testing.T, file string) *ErrorMatcher { break } errors = append(errors, &errorDesc{ - file: filepath.Base(file), - line: i, + pos: Pos{File: filepath.Base(file), Line: i}, text: strings.TrimSpace(string(ln[pos+3:])), }) ln = ln[:pos] @@ -70,9 +69,7 @@ func (em *ErrorMatcher) ErrorHandler(pos Pos, msg string) { msg = msg[0:match[0]] + "at LOCATION" + msg[match[1]:] } em.got = append(em.got, &errorDesc{ - file: pos.File, - line: pos.Line, - col: pos.Col, + pos: pos, text: msg, }) } @@ -82,27 +79,58 @@ func (em *ErrorMatcher) Count() int { } func (em *ErrorMatcher) Check() { + em.t.Helper() + errors := make(map[Pos][]string) nextErr: for _, e := range em.got { for _, want := range em.expect { - if want.matched || want.line != e.line || want.text != e.text { + if want.matched || want.pos.Line != e.pos.Line || want.text != e.text { continue } want.matched = true continue nextErr } - em.t.Errorf("unexpected error:\n%v:%v:%v: %v", e.file, e.line, e.col, e.text) + pos := e.pos + pos.Col = 0 + pos.Off = 0 + errors[pos] = append(errors[pos], fmt.Sprintf("unexpected: %v", e.text)) } for _, want := range em.expect { if want.matched { continue } - em.t.Errorf("unmatched error:\n%v:%v: %v", want.file, want.line, want.text) + errors[want.pos] = append(errors[want.pos], fmt.Sprintf("unmatched : %v", want.text)) } + + if len(errors) == 0 { + return + } + type Sorted struct { + pos Pos + msgs []string + } + sorted := []Sorted{} + for pos, msgs := range errors { + sorted = append(sorted, Sorted{pos, msgs}) + } + sort.Slice(sorted, func(i, j int) bool { + return sorted[i].pos.less(sorted[j].pos) + }) + buf := new(bytes.Buffer) + for _, err := range sorted { + if len(err.msgs) == 1 { + fmt.Fprintf(buf, "%v: %v\n", err.pos, err.msgs[0]) + continue + } + sort.Strings(err.msgs) + fmt.Fprintf(buf, "%v:\n\t%v\n", err.pos, strings.Join(err.msgs, "\n\t")) + } + em.t.Errorf("\n%s", buf.Bytes()) } func (em *ErrorMatcher) DumpErrors() { + em.t.Helper() for _, e := range em.got { - em.t.Logf("%v:%v:%v: %v", e.file, e.line, e.col, e.text) + em.t.Logf("%v: %v", e.pos, e.text) } } |
