// SPDX-License-Identifier: Unlicense package bytes_test import ( "bytes" "strings" "testing" "git.codemonkeysoftware.net/b/gigaparsec" pbytes "git.codemonkeysoftware.net/b/gigaparsec/bytes" "git.codemonkeysoftware.net/b/gigaparsec/cursor" ptest "git.codemonkeysoftware.net/b/gigaparsec/test" pgen "git.codemonkeysoftware.net/b/gigaparsec/test/generator" "github.com/shoenig/test" "github.com/shoenig/test/must" "pgregory.net/rapid" ) func Todo(t *testing.T) { t.Fatalf("TODO") } 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", rapid.MakeCheck(func(t *rapid.T) { })) t.Run("basically works", func(t *testing.T) { result, err := pbytes.Regexp("a")(gigaparsec.MakeState(cursor.NewReaderAt(strings.NewReader("a")))) must.NoError(t, err) success, value, _ := result.Status() test.True(t, success, test.Sprint(result.Message())) test.EqOp(t, "a", value) test.True(t, result.Consumed()) }) } func TestRuneReader(t *testing.T) { var s = "abcdefghijklmnopqrstuvwxyz" rr := pbytes.NewRuneReader(cursor.NewReaderAt(strings.NewReader(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) } } } func TestMatchString(t *testing.T) { t.Run("fails on unexpected error", rapid.MakeCheck(func(t *rapid.T) { s := rapid.StringN(-1, -1, 100).Draw(t, "s") readErr := pgen.Error().Draw(t, "readErr") result, err := pbytes.MatchString(s)(gigaparsec.MakeState(cursor.NewReaderAt(ptest.ErrReaderAt(readErr)))) test.ErrorIs(t, err, readErr) success, _, _ := result.Status() test.False(t, success) test.False(t, result.Consumed()) })) t.Run("does not succeed or consume on mismatch", rapid.MakeCheck(func(t *rapid.T) { bgen := rapid.SliceOfN(rapid.Byte(), 1, 100) input := bgen.Draw(t, "input") notPrefix := func(b []byte) bool { return !bytes.HasPrefix(input, b) } s := string(bgen.Filter(notPrefix).Draw(t, "s")) result, err := pbytes.MatchString(s)(gigaparsec.MakeState(cursor.NewReaderAt(bytes.NewReader(input)))) test.NoError(t, err) success, _, _ := result.Status() test.False(t, success) test.False(t, result.Consumed()) })) t.Run("succeeds with correct value, consumption, and position", rapid.MakeCheck(func(t *rapid.T) { input := rapid.SliceOfN(rapid.Byte(), 1, 100).Draw(t, "input") slen := rapid.IntRange(0, len(input)).Draw(t, "slen") s := string(input[:slen]) result, err := pbytes.MatchString(s)(gigaparsec.MakeState(cursor.NewReaderAt(bytes.NewReader(input)))) must.NoError(t, err) success, value, next := result.Status() must.True(t, success) test.True(t, result.Consumed()) test.EqOp(t, s, value) ptest.StateIsAt(t, next, uint64(slen)) })) }