Fix RuneReader breaking right before EOF

This commit is contained in:
Brandon Dyck 2024-09-17 20:48:38 -06:00
parent edff0f8ca0
commit 5e9566be33
2 changed files with 39 additions and 4 deletions

View File

@ -35,10 +35,14 @@ func (rr *RuneReader) ReadRune() (r rune, size int, err error) {
rr.cursor = next rr.cursor = next
return 0, 0, fmt.Errorf("ReadRune: %w", err) return 0, 0, fmt.Errorf("ReadRune: %w", err)
} }
if n == 0 {
return 0, 0, io.EOF
}
s = s[:n] s = s[:n]
fmt.Println("read bytes:", s)
r, size = utf8.DecodeRune(s) r, size = utf8.DecodeRune(s)
rr.cursor = rr.cursor.At(rr.cursor.Pos() + uint64(size)) 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] { func (rr *RuneReader) Cursor() cursor.Cursor[byte] {

View File

@ -1,6 +1,15 @@
package bytes_test 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) { func Todo(t *testing.T) {
t.Fatalf("TODO") t.Fatalf("TODO")
@ -10,9 +19,31 @@ func TestRegexp(t *testing.T) {
t.Run("only searches the beginning of input", Todo) t.Run("only searches the beginning of input", Todo)
t.Run("position is correct after match", Todo) t.Run("position is correct after match", Todo)
t.Run("fails on unexpected error", 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) { 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)
}
}
} }