go-parsekit/reader/reader_test.go

132 lines
3.5 KiB
Go
Raw Blame History

package reader_test
import (
"fmt"
"io"
"strings"
"testing"
"git.makaay.nl/mauricem/go-parsekit/reader"
"github.com/stretchr/testify/assert"
)
func ExampleNew() {
r := reader.New(strings.NewReader("Hello, world!"))
at := func(i int) rune { r, _ := r.RuneAt(i); return r }
fmt.Printf("%c", at(0))
fmt.Printf("%c", at(12))
// Output:
// H!
}
func TestReader_RuneAt(t *testing.T) {
r := reader.New(strings.NewReader("Hello, world!"))
at := func(i int) rune { r, _ := r.RuneAt(i); return r }
// It is possible to go back and forth while reading the input.
result := fmt.Sprintf("%c%c%c%c", at(0), at(12), at(7), at(0))
assert.Equal(t, "H!wH", result)
}
func TestReader_RuneAt_endOfFile(t *testing.T) {
r := reader.New(strings.NewReader("Hello, world!"))
rn, err := r.RuneAt(13)
result := fmt.Sprintf("%q %s %t", rn, err, err == io.EOF)
assert.Equal(t, "'<27>' EOF true", result)
rn, err = r.RuneAt(20)
result = fmt.Sprintf("%q %s %t", rn, err, err == io.EOF)
assert.Equal(t, "'<27>' EOF true", result)
}
func TestReader_RuneAt_invalidRune(t *testing.T) {
r := reader.New(strings.NewReader("Hello, \xcdworld!"))
at := func(i int) rune { r, _ := r.RuneAt(i); return r }
result := fmt.Sprintf("%c%c%c%c", at(6), at(7), at(8), at(9))
assert.Equal(t, " <20>wo", result, "result")
}
func ExampleReader_RuneAt() {
reader := reader.New(strings.NewReader("Hello, world!"))
fmt.Printf("Runes: ")
for i := 0; ; i++ {
r, err := reader.RuneAt(i)
if err != nil {
fmt.Printf("\nErr: %s\n", err)
break
}
fmt.Printf("%c", r)
}
// Output:
// Runes: Hello, world!
// Err: EOF
}
func TestRuneAt_SkipsBOMAtStartOfFile(t *testing.T) {
r := reader.New(strings.NewReader("\uFEFFBommetje!"))
b, _ := r.RuneAt(0)
o, _ := r.RuneAt(1)
m, _ := r.RuneAt(2)
bom := fmt.Sprintf("%c%c%c", b, o, m)
assert.Equal(t, "Bom", bom, "first three runes")
}
func TestReader_Flush(t *testing.T) {
r := reader.New(strings.NewReader("Hello, world!"))
at := func(i int) rune { r, _ := r.RuneAt(i); return r }
// Fills the buffer with the first 8 runes on the input: "Hello, w"
result := fmt.Sprintf("%c", at(7))
assert.Equal(t, "w", result, "first read")
// Now flush the first 4 runes from the buffer (dropping "Hell" from it)
r.Flush(4)
// Rune 0 is now pointing at what originally was rune offset 4.
// We can continue reading from there.
result = fmt.Sprintf("%c%c%c%c%c%c", at(0), at(1), at(2), at(3), at(4), at(5))
assert.Equal(t, "o, wor", result)
}
func ExampleReader_Flush() {
r := reader.New(strings.NewReader("dog eat dog!"))
at := func(offset int) rune { c, _ := r.RuneAt(offset); return c }
// Read from the first 4 runes of the input.
fmt.Printf("%c%c%c%c", at(0), at(1), at(2), at(3))
// Flush those 4 runes, bringing offset 0 to the start of "eat dog".
r.Flush(4)
// Read another 4 runes, because of the flushing, we start at offset 0.
fmt.Printf("%c%c%c%c", at(1), at(2), at(0), at(3))
// Again, flush 4 runes, bringing offset 0 to the start of "dog!".
r.Flush(4)
// Read from the remainder runes.
fmt.Printf("%c%c%c%c%c", at(2), at(1), at(1), at(0), at(3))
// Output:
// dog ate good!
}
func TestGivenNumberOfRunesTooHigh_Flush_Panics(t *testing.T) {
r := reader.New(strings.NewReader("Hello, world!"))
// Fill buffer with "Hello, worl", the first 11 runes.
r.RuneAt(10)
// However, we flush 12 runes, which exceeds the buffer size.
assert.PanicsWithValue(t,
"parsekit.Input.Reader.Flush(): number of runes to flush "+
"(12) exceeds size of the buffer (11)",
func() { r.Flush(12) })
}