96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
|
package match_test
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"git.codemonkeysoftware.net/b/peachy-go/csexp"
|
||
|
"git.codemonkeysoftware.net/b/peachy-go/csexp/match"
|
||
|
"github.com/shoenig/test"
|
||
|
"github.com/shoenig/test/must"
|
||
|
)
|
||
|
|
||
|
func TestMatchLiteral(t *testing.T) {
|
||
|
t.Run("same", func(t *testing.T) {
|
||
|
atom := csexp.Atom("hello")
|
||
|
err := match.MustCompile(atom.String()).Match(atom)
|
||
|
must.NoError(t, err)
|
||
|
})
|
||
|
t.Run("different", func(t *testing.T) {
|
||
|
atom := csexp.Atom("hello")
|
||
|
pattern := csexp.Atom("goodbye").String()
|
||
|
|
||
|
err := match.MustCompile(pattern).Match(atom)
|
||
|
|
||
|
var mismatch match.MismatchError
|
||
|
must.ErrorAs(t, err, &mismatch)
|
||
|
test.Equal(t, mismatch.Got, csexp.Sexp(atom))
|
||
|
test.StrContains(t, mismatch.Expected, pattern)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestMatchList(t *testing.T) {
|
||
|
t.Run("both empty", func(t *testing.T) {
|
||
|
err := match.MustCompile("()").Match(csexp.List(nil))
|
||
|
must.NoError(t, err)
|
||
|
})
|
||
|
t.Run("same length", func(t *testing.T) {
|
||
|
list := csexp.List{csexp.Atom("a"), csexp.Atom("b"), csexp.Atom("c")}
|
||
|
err := match.MustCompile(list.String()).Match(list)
|
||
|
must.NoError(t, err)
|
||
|
})
|
||
|
t.Run("sexp too long", func(t *testing.T) {
|
||
|
list := csexp.List{csexp.Atom("a"), csexp.Atom("b"), csexp.Atom("c")}
|
||
|
pattern := list[0:2].String()
|
||
|
|
||
|
err := match.MustCompile(pattern).Match(list)
|
||
|
|
||
|
var mismatch match.MismatchError
|
||
|
must.ErrorAs(t, err, &mismatch)
|
||
|
test.Equal(t, mismatch.Got, csexp.Sexp(list))
|
||
|
test.StrContains(t, mismatch.Expected, "list of 2 items")
|
||
|
})
|
||
|
t.Run("sexp too short", func(t *testing.T) {
|
||
|
list := csexp.List{csexp.Atom("a"), csexp.Atom("b"), csexp.Atom("c")}
|
||
|
shortList := list[0:2]
|
||
|
|
||
|
err := match.MustCompile(list.String()).Match(shortList)
|
||
|
|
||
|
var mismatch match.MismatchError
|
||
|
must.ErrorAs(t, err, &mismatch)
|
||
|
test.Equal(t, mismatch.Got, csexp.Sexp(shortList))
|
||
|
test.StrContains(t, mismatch.Expected, "list of 3 items")
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func TestExtract(t *testing.T) {
|
||
|
matcher := match.MustCompile("(3:abc%s(%s3:jkl)%s3:pqr%s)")
|
||
|
sexp, err := csexp.Parse([]byte("(3:abc3:def(3:ghi3:jkl)3:mno3:pqr3:stu)"))
|
||
|
must.NoError(t, err)
|
||
|
t.Run("correct number of operands", func(t *testing.T) {
|
||
|
var def, ghi, mno, stu string
|
||
|
err := matcher.Match(sexp, &def, &ghi, &mno, &stu)
|
||
|
must.NoError(t, err)
|
||
|
test.EqOp(t, "def", def)
|
||
|
test.EqOp(t, "ghi", ghi)
|
||
|
test.EqOp(t, "mno", mno)
|
||
|
test.EqOp(t, "stu", stu)
|
||
|
})
|
||
|
t.Run("too many operands", func(t *testing.T) {
|
||
|
var def, ghi, mno, stu, extra string
|
||
|
err := matcher.Match(sexp, &def, &ghi, &mno, &stu, &extra)
|
||
|
must.ErrorContains(t, err, "too many operands")
|
||
|
test.EqOp(t, "def", def)
|
||
|
test.EqOp(t, "ghi", ghi)
|
||
|
test.EqOp(t, "mno", mno)
|
||
|
test.EqOp(t, "stu", stu)
|
||
|
})
|
||
|
t.Run("too few operands", func(t *testing.T) {
|
||
|
var def, ghi, mno string
|
||
|
err := matcher.Match(sexp, &def, &ghi, &mno)
|
||
|
must.ErrorContains(t, err, "too few operands")
|
||
|
test.EqOp(t, "def", def)
|
||
|
test.EqOp(t, "ghi", ghi)
|
||
|
test.EqOp(t, "mno", mno)
|
||
|
})
|
||
|
}
|