diff --git a/bytes/regexp.go b/bytes/regexp.go index a4b9498..89767e3 100644 --- a/bytes/regexp.go +++ b/bytes/regexp.go @@ -35,10 +35,14 @@ func (rr *RuneReader) ReadRune() (r rune, size int, err error) { rr.cursor = next return 0, 0, fmt.Errorf("ReadRune: %w", err) } + if n == 0 { + return 0, 0, io.EOF + } s = s[:n] + fmt.Println("read bytes:", s) r, size = utf8.DecodeRune(s) rr.cursor = rr.cursor.At(rr.cursor.Pos() + uint64(size)) - return r, size, err + return r, size, nil } func (rr *RuneReader) Cursor() cursor.Cursor[byte] { diff --git a/bytes/regexp_test.go b/bytes/regexp_test.go index 377a31d..3f96828 100644 --- a/bytes/regexp_test.go +++ b/bytes/regexp_test.go @@ -1,6 +1,15 @@ package bytes_test -import "testing" +import ( + "testing" + + "git.codemonkeysoftware.net/b/gigaparsec" + "git.codemonkeysoftware.net/b/gigaparsec/bytes" + "git.codemonkeysoftware.net/b/gigaparsec/cursor" + "github.com/shoenig/test" + "github.com/shoenig/test/must" + "pgregory.net/rapid" +) func Todo(t *testing.T) { t.Fatalf("TODO") @@ -10,9 +19,31 @@ func TestRegexp(t *testing.T) { t.Run("only searches the beginning of input", Todo) t.Run("position is correct after match", Todo) t.Run("fails on unexpected error", Todo) - t.Run("returns a useful Got value", Todo) + t.Run("returns a useful Got value", rapid.MakeCheck(func(t *rapid.T) { + + })) + t.Run("basically works", func(t *testing.T) { + result, err := bytes.Regexp("a")(gigaparsec.MakeState(cursor.NewSlice([]byte("a")))) + must.NoError(t, err) + failed, _, msg := result.Failed() + must.False(t, failed, must.Sprint(msg)) + succeeded, consumed, value, _, _ := result.Succeeded() + test.True(t, succeeded) + test.True(t, consumed) + test.EqOp(t, "a", value) + }) } func TestRuneReader(t *testing.T) { - Todo(t) + var s = []byte("abcdefghijklmnopqrstuvwxyz") + rr := bytes.NewRuneReader(cursor.NewSlice(s)) + for i, b := range s { + r, n, err := rr.ReadRune() + test.NoError(t, err) + test.EqOp(t, 1, n) + test.EqOp(t, r, rune(b)) + if t.Failed() { + t.Fatalf("failed at %d", i) + } + } }