diff --git a/TODO.txt b/TODO.txt index d85353d..aad8838 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,2 +1,4 @@ +Result should be Failed by default Test RuneReader Test Regexp +Add SPDX tags diff --git a/parser_test.go b/parser_test.go index 4ee5681..9f8464c 100644 --- a/parser_test.go +++ b/parser_test.go @@ -2,10 +2,12 @@ package gigaparsec_test import ( "bytes" + "errors" "testing" "git.codemonkeysoftware.net/b/gigaparsec" "git.codemonkeysoftware.net/b/gigaparsec/cursor" + ptest "git.codemonkeysoftware.net/b/gigaparsec/test" "github.com/shoenig/test" "github.com/shoenig/test/must" "pgregory.net/rapid" @@ -49,7 +51,14 @@ func TestSlice(t *testing.T) { input := s[:inputLen] assertParseFails(t, input, gigaparsec.Slice(s)) })) - t.Run("fails when read fails", Todo) + 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") + r := ptest.ErrReaderAt(expectedErr) + c := cursor.NewReaderAt(r) + s := rapid.SliceOfN(rapid.Byte(), 0, 100).Draw(t, "s") + _, err := gigaparsec.Slice(s)(gigaparsec.MakeState(c)) + test.ErrorIs(t, err, expectedErr) + })) 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") diff --git a/test/readerat.go b/test/readerat.go new file mode 100644 index 0000000..c4a0029 --- /dev/null +++ b/test/readerat.go @@ -0,0 +1,17 @@ +// Package test contains helpers for testing parsers. +package test + +import "io" + +type errReaderAt struct { + err error +} + +func (r errReaderAt) ReadAt([]byte, int64) (int, error) { + return 0, r.err +} + +// ErrReaderAt returns an [io.ReaderAt] with a ReadAt method that always returns err. +func ErrReaderAt(err error) io.ReaderAt { + return errReaderAt{err: err} +}