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, "'�' EOF true", result, "result") rn, err = r.runeAt(20) result = fmt.Sprintf("%q %s %t", rn, err, err == io.EOF) AssertEqual(t, "'�' 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, " �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)", }) }