From 2934e7a20fa076f9b2f0ecc6bda589b7d7fdb74b Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Tue, 11 Feb 2025 19:12:40 -0500 Subject: [PATCH] Wrote tests for backreferences --- regex/re_test.go | 190 ++++++++++++++++++++++++++--------------------- 1 file changed, 105 insertions(+), 85 deletions(-) diff --git a/regex/re_test.go b/regex/re_test.go index 05230a1..c751c26 100644 --- a/regex/re_test.go +++ b/regex/re_test.go @@ -314,10 +314,6 @@ var reTests = []struct { {`\0009`, nil, "\x009", []Group{{0, 2}}}, {`\0141`, nil, "a", []Group{{0, 1}}}, - // At this point, the python test suite has a bunch - // of backreference tests. Since my engine doesn't - // implement backreferences, I've skipped those tests. - {`*a`, nil, ``, nil}, {`(*)b`, nil, ``, nil}, {`a**`, nil, ``, nil}, @@ -585,9 +581,29 @@ var groupTests = []struct { {`(.*)c(.*)`, nil, `abcde`, []Match{[]Group{{0, 5}, {0, 2}, {3, 5}}}}, {`\((.*), (.*)\)`, nil, `(a, b)`, []Match{[]Group{{0, 6}, {1, 2}, {4, 5}}}}, - // At this point, the python test suite has a bunch - // of backreference tests. Since my engine doesn't - // implement backreferences, I've skipped those tests. + // Backreference tests + {`(abc)\1`, nil, `abcabc`, []Match{[]Group{{0, 6}, {0, 3}}}}, + {`([a-c]+)\1`, nil, `abcabc`, []Match{[]Group{{0, 6}, {0, 3}}}}, + {`([a-c]*)\1`, nil, `abcabc`, []Match{[]Group{{0, 6}, {0, 3}}, []Group{{6, 6}, {6, 6}}}}, + {`^(.+)?B`, nil, `AB`, []Match{[]Group{{0, 2}, {0, 1}}}}, + {`(a+).\1$`, nil, `aaaaa`, []Match{[]Group{{0, 5}, {0, 2}}}}, + {`^(a+).\1$`, nil, `aaaa`, []Match{}}, + {`(a)\1`, nil, `aa`, []Match{[]Group{{0, 2}, {0, 1}}}}, + {`(a+)\1`, nil, `aa`, []Match{[]Group{{0, 2}, {0, 1}}}}, + {`(a+)+\1`, nil, `aa`, []Match{[]Group{{0, 2}, {0, 1}}}}, + {`(a).+\1`, nil, `aba`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`(a)ba*\1`, nil, `aba`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`(aa|a)a\1$`, nil, `aaa`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`(a|aa)a\1$`, nil, `aaa`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`(a+)a\1$`, nil, `aaa`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`([abc]*)\1`, nil, `abcabc`, []Match{[]Group{{0, 6}, {0, 3}}, []Group{{6, 6}, {6, 6}}}}, + {`(a)(?:b)\1`, nil, `aba`, []Match{[]Group{{0, 3}, {0, 1}}}}, + {`(a)(?:b)\1`, nil, `abb`, []Match{}}, + {`(?:a)(b)\1`, nil, `aba`, []Match{}}, + {`(?:a)(b)\1`, nil, `abb`, []Match{[]Group{{0, 3}, {1, 2}}}}, + {`(?:(cat)|(dog))\2`, nil, `catdog`, []Match{}}, + {`(?:a)\1`, nil, `aa`, nil}, + {`((cat)|(dog)|(cow)|(bat))\4`, nil, `cowcow`, []Match{[]Group{{0, 6}, {0, 3}, {-1, -1}, {-1, -1}, {0, 3}, {-1, -1}}}}, {`(a)(b)c|ab`, nil, `ab`, []Match{[]Group{{0, 2}}}}, {`(a)+x`, nil, `aaax`, []Match{[]Group{{0, 4}, {2, 3}}}}, @@ -792,23 +808,24 @@ func TestFindSubmatch(t *testing.T) { if test.result != nil { panic(err) } - } - match, err := regComp.FindSubmatch(test.str) - if err != nil { - if len(test.result) != 0 { - t.Errorf("Wanted %v got no match\n", test.result[0]) - } - } else if len(test.result) == 0 { - t.Errorf("Wanted no match got %v\n", match) - } - for i := range match { - if match[i].IsValid() { - if test.result[0][i] != match[i] { - t.Errorf("Wanted %v Got %v\n", test.result[0], match) + } else { + match, err := regComp.FindSubmatch(test.str) + if err != nil { + if len(test.result) != 0 { + t.Errorf("Wanted %v got no match\n", test.result[0]) } - } else { - if i < len(test.result) && test.result[0][i].IsValid() { - t.Errorf("Wanted %v Got %v\n", test.result[0], match) + } else if len(test.result) == 0 { + t.Errorf("Wanted no match got %v\n", match) + } + for i := range match { + if match[i].IsValid() { + if test.result[0][i] != match[i] { + t.Errorf("Wanted %v Got %v\n", test.result[0], match) + } + } else { + if i < len(test.result) && test.result[0][i].IsValid() { + t.Errorf("Wanted %v Got %v\n", test.result[0], match) + } } } } @@ -823,10 +840,22 @@ func TestFindStringSubmatch(t *testing.T) { if test.result != nil { panic(err) } - } - matchStr := regComp.FindStringSubmatch(test.str) - if matchStr == nil { - if len(test.result) != 0 { + } else { + matchStr := regComp.FindStringSubmatch(test.str) + if matchStr == nil { + if len(test.result) != 0 { + expectedStr := funcMap(test.result[0], func(g Group) string { + if g.IsValid() { + return test.str[g.StartIdx:g.EndIdx] + } else { + return "" + } + }) + t.Errorf("Wanted %v got no match\n", expectedStr) + } + } else if len(test.result) == 0 { + t.Errorf("Wanted no match got %v\n", matchStr) + } else { expectedStr := funcMap(test.result[0], func(g Group) string { if g.IsValid() { return test.str[g.StartIdx:g.EndIdx] @@ -834,26 +863,15 @@ func TestFindStringSubmatch(t *testing.T) { return "" } }) - t.Errorf("Wanted %v got no match\n", expectedStr) - } - } else if len(test.result) == 0 { - t.Errorf("Wanted no match got %v\n", matchStr) - } else { - expectedStr := funcMap(test.result[0], func(g Group) string { - if g.IsValid() { - return test.str[g.StartIdx:g.EndIdx] - } else { - return "" - } - }) - for i, groupStr := range matchStr { - if groupStr == "" { - if i < len(expectedStr) && expectedStr[i] != "" { - t.Errorf("Wanted %v Got %v\n", expectedStr, matchStr) - } - } else { - if expectedStr[i] != groupStr { - t.Errorf("Wanted %v Got %v\n", expectedStr, matchStr) + for i, groupStr := range matchStr { + if groupStr == "" { + if i < len(expectedStr) && expectedStr[i] != "" { + t.Errorf("Wanted %v Got %v\n", expectedStr, matchStr) + } + } else { + if expectedStr[i] != groupStr { + t.Errorf("Wanted %v Got %v\n", expectedStr, matchStr) + } } } } @@ -870,10 +888,24 @@ func TestFindAllStringSubmatch(t *testing.T) { if test.result != nil { panic(err) } - } - matchStrs := regComp.FindAllStringSubmatch(test.str) - if matchStrs == nil { - if len(test.result) != 0 { + } else { + matchStrs := regComp.FindAllStringSubmatch(test.str) + if matchStrs == nil { + if len(test.result) != 0 { + expectedStrs := funcMap(test.result, func(m Match) []string { + return funcMap(m, func(g Group) string { + if g.IsValid() { + return test.str[g.StartIdx:g.EndIdx] + } else { + return "" + } + }) + }) + t.Errorf("Wanted %v got no match\n", expectedStrs) + } + } else if len(test.result) == 0 { + t.Errorf("Wanted no match got %v\n", matchStrs) + } else { expectedStrs := funcMap(test.result, func(m Match) []string { return funcMap(m, func(g Group) string { if g.IsValid() { @@ -883,29 +915,16 @@ func TestFindAllStringSubmatch(t *testing.T) { } }) }) - t.Errorf("Wanted %v got no match\n", expectedStrs) - } - } else if len(test.result) == 0 { - t.Errorf("Wanted no match got %v\n", matchStrs) - } else { - expectedStrs := funcMap(test.result, func(m Match) []string { - return funcMap(m, func(g Group) string { - if g.IsValid() { - return test.str[g.StartIdx:g.EndIdx] - } else { - return "" - } - }) - }) - for i, matchStr := range matchStrs { - for j, groupStr := range matchStr { - if groupStr == "" { - if j < len(expectedStrs[i]) && expectedStrs[i][j] != "" { - t.Errorf("Wanted %v Got %v\n", expectedStrs, matchStrs) - } - } else { - if expectedStrs[i][j] != groupStr { - t.Errorf("Wanted %v Got %v\n", expectedStrs, matchStrs) + for i, matchStr := range matchStrs { + for j, groupStr := range matchStr { + if groupStr == "" { + if j < len(expectedStrs[i]) && expectedStrs[i][j] != "" { + t.Errorf("Wanted %v Got %v\n", expectedStrs, matchStrs) + } + } else { + if expectedStrs[i][j] != groupStr { + t.Errorf("Wanted %v Got %v\n", expectedStrs, matchStrs) + } } } } @@ -923,17 +942,18 @@ func TestFindAllSubmatch(t *testing.T) { if test.result != nil { panic(err) } - } - matchIndices := regComp.FindAllSubmatch(test.str) - for i := range matchIndices { - for j := range matchIndices[i] { - if matchIndices[i][j].IsValid() { - if test.result[i][j] != matchIndices[i][j] { - t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) - } - } else { - if i < len(test.result) && j < len(test.result[i]) && test.result[i][j].IsValid() { - t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) + } else { + matchIndices := regComp.FindAllSubmatch(test.str) + for i := range matchIndices { + for j := range matchIndices[i] { + if matchIndices[i][j].IsValid() { + if test.result[i][j] != matchIndices[i][j] { + t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) + } + } else { + if i < len(test.result) && j < len(test.result[i]) && test.result[i][j].IsValid() { + t.Errorf("Wanted %v Got %v\n", test.result, matchIndices) + } } } }