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) }) }