Skip to content

Commit

Permalink
Clearer match/natch errors
Browse files Browse the repository at this point in the history
This patch updates the error messages for match/natch expressions
to include the regex and source line in a much friendlier format.
  • Loading branch information
akutz committed Feb 27, 2022
1 parent 7694a69 commit 63110e1
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 52 deletions.
142 changes: 104 additions & 38 deletions internal/internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -253,8 +256,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -269,9 +275,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
regexp.MustCompile("(?s)world"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?s)world"),
Source: "world",
},
},
},
},
Expand All @@ -285,9 +297,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
regexp.MustCompile("(?s)world"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?s)world"),
Source: "world",
},
},
},
},
Expand All @@ -303,9 +321,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?m)hello"),
regexp.MustCompile("(?m)world"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?m)world"),
Source: "world",
},
},
},
},
Expand All @@ -319,8 +343,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?m)hello"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -336,8 +363,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?m)hello"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -351,8 +381,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Matches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
Matches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -367,8 +400,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -382,8 +418,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -398,9 +437,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
regexp.MustCompile("(?s)world"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?s)world"),
Source: "world",
},
},
},
},
Expand All @@ -414,9 +459,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?s)hello"),
regexp.MustCompile("(?s)world"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?s)world"),
Source: "world",
},
},
},
},
Expand All @@ -432,9 +483,15 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?m)hello"),
regexp.MustCompile("(?m)world"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
{
Regexp: regexp.MustCompile("(?m)world"),
Source: "world",
},
},
},
},
Expand All @@ -448,8 +505,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?m)hello"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -465,8 +525,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?m)hi"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?m)hello"),
Source: "hello",
},
},
},
},
Expand All @@ -480,8 +543,11 @@ func TestTreeInsert(t *testing.T) {
{
ID: "a",
Name: "1",
Natches: []*regexp.Regexp{
regexp.MustCompile("(?s)hi"),
Natches: []internal.LineMatcher{
{
Regexp: regexp.MustCompile("(?s)hello"),
Source: "hello",
},
},
},
},
Expand Down
62 changes: 54 additions & 8 deletions internal/testcase.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,40 @@ import (
"fmt"
"go/parser"
"go/token"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
)

// LineMatcher is a regular expression used to patch an expected expression
// from build optimization output for a line in a Go source file.
type LineMatcher struct {
// Regexp is matched against the build optimization output.
Regexp *regexp.Regexp

// Source is the line of source code for which this matcher was built.
Source string
}

func (lm LineMatcher) deepEqual(b LineMatcher) bool {
if lm.Source != b.Source {
return false
}
ar, br := lm.Regexp, b.Regexp
if ar == nil && br != nil {
return false
}
if ar != nil && br == nil {
return false
}
if ar != nil && br != nil && ar.String() != br.String() {
return false
}
return true
}

// TestCase is a test case parsed from the lem comments in a source file.
type TestCase struct {
// ID maps to lem.<ID>.
Expand All @@ -45,11 +73,11 @@ type TestCase struct {

// Matches maps to lem.<ID>.m= and is a list of patterns that must appear
// in the optimization output.
Matches []*regexp.Regexp
Matches []LineMatcher

// Natches maps to lem.<ID>.m!= and is a list of patterns that must appear
// in the optimization output.
Natches []*regexp.Regexp
Natches []LineMatcher
}

func (tc TestCase) deepEqual(b TestCase) bool {
Expand All @@ -69,17 +97,15 @@ func (tc TestCase) deepEqual(b TestCase) bool {
return false
}
for i := range tc.Matches {
am, bm := tc.Matches[i], b.Matches[i]
if am.String() != bm.String() {
if !tc.Matches[i].deepEqual(b.Matches[i]) {
return false
}
}
if len(tc.Natches) != len(b.Natches) {
return false
}
for i := range tc.Natches {
am, bm := tc.Natches[i], b.Natches[i]
if am.String() != bm.String() {
if !tc.Natches[i].deepEqual(b.Natches[i]) {
return false
}
}
Expand Down Expand Up @@ -114,6 +140,7 @@ var (
bytesRx = regexp.MustCompile(`^// lem\.([^.]+)\.bytes=(\d+)(?:-(\d+))?$`)
matchRx = regexp.MustCompile(`^// lem\.([^.]+)\.m=(.+)$`)
natchRx = regexp.MustCompile(`^// lem\.([^.]+)\.m!=(.+)$`)
newlnRx = regexp.MustCompile(`\r?\n`)
)

// GetTestCases parses the provided Go source files & returns a TestCase slice.
Expand Down Expand Up @@ -154,6 +181,14 @@ func (t testCaseLookupTable) Get(id string) (*TestCase, error) {
return tc, nil
}

func readLines(filePath string) ([]string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
return newlnRx.Split(string(data), -1), nil
}

func getTestCasesInFile(
filePath string,
lookupTbl testCaseLookupTable) ([]TestCase, error) {
Expand All @@ -173,6 +208,11 @@ func getTestCasesInFile(
return nil, err
}

lines, err := readLines(filePath)
if err != nil {
return nil, err
}

// Scan each line of the file for lem comments.
for _, cg := range f.Comments {
for _, c := range cg.List {
Expand Down Expand Up @@ -247,7 +287,10 @@ func getTestCasesInFile(
if err != nil {
return nil, err
}
tc.Matches = append(tc.Matches, r)
tc.Matches = append(tc.Matches, LineMatcher{
Regexp: r,
Source: lines[lineNo],
})
} else if m := natchRx.FindStringSubmatch(l); m != nil {
if tc, _ = lookupTbl.Get(m[1]); tc == nil {
testCases = append(testCases, TestCase{ID: m[1]})
Expand All @@ -261,7 +304,10 @@ func getTestCasesInFile(
if err != nil {
return nil, err
}
tc.Natches = append(tc.Natches, r)
tc.Natches = append(tc.Natches, LineMatcher{
Regexp: r,
Source: lines[lineNo],
})
}
}
}
Expand Down
Loading

0 comments on commit 63110e1

Please sign in to comment.