95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
package parsekit
|
||
|
||
import (
|
||
"fmt"
|
||
"io"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
func ExamplenewReader() {
|
||
in := strings.NewReader("Hello, world!")
|
||
r := newReader(in)
|
||
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) {
|
||
in := strings.NewReader("Hello, world!")
|
||
r := newReader(in)
|
||
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))
|
||
AssertEqual(t, "H!wH", result, "result")
|
||
}
|
||
|
||
func TestReader_runeAt_endOfFile(t *testing.T) {
|
||
in := strings.NewReader("Hello, world!")
|
||
r := newReader(in)
|
||
|
||
rn, err := r.runeAt(13)
|
||
result := fmt.Sprintf("%q %s %t", rn, err, err == io.EOF)
|
||
AssertEqual(t, "'<27>' EOF true", result, "result")
|
||
|
||
rn, err = r.runeAt(20)
|
||
result = fmt.Sprintf("%q %s %t", rn, err, err == io.EOF)
|
||
AssertEqual(t, "'<27>' EOF true", result, "result")
|
||
}
|
||
|
||
func TestReader_runeAt_invalidRune(t *testing.T) {
|
||
in := strings.NewReader("Hello, \xcdworld!")
|
||
r := newReader(in)
|
||
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))
|
||
AssertEqual(t, " <20>wo", result, "result")
|
||
}
|
||
|
||
func TestRuneAt_SkipsBOMAtStartOfFile(t *testing.T) {
|
||
in := strings.NewReader("\uFEFFBommetje!")
|
||
r := newReader(in)
|
||
b, _ := r.runeAt(0)
|
||
o, _ := r.runeAt(1)
|
||
m, _ := r.runeAt(2)
|
||
bom := fmt.Sprintf("%c%c%c", b, o, m)
|
||
AssertEqual(t, "Bom", bom, "first three runes")
|
||
}
|
||
|
||
func TestReader_Flush(t *testing.T) {
|
||
in := strings.NewReader("Hello, world!")
|
||
r := newReader(in)
|
||
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))
|
||
AssertEqual(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))
|
||
AssertEqual(t, "o, wor", result, "second read")
|
||
}
|
||
|
||
func TestGivenNumberOfRunesTooHigh_Flush_Panics(t *testing.T) {
|
||
in := strings.NewReader("Hello, world!")
|
||
r := newReader(in)
|
||
|
||
// Fill buffer with "Hello, worl", the first 11 runes.
|
||
r.runeAt(10)
|
||
|
||
// However, we flush 12 runes, which exceeds the buffer size.
|
||
AssertPanic(t, PanicT{
|
||
Function: func() { r.flush(12) },
|
||
Expect: "parsekit.Input.Reader.Flush(): number of runes to flush (12) exceeds size of the buffer (11)",
|
||
})
|
||
}
|