peachy-go/csexp/sexp_test.go

99 lines
2.5 KiB
Go

package csexp_test
import (
"bytes"
"testing"
"git.codemonkeysoftware.net/b/peachy-go/csexp"
"git.codemonkeysoftware.net/b/peachy-go/csexp/gen"
"github.com/shoenig/test/must"
"pgregory.net/rapid"
)
func TestWriteToAndStringEquivalent(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
sexp := gen.Sexp().Draw(t, "sexp")
stringed := sexp.String()
var buf bytes.Buffer
n, err := sexp.WriteTo(&buf)
must.NoError(t, err)
written := buf.String()
must.EqOp(t, written, stringed)
must.EqOp(t, int64(len(stringed)), n)
})
}
func TestStringAndParseEqual(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
sexp := gen.Sexp().Draw(t, "sexp")
str := sexp.String()
parsed, err := csexp.Parse([]byte(str))
must.NoError(t, err)
must.Equal(t, sexp, parsed)
})
}
func TestCloneEqual(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
sexp := gen.Sexp().Draw(t, "sexp")
cloned := sexp.Clone()
must.Equal(t, sexp, cloned)
})
}
func MustNotBeEqual(t rapid.TB, s1, s2 csexp.Sexp) {
e1 := s1.Equal(s2)
e2 := s2.Equal(s1)
if e1 == !e2 {
t.Logf("expected Sexp.Equal to be commutative, but got different results")
}
if e1 || e2 {
t.Fatalf("expected sexps not to be equal\ns1: %q\ns2: %q", string(s1.String()), string(s2.String()))
}
}
func TestNotEqual(t *testing.T) {
t.Run("append to atom", rapid.MakeCheck(func(t *rapid.T) {
a1 := gen.Atom().Draw(t, "a1")
a2 := a1.Clone().(csexp.Atom)
a2 = append(a2, 'x')
MustNotBeEqual(t, a1, a2)
}))
t.Run("change atom byte", rapid.MakeCheck(func(t *rapid.T) {
nonEmpty := func(a csexp.Atom) bool { return len(a) >= 1 }
a1 := gen.Atom().Filter(nonEmpty).Draw(t, "a1")
a2 := a1.Clone().(csexp.Atom)
a2[0] = a2[0] + 1
MustNotBeEqual(t, a1, a2)
}))
t.Run("append to list", rapid.MakeCheck(func(t *rapid.T) {
l1 := gen.List().Draw(t, "l1")
extraElement := gen.Sexp().Draw(t, "extraElement")
l2 := l1.Clone().(csexp.List)
l2 = append(l2, extraElement)
MustNotBeEqual(t, l1, l2)
}))
t.Run("change list element", rapid.MakeCheck(func(t *rapid.T) {
nonEmpty := func(l csexp.List) bool { return len(l) >= 1 }
l1 := gen.List().Filter(nonEmpty).Draw(t, "l1")
isDifferent := func(s csexp.Sexp) bool { return !s.Equal(l1[0]) }
newElement := gen.Sexp().Filter(isDifferent).Draw(t, "newElement")
l2 := l1.Clone().(csexp.List)
l2[0] = newElement
MustNotBeEqual(t, l1, l2)
}))
t.Run("list and atom", rapid.MakeCheck(func(t *rapid.T) {
atom := gen.Atom().Draw(t, "atom")
list := gen.List().Draw(t, "list")
MustNotBeEqual(t, atom, list)
}))
}