From e409950492340d0e74db681de25f4a2a0dc84b37 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 12 Jul 2024 14:30:15 +0200 Subject: main: refactor error messages to use FileCheck-like patterns Match the error messages in testdata/errors/*.go like LLVM FileCheck, which includes regular expressions. I believe this is much more flexible, and LLVM uses it in nearly all of their tests so it must work quite well for compilers. --- errors_test.go | 40 +++++++++++++++++++++++++++--------- testdata/errors/loader-invaliddep.go | 2 +- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/errors_test.go b/errors_test.go index 1ee9a0e18..49d7b2573 100644 --- a/errors_test.go +++ b/errors_test.go @@ -5,7 +5,7 @@ import ( "fmt" "os" "path/filepath" - "runtime" + "regexp" "strings" "testing" "time" @@ -62,20 +62,40 @@ func testErrorMessages(t *testing.T, filename string) { actual := strings.TrimRight(buf.String(), "\n") // Check whether the error is as expected. - if canonicalizeErrors(actual) != canonicalizeErrors(expected) { + if !matchErrors(t, expected, actual) { t.Errorf("expected error:\n%s\ngot:\n%s", indentText(expected, "> "), indentText(actual, "> ")) } } -func canonicalizeErrors(text string) string { - // Fix for Windows: replace all backslashes with forward slashes so that - // paths will be the same as on POSIX systems. - // (It may also change some other backslashes, but since this is only for - // comparing text it should be fine). - if runtime.GOOS == "windows" { - text = strings.ReplaceAll(text, "\\", "/") +func matchErrors(t *testing.T, pattern, actual string) bool { + patternLines := strings.Split(pattern, "\n") + actualLines := strings.Split(actual, "\n") + if len(patternLines) != len(actualLines) { + return false } - return text + for i, patternLine := range patternLines { + indices := regexp.MustCompile(`\{\{.*?\}\}`).FindAllStringIndex(patternLine, -1) + patternParts := []string{"^"} + lastStop := 0 + for _, startstop := range indices { + start := startstop[0] + stop := startstop[1] + patternParts = append(patternParts, + regexp.QuoteMeta(patternLine[lastStop:start]), + patternLine[start+2:stop-2]) + lastStop = stop + } + patternParts = append(patternParts, regexp.QuoteMeta(patternLine[lastStop:]), "$") + pattern := strings.Join(patternParts, "") + re, err := regexp.Compile(pattern) + if err != nil { + t.Fatalf("could not compile regexp for %#v: %v", patternLine, err) + } + if !re.MatchString(actualLines[i]) { + return false + } + } + return true } // Indent the given text with a given indentation string. diff --git a/testdata/errors/loader-invaliddep.go b/testdata/errors/loader-invaliddep.go index db935d38a..05c2f2d5b 100644 --- a/testdata/errors/loader-invaliddep.go +++ b/testdata/errors/loader-invaliddep.go @@ -5,4 +5,4 @@ import _ "github.com/tinygo-org/tinygo/testdata/errors/invaliddep" func main() { } -// ERROR: invaliddep/invaliddep.go:1:1: expected 'package', found ppackage +// ERROR: invaliddep{{[\\/]}}invaliddep.go:1:1: expected 'package', found ppackage -- cgit v1.2.3