gigaparsec/parser_test.go

110 lines
2.7 KiB
Go
Raw Normal View History

2024-09-09 16:27:54 +00:00
package gigaparsec_test
import (
"bytes"
2024-09-13 16:38:47 +00:00
"errors"
2024-09-09 16:27:54 +00:00
"testing"
"git.codemonkeysoftware.net/b/gigaparsec"
"git.codemonkeysoftware.net/b/gigaparsec/cursor"
2024-09-13 16:38:47 +00:00
ptest "git.codemonkeysoftware.net/b/gigaparsec/test"
2024-09-09 16:27:54 +00:00
"github.com/shoenig/test"
"github.com/shoenig/test/must"
2024-09-09 16:27:54 +00:00
"pgregory.net/rapid"
)
func Todo(t *testing.T) {
t.Errorf("TODO")
}
2024-09-09 21:18:27 +00:00
func not[T any](pred func(T) bool) func(T) bool {
2024-09-09 16:27:54 +00:00
return func(x T) bool { return !pred(x) }
}
2024-09-10 15:30:54 +00:00
func hasPrefix(prefix []byte) func([]byte) bool {
return func(b []byte) bool { return bytes.HasPrefix(b, prefix) }
}
2024-09-09 16:27:54 +00:00
func TestSlice(t *testing.T) {
assertParseFails := func(t rapid.TB, input []byte, p gigaparsec.Parser[byte, []byte]) {
2024-09-09 21:13:37 +00:00
t.Helper()
start := gigaparsec.MakeState(cursor.NewSlice(input))
result, err := p(start)
must.NoError(t, err)
failed, consumed, _ := result.Failed()
test.True(t, failed)
test.False(t, consumed)
2024-09-09 21:13:37 +00:00
if t.Failed() {
t.FailNow()
}
}
2024-09-09 16:27:54 +00:00
t.Run("fails with wrong contents", rapid.MakeCheck(func(t *rapid.T) {
s := rapid.SliceOfN(rapid.Byte(), 1, -1).Draw(t, "s")
input := rapid.SliceOfN(rapid.Byte(), len(s), -1).
2024-09-10 15:30:54 +00:00
Filter(not(hasPrefix(s))).Draw(t, "input")
2024-09-09 21:13:37 +00:00
assertParseFails(t, input, gigaparsec.Slice(s))
2024-09-09 16:27:54 +00:00
}))
t.Run("fails at end of input", rapid.MakeCheck(func(t *rapid.T) {
s := rapid.SliceOfN(rapid.Byte(), 1, -1).Draw(t, "s")
inputLen := rapid.IntRange(0, len(s)-1).Draw(t, "inputLen")
input := s[:inputLen]
2024-09-09 21:13:37 +00:00
assertParseFails(t, input, gigaparsec.Slice(s))
2024-09-09 16:27:54 +00:00
}))
2024-09-13 16:38:47 +00:00
t.Run("fails when read fails", rapid.MakeCheck(func(t *rapid.T) {
expectedErr := rapid.Map(rapid.StringN(0, 100, -1), errors.New).Draw(t, "err")
2024-09-13 17:02:13 +00:00
c := ptest.ErrCursor[byte](expectedErr)
2024-09-13 16:38:47 +00:00
s := rapid.SliceOfN(rapid.Byte(), 0, 100).Draw(t, "s")
2024-09-13 16:44:30 +00:00
result, err := gigaparsec.Slice(s)(gigaparsec.MakeState(c))
failed, _, _ := result.Failed()
2024-09-13 16:38:47 +00:00
test.ErrorIs(t, err, expectedErr)
2024-09-13 16:44:30 +00:00
test.True(t, failed)
2024-09-13 16:38:47 +00:00
}))
2024-09-09 16:27:54 +00:00
t.Run("succeeds when contents match", rapid.MakeCheck(func(t *rapid.T) {
input := rapid.SliceOfN(rapid.Byte(), 1, -1).Draw(t, "input")
sLen := rapid.IntRange(0, len(input)).Draw(t, "sLen")
s := input[:sLen]
start := gigaparsec.MakeState(cursor.NewSlice(input))
result, err := gigaparsec.Slice(s)(start)
must.NoError(t, err)
succeeded, consumed, value, next, _ := result.Succeeded()
test.True(t, succeeded)
test.True(t, consumed)
test.SliceEqOp(t, s, value)
test.EqOp(t, uint64(len(s)), next.Pos())
2024-09-09 16:27:54 +00:00
}))
}
2024-09-10 22:46:31 +00:00
func TestChoose(t *testing.T) {
Todo(t)
}
2024-09-10 22:58:34 +00:00
func TestBind(t *testing.T) {
Todo(t)
}
func TestReturn(t *testing.T) {
Todo(t)
}
func TestMap(t *testing.T) {
Todo(t)
}
func TestSatisfy(t *testing.T) {
Todo(t)
}
func Try(t *testing.T) {
Todo(t)
}
func TestLabel(t *testing.T) {
Todo(t)
}
2024-09-11 01:00:44 +00:00
func TestEnd(t *testing.T) {
Todo(t)
}