blob: 616f1955f7cd58faa4e4d1696165ab46b9d7a968 [file] [log] [blame]
package pathregex
import (
"runtime"
"strings"
"testing"
)
type testCase struct {
// path expression.
path string
// expected regular expression afer parsing.
expected string
// expected reversed regular expression.
reversed string
}
type errorCase struct {
// path expression.
path string
// expected error position.
pos int64
}
var (
testCases = []testCase{
testCase{"a", "^a$", "^a$"},
testCase{"*", "^.*$", "^.*$"},
testCase{"?", "^.$", "^.$"},
testCase{".", "^\\.$", "^\\.$"},
testCase{"[a]", "^[a]$", "^[a]$"},
testCase{"[]]", "^[]]$", "^[]]$"},
testCase{"[a-z]", "^[a-z]$", "^[a-z]$"},
testCase{"[^a-z]", "^[^a-z]$", "^[^a-z]$"},
testCase{
"DSC[0-9][0-9][0-9][0-9].jpg",
"^DSC[0-9][0-9][0-9][0-9]\\.jpg$",
"^DSC[0-9][0-9][0-9][0-9]\\.jpg$",
},
testCase{"abc/def", "^abc$/^def$", "^def$/^abc$"},
testCase{"abc{foo,bar}def", "^abc(foo|bar)def$", "^abc(foo|bar)def$"},
testCase{"{abc,def}", "(^abc$|^def$)", "(^abc$|^def$)"},
testCase{
"abc/{bbb,ccc,ddd}/def",
"^abc$/(^bbb$|(^ccc$|^ddd$))/^def$",
"^def$/(^bbb$|(^ccc$|^ddd$))/^abc$",
},
testCase{
".../abc/def/...",
"(<true>)*/^abc$/^def$/(<true>)*",
"(<true>)*/^def$/^abc$/(<true>)*",
},
testCase{
"abc/{bbb,ccc}/ddd,eee",
"^abc$/(^bbb$|^ccc$)/^ddd,eee$",
"^ddd,eee$/(^bbb$|^ccc$)/^abc$",
},
testCase{
"aaa/bbb{ccc,ddd}eee,fff/ggg",
"^aaa$/^bbb(ccc|ddd)eee,fff$/^ggg$",
"^ggg$/^bbb(ccc|ddd)eee,fff$/^aaa$",
},
testCase{
"aaa/{bbb/ccc,ddd{eee,fff}ggg,ggg/{hhh,iii}/jjj}/kkk",
"^aaa$/(^bbb$/^ccc$|(^ddd(eee|fff)ggg$|^ggg$/(^hhh$|^iii$)/^jjj$))/^kkk$",
"^kkk$/(^ccc$/^bbb$|(^ddd(eee|fff)ggg$|^jjj$/(^hhh$|^iii$)/^ggg$))/^aaa$",
},
}
errorCases = []errorCase{
errorCase{"[", 1},
errorCase{"[]", 2},
errorCase{"{", 1},
errorCase{"{,", 2},
errorCase{"aaa{bbb/ccc}ddd", 8},
errorCase{"aaa/bbb/ccc}", 11},
}
)
func parsePath(t *testing.T, c *testCase) {
p := &parser{reader: strings.NewReader(c.path)}
re := p.parsePath()
pos, _ := p.reader.Seek(0, 1)
if p.isErrored || p.reader.Len() != 0 {
_, file, line, _ := runtime.Caller(1)
t.Fatalf("%s(%d): syntax error at char %d: %q", file, line, pos, c.path)
}
s := re.String()
if s != c.expected {
t.Errorf("Expected %q, got %q", c.expected, s)
}
re.reverse()
s = re.String()
if s != c.reversed {
t.Errorf("Expected %q, got %q", c.reversed, s)
}
}
func parsePathError(t *testing.T, e *errorCase) {
_, file, line, _ := runtime.Caller(1)
p := &parser{reader: strings.NewReader(e.path)}
p.parsePath()
if p.reader.Len() != 0 {
p.setError()
}
if !p.isErrored {
t.Errorf("%s(%d): expected error: %q", file, line, e.path)
}
if pos, _ := p.reader.Seek(0, 1); pos != e.pos {
t.Errorf("%s(%d): %q: expected error at pos %d, got %d", file, line, e.path, e.pos, pos)
}
}
func TestParser(t *testing.T) {
for _, c := range testCases {
parsePath(t, &c)
}
}
func TestParserErrors(t *testing.T) {
for _, e := range errorCases {
parsePathError(t, &e)
}
}