Added Repeat tests

This commit is contained in:
2024-10-16 11:58:12 -06:00
parent bfc9a9ae58
commit 9c5e8fff0e
2 changed files with 48 additions and 2 deletions

View File

@ -4,6 +4,8 @@ package gigaparsec_test
import (
"bytes"
"errors"
"io"
"testing"
"git.codemonkeysoftware.net/b/gigaparsec"
@ -156,7 +158,51 @@ func TestRepeat(t *testing.T) {
}
}))
t.Run("consumes iff at least one application consumes", rapid.MakeCheck(func(t *rapid.T) {
type Token struct {
Consume, Succeed bool
}
// p will succeed and consume based on the values in the parsed token.
var p gigaparsec.Parser[Token, Token] = func(s gigaparsec.State[Token]) (gigaparsec.Result[Token, Token], error) {
buf := make([]Token, 1)
_, next, err := s.Read(buf)
if errors.Is(err, io.EOF) {
return gigaparsec.Fail[Token, Token](false, gigaparsec.MessageEnd(s.Pos())), nil
}
if err != nil {
return gigaparsec.Result[Token, Token]{}, err
}
tok := buf[0]
if tok.Succeed {
return gigaparsec.Succeed(tok.Consume, tok, next, gigaparsec.MessageOK(s.Pos())), nil
} else {
return gigaparsec.Fail[Token, Token](tok.Consume, gigaparsec.MakeMessage(s.Pos(), "false", "true")), nil
}
}
input := rapid.Map(rapid.SliceOfN(rapid.Just(Token{Succeed: true}), 0, 100),
func(ts []Token) []Token { return append(ts, Token{}) }).Draw(t, "input")
consumeAt := rapid.Ptr(rapid.IntRange(0, len(input)-1), true).Draw(t, "consumeAt")
if consumeAt != nil {
input[*consumeAt].Consume = true
}
shouldConsume := consumeAt != nil
result, err := gigaparsec.Repeat(0, p)(gigaparsec.MakeState(gigaparsec.SliceReaderAt[Token](input)))
must.NoError(t, err)
test.EqOp(t, shouldConsume, result.Consumed())
}))
t.Run("fails on error", Todo)
t.Run("does not consume on empty input", func(t *testing.T) {
p := gigaparsec.Repeat(0, gigaparsec.Match(0))
result, err := p(gigaparsec.MakeState(gigaparsec.SliceReaderAt[int](nil)))
must.NoError(t, err)
must.False(t, result.Consumed())
})
t.Run("fails on error", func(t *testing.T) {
expectedErr := errors.New("it broke")
p := gigaparsec.Repeat(0, gigaparsec.Match(byte(0)))
result, err := p(gigaparsec.MakeState(ptest.ErrReaderAt(expectedErr)))
succeeded, _, _ := result.Status()
test.ErrorIs(t, err, expectedErr)
test.False(t, succeeded)
})
}