peachy-go/csexp/match/match_test.go

96 lines
2.8 KiB
Go
Raw Normal View History

2024-10-30 21:22:55 +00:00
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)
})
}