package parsekit import ( "fmt" "io" "strings" "testing" "git.makaay.nl/mauricem/go-parsekit/assert" ) 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 ExampleReader_RuneAt() { 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. fmt.Printf("%c", at(0)) fmt.Printf("%c", at(12)) fmt.Printf("%c", at(7)) fmt.Printf("%c", at(0)) // Output: // H!wH } func ExampleReader_RuneAt_endOfFile() { in := strings.NewReader("Hello, world!") r := NewReader(in) rn, err := r.RuneAt(13) fmt.Printf("%q %s %t\n", rn, err, err == io.EOF) rn, err = r.RuneAt(20) fmt.Printf("%q %s %t\n", rn, err, err == io.EOF) // Output: // '�' EOF true // '�' EOF true } func ExampleReader_RuneAt_invalidRune() { in := strings.NewReader("Hello, \xcdworld!") r := NewReader(in) rn, err := r.RuneAt(6) fmt.Printf("%q %t\n", rn, err == nil) rn, err = r.RuneAt(7) fmt.Printf("%q %t\n", rn, err == nil) rn, err = r.RuneAt(8) fmt.Printf("%q %t\n", rn, err == nil) rn, err = r.RuneAt(9) fmt.Printf("%q %t\n", rn, err == nil) // Output: // ' ' true // '�' true // 'w' true // 'o' true } func ExampleReader_RunesAt() { in := strings.NewReader("Hello, \xcdworld!") r := NewReader(in) rs, err := r.RunesAt(4, 6) fmt.Printf("%q %t\n", string(rs), err == nil) rs, err = r.RunesAt(4, 0) fmt.Printf("%q %t\n", string(rs), err == nil) rs, err = r.RunesAt(8, 100) fmt.Printf("%q %t\n", string(rs), err == io.EOF) // Output: // "o, �wo" true // "" true // "world!" true } 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) assert.Equal(t, "Bom", bom, "first three runes") } func ExampleReader_Flush() { in := strings.NewReader("Hello, world!") r := NewReader(in) at := func(i int) rune { r, _ := r.RuneAt(i); return r } rb := func(start int, len int) []rune { r, _ := r.RunesAt(start, len); return r } // Fills the buffer with the first 8 runes on the input: "Hello, w" fmt.Printf("%c\n", at(7)) // 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. fmt.Printf("%s", string(rb(0, 8))) // Output: // w // o, world } 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. assert.Panic(t, assert.PanicT{ Function: func() { r.Flush(12) }, Expect: "parsekit.Input.Reader.Flush(): number of runes to flush (12) exceeds size of the buffer (11)", }) }