LEFT | RIGHT |
| 1 // Copyright 2009 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. |
| 4 |
| 5 package bufio_test |
| 6 |
| 7 import ( |
| 8 . "bufio" |
| 9 "bytes" |
| 10 "errors" |
| 11 "fmt" |
| 12 "io" |
| 13 "io/ioutil" |
| 14 "strings" |
| 15 "testing" |
| 16 "testing/iotest" |
| 17 "time" |
| 18 "unicode/utf8" |
| 19 ) |
| 20 |
| 21 // Reads from a reader and rot13s the result. |
| 22 type rot13Reader struct { |
| 23 r io.Reader |
| 24 } |
| 25 |
| 26 func newRot13Reader(r io.Reader) *rot13Reader { |
| 27 r13 := new(rot13Reader) |
| 28 r13.r = r |
| 29 return r13 |
| 30 } |
| 31 |
| 32 func (r13 *rot13Reader) Read(p []byte) (int, error) { |
| 33 n, err := r13.r.Read(p) |
| 34 if err != nil { |
| 35 return n, err |
| 36 } |
| 37 for i := 0; i < n; i++ { |
| 38 c := p[i] | 0x20 // lowercase byte |
| 39 if 'a' <= c && c <= 'm' { |
| 40 p[i] += 13 |
| 41 } else if 'n' <= c && c <= 'z' { |
| 42 p[i] -= 13 |
| 43 } |
| 44 } |
| 45 return n, nil |
| 46 } |
| 47 |
| 48 // Call ReadByte to accumulate the text of a file |
| 49 func readBytes(buf *Reader) string { |
| 50 var b [1000]byte |
| 51 nb := 0 |
| 52 for { |
| 53 c, err := buf.ReadByte() |
| 54 if err == io.EOF { |
| 55 break |
| 56 } |
| 57 if err == nil { |
| 58 b[nb] = c |
| 59 nb++ |
| 60 } else if err != iotest.ErrTimeout { |
| 61 panic("Data: " + err.Error()) |
| 62 } |
| 63 } |
| 64 return string(b[0:nb]) |
| 65 } |
| 66 |
| 67 func TestReaderSimple(t *testing.T) { |
| 68 data := "hello world" |
| 69 b := NewReader(strings.NewReader(data)) |
| 70 if s := readBytes(b); s != "hello world" { |
| 71 t.Errorf("simple hello world test failed: got %q", s) |
| 72 } |
| 73 |
| 74 b = NewReader(newRot13Reader(strings.NewReader(data))) |
| 75 if s := readBytes(b); s != "uryyb jbeyq" { |
| 76 t.Errorf("rot13 hello world test failed: got %q", s) |
| 77 } |
| 78 } |
| 79 |
| 80 type readMaker struct { |
| 81 name string |
| 82 fn func(io.Reader) io.Reader |
| 83 } |
| 84 |
| 85 var readMakers = []readMaker{ |
| 86 {"full", func(r io.Reader) io.Reader { return r }}, |
| 87 {"byte", iotest.OneByteReader}, |
| 88 {"half", iotest.HalfReader}, |
| 89 {"data+err", iotest.DataErrReader}, |
| 90 {"timeout", iotest.TimeoutReader}, |
| 91 } |
| 92 |
| 93 // Call ReadString (which ends up calling everything else) |
| 94 // to accumulate the text of a file. |
| 95 func readLines(b *Reader) string { |
| 96 s := "" |
| 97 for { |
| 98 s1, err := b.ReadString('\n') |
| 99 if err == io.EOF { |
| 100 break |
| 101 } |
| 102 if err != nil && err != iotest.ErrTimeout { |
| 103 panic("GetLines: " + err.Error()) |
| 104 } |
| 105 s += s1 |
| 106 } |
| 107 return s |
| 108 } |
| 109 |
| 110 // Call Read to accumulate the text of a file |
| 111 func reads(buf *Reader, m int) string { |
| 112 var b [1000]byte |
| 113 nb := 0 |
| 114 for { |
| 115 n, err := buf.Read(b[nb : nb+m]) |
| 116 nb += n |
| 117 if err == io.EOF { |
| 118 break |
| 119 } |
| 120 } |
| 121 return string(b[0:nb]) |
| 122 } |
| 123 |
| 124 type bufReader struct { |
| 125 name string |
| 126 fn func(*Reader) string |
| 127 } |
| 128 |
| 129 var bufreaders = []bufReader{ |
| 130 {"1", func(b *Reader) string { return reads(b, 1) }}, |
| 131 {"2", func(b *Reader) string { return reads(b, 2) }}, |
| 132 {"3", func(b *Reader) string { return reads(b, 3) }}, |
| 133 {"4", func(b *Reader) string { return reads(b, 4) }}, |
| 134 {"5", func(b *Reader) string { return reads(b, 5) }}, |
| 135 {"7", func(b *Reader) string { return reads(b, 7) }}, |
| 136 {"bytes", readBytes}, |
| 137 {"lines", readLines}, |
| 138 } |
| 139 |
| 140 const minReadBufferSize = 16 |
| 141 |
| 142 var bufsizes = []int{ |
| 143 0, minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096, |
| 144 } |
| 145 |
| 146 func TestReader(t *testing.T) { |
| 147 var texts [31]string |
| 148 str := "" |
| 149 all := "" |
| 150 for i := 0; i < len(texts)-1; i++ { |
| 151 texts[i] = str + "\n" |
| 152 all += texts[i] |
| 153 str += string(i%26 + 'a') |
| 154 } |
| 155 texts[len(texts)-1] = all |
| 156 |
| 157 for h := 0; h < len(texts); h++ { |
| 158 text := texts[h] |
| 159 for i := 0; i < len(readMakers); i++ { |
| 160 for j := 0; j < len(bufreaders); j++ { |
| 161 for k := 0; k < len(bufsizes); k++ { |
| 162 readmaker := readMakers[i] |
| 163 bufreader := bufreaders[j] |
| 164 bufsize := bufsizes[k] |
| 165 read := readmaker.fn(strings.NewReader(t
ext)) |
| 166 buf := NewReaderSize(read, bufsize) |
| 167 s := bufreader.fn(buf) |
| 168 if s != text { |
| 169 t.Errorf("reader=%s fn=%s bufsiz
e=%d want=%q got=%q", |
| 170 readmaker.name, bufreade
r.name, bufsize, text, s) |
| 171 } |
| 172 } |
| 173 } |
| 174 } |
| 175 } |
| 176 } |
| 177 |
| 178 type zeroReader struct{} |
| 179 |
| 180 func (zeroReader) Read(p []byte) (int, error) { |
| 181 return 0, nil |
| 182 } |
| 183 |
| 184 func TestZeroReader(t *testing.T) { |
| 185 var z zeroReader |
| 186 r := NewReader(z) |
| 187 |
| 188 c := make(chan error) |
| 189 go func() { |
| 190 _, err := r.ReadByte() |
| 191 c <- err |
| 192 }() |
| 193 |
| 194 select { |
| 195 case err := <-c: |
| 196 if err == nil { |
| 197 t.Error("error expected") |
| 198 } else if err != io.ErrNoProgress { |
| 199 t.Error("unexpected error:", err) |
| 200 } |
| 201 case <-time.After(time.Second): |
| 202 t.Error("test timed out (endless loop in ReadByte?)") |
| 203 } |
| 204 } |
| 205 |
| 206 // A StringReader delivers its data one string segment at a time via Read. |
| 207 type StringReader struct { |
| 208 data []string |
| 209 step int |
| 210 } |
| 211 |
| 212 func (r *StringReader) Read(p []byte) (n int, err error) { |
| 213 if r.step < len(r.data) { |
| 214 s := r.data[r.step] |
| 215 n = copy(p, s) |
| 216 r.step++ |
| 217 } else { |
| 218 err = io.EOF |
| 219 } |
| 220 return |
| 221 } |
| 222 |
| 223 func readRuneSegments(t *testing.T, segments []string) { |
| 224 got := "" |
| 225 want := strings.Join(segments, "") |
| 226 r := NewReader(&StringReader{data: segments}) |
| 227 for { |
| 228 r, _, err := r.ReadRune() |
| 229 if err != nil { |
| 230 if err != io.EOF { |
| 231 return |
| 232 } |
| 233 break |
| 234 } |
| 235 got += string(r) |
| 236 } |
| 237 if got != want { |
| 238 t.Errorf("segments=%v got=%s want=%s", segments, got, want) |
| 239 } |
| 240 } |
| 241 |
| 242 var segmentList = [][]string{ |
| 243 {}, |
| 244 {""}, |
| 245 {"日", "本語"}, |
| 246 {"\u65e5", "\u672c", "\u8a9e"}, |
| 247 {"\U000065e5", "\U0000672c", "\U00008a9e"}, |
| 248 {"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"}, |
| 249 {"Hello", ", ", "World", "!"}, |
| 250 {"Hello", ", ", "", "World", "!"}, |
| 251 } |
| 252 |
| 253 func TestReadRune(t *testing.T) { |
| 254 for _, s := range segmentList { |
| 255 readRuneSegments(t, s) |
| 256 } |
| 257 } |
| 258 |
| 259 func TestUnreadRune(t *testing.T) { |
| 260 segments := []string{"Hello, world:", "日本語"} |
| 261 r := NewReader(&StringReader{data: segments}) |
| 262 got := "" |
| 263 want := strings.Join(segments, "") |
| 264 // Normal execution. |
| 265 for { |
| 266 r1, _, err := r.ReadRune() |
| 267 if err != nil { |
| 268 if err != io.EOF { |
| 269 t.Error("unexpected error on ReadRune:", err) |
| 270 } |
| 271 break |
| 272 } |
| 273 got += string(r1) |
| 274 // Put it back and read it again. |
| 275 if err = r.UnreadRune(); err != nil { |
| 276 t.Fatal("unexpected error on UnreadRune:", err) |
| 277 } |
| 278 r2, _, err := r.ReadRune() |
| 279 if err != nil { |
| 280 t.Fatal("unexpected error reading after unreading:", err
) |
| 281 } |
| 282 if r1 != r2 { |
| 283 t.Fatalf("incorrect rune after unread: got %c, want %c",
r1, r2) |
| 284 } |
| 285 } |
| 286 if got != want { |
| 287 t.Errorf("got %q, want %q", got, want) |
| 288 } |
| 289 } |
| 290 |
| 291 func TestUnreadByte(t *testing.T) { |
| 292 segments := []string{"Hello, ", "world"} |
| 293 r := NewReader(&StringReader{data: segments}) |
| 294 got := "" |
| 295 want := strings.Join(segments, "") |
| 296 // Normal execution. |
| 297 for { |
| 298 b1, err := r.ReadByte() |
| 299 if err != nil { |
| 300 if err != io.EOF { |
| 301 t.Error("unexpected error on ReadByte:", err) |
| 302 } |
| 303 break |
| 304 } |
| 305 got += string(b1) |
| 306 // Put it back and read it again. |
| 307 if err = r.UnreadByte(); err != nil { |
| 308 t.Fatal("unexpected error on UnreadByte:", err) |
| 309 } |
| 310 b2, err := r.ReadByte() |
| 311 if err != nil { |
| 312 t.Fatal("unexpected error reading after unreading:", err
) |
| 313 } |
| 314 if b1 != b2 { |
| 315 t.Fatalf("incorrect byte after unread: got %q, want %q",
b1, b2) |
| 316 } |
| 317 } |
| 318 if got != want { |
| 319 t.Errorf("got %q, want %q", got, want) |
| 320 } |
| 321 } |
| 322 |
| 323 func TestUnreadByteMultiple(t *testing.T) { |
| 324 segments := []string{"Hello, ", "world"} |
| 325 data := strings.Join(segments, "") |
| 326 for n := 0; n <= len(data); n++ { |
| 327 r := NewReader(&StringReader{data: segments}) |
| 328 // Read n bytes. |
| 329 for i := 0; i < n; i++ { |
| 330 b, err := r.ReadByte() |
| 331 if err != nil { |
| 332 t.Fatalf("n = %d: unexpected error on ReadByte:
%v", n, err) |
| 333 } |
| 334 if b != data[i] { |
| 335 t.Fatalf("n = %d: incorrect byte returned from R
eadByte: got %q, want %q", n, b, data[i]) |
| 336 } |
| 337 } |
| 338 // Unread one byte if there is one. |
| 339 if n > 0 { |
| 340 if err := r.UnreadByte(); err != nil { |
| 341 t.Errorf("n = %d: unexpected error on UnreadByte
: %v", n, err) |
| 342 } |
| 343 } |
| 344 // Test that we cannot unread any further. |
| 345 if err := r.UnreadByte(); err == nil { |
| 346 t.Errorf("n = %d: expected error on UnreadByte", n) |
| 347 } |
| 348 } |
1 } | 349 } |
2 | 350 |
3 func TestUnreadByteOthers(t *testing.T) { | 351 func TestUnreadByteOthers(t *testing.T) { |
4 » // A list of readers to use in conjuction with UnreadByte. | 352 » // A list of readers to use in conjunction with UnreadByte. |
5 var readers = []func(*Reader, byte) ([]byte, error){ | 353 var readers = []func(*Reader, byte) ([]byte, error){ |
6 (*Reader).ReadBytes, | 354 (*Reader).ReadBytes, |
7 (*Reader).ReadSlice, | 355 (*Reader).ReadSlice, |
| 356 func(r *Reader, delim byte) ([]byte, error) { |
| 357 data, err := r.ReadString(delim) |
| 358 return []byte(data), err |
| 359 }, |
| 360 // ReadLine doesn't fit the data/pattern easily |
| 361 // so we leave it out. It should be covered via |
| 362 // the ReadSlice test since ReadLine simply calls |
| 363 // ReadSlice, and it's that function that handles |
| 364 // the last byte. |
| 365 } |
| 366 |
| 367 // Try all readers with UnreadByte. |
| 368 for rno, read := range readers { |
| 369 // Some input data that is longer than the minimum reader buffer
size. |
| 370 const n = 10 |
| 371 var buf bytes.Buffer |
| 372 for i := 0; i < n; i++ { |
| 373 buf.WriteString("abcdefg") |
| 374 } |
| 375 |
| 376 r := NewReaderSize(&buf, minReadBufferSize) |
| 377 readTo := func(delim byte, want string) { |
| 378 data, err := read(r, delim) |
| 379 if err != nil { |
| 380 t.Fatalf("#%d: unexpected error reading to %c: %
v", rno, delim, err) |
| 381 } |
| 382 if got := string(data); got != want { |
| 383 t.Fatalf("#%d: got %q, want %q", rno, got, want) |
| 384 } |
| 385 } |
| 386 |
| 387 // Read the data with occasional UnreadByte calls. |
| 388 for i := 0; i < n; i++ { |
| 389 readTo('d', "abcd") |
| 390 for j := 0; j < 3; j++ { |
| 391 if err := r.UnreadByte(); err != nil { |
| 392 t.Fatalf("#%d: unexpected error on Unrea
dByte: %v", rno, err) |
| 393 } |
| 394 readTo('d', "d") |
| 395 } |
| 396 readTo('g', "efg") |
| 397 } |
| 398 |
| 399 // All data should have been read. |
| 400 _, err := r.ReadByte() |
| 401 if err != io.EOF { |
| 402 t.Errorf("#%d: got error %v; want EOF", rno, err) |
| 403 } |
| 404 } |
| 405 } |
| 406 |
| 407 // Test that UnreadRune fails if the preceding operation was not a ReadRune. |
| 408 func TestUnreadRuneError(t *testing.T) { |
| 409 buf := make([]byte, 3) // All runes in this test are 3 bytes long |
| 410 r := NewReader(&StringReader{data: []string{"日本語日本語日本語"}}) |
| 411 if r.UnreadRune() == nil { |
| 412 t.Error("expected error on UnreadRune from fresh buffer") |
| 413 } |
| 414 _, _, err := r.ReadRune() |
| 415 if err != nil { |
| 416 t.Error("unexpected error on ReadRune (1):", err) |
| 417 } |
| 418 if err = r.UnreadRune(); err != nil { |
| 419 t.Error("unexpected error on UnreadRune (1):", err) |
| 420 } |
| 421 if r.UnreadRune() == nil { |
| 422 t.Error("expected error after UnreadRune (1)") |
| 423 } |
| 424 // Test error after Read. |
| 425 _, _, err = r.ReadRune() // reset state |
| 426 if err != nil { |
| 427 t.Error("unexpected error on ReadRune (2):", err) |
| 428 } |
| 429 _, err = r.Read(buf) |
| 430 if err != nil { |
| 431 t.Error("unexpected error on Read (2):", err) |
| 432 } |
| 433 if r.UnreadRune() == nil { |
| 434 t.Error("expected error after Read (2)") |
| 435 } |
| 436 // Test error after ReadByte. |
| 437 _, _, err = r.ReadRune() // reset state |
| 438 if err != nil { |
| 439 t.Error("unexpected error on ReadRune (2):", err) |
| 440 } |
| 441 for _ = range buf { |
| 442 _, err = r.ReadByte() |
| 443 if err != nil { |
| 444 t.Error("unexpected error on ReadByte (2):", err) |
| 445 } |
| 446 } |
| 447 if r.UnreadRune() == nil { |
| 448 t.Error("expected error after ReadByte") |
| 449 } |
| 450 // Test error after UnreadByte. |
| 451 _, _, err = r.ReadRune() // reset state |
| 452 if err != nil { |
| 453 t.Error("unexpected error on ReadRune (3):", err) |
| 454 } |
| 455 _, err = r.ReadByte() |
| 456 if err != nil { |
| 457 t.Error("unexpected error on ReadByte (3):", err) |
| 458 } |
| 459 err = r.UnreadByte() |
| 460 if err != nil { |
| 461 t.Error("unexpected error on UnreadByte (3):", err) |
| 462 } |
| 463 if r.UnreadRune() == nil { |
| 464 t.Error("expected error after UnreadByte (3)") |
| 465 } |
| 466 } |
| 467 |
| 468 func TestUnreadRuneAtEOF(t *testing.T) { |
| 469 // UnreadRune/ReadRune should error at EOF (was a bug; used to panic) |
| 470 r := NewReader(strings.NewReader("x")) |
| 471 r.ReadRune() |
| 472 r.ReadRune() |
| 473 r.UnreadRune() |
| 474 _, _, err := r.ReadRune() |
| 475 if err == nil { |
| 476 t.Error("expected error at EOF") |
| 477 } else if err != io.EOF { |
| 478 t.Error("expected EOF; got", err) |
| 479 } |
| 480 } |
| 481 |
| 482 func TestReadWriteRune(t *testing.T) { |
| 483 const NRune = 1000 |
| 484 byteBuf := new(bytes.Buffer) |
| 485 w := NewWriter(byteBuf) |
| 486 // Write the runes out using WriteRune |
| 487 buf := make([]byte, utf8.UTFMax) |
| 488 for r := rune(0); r < NRune; r++ { |
| 489 size := utf8.EncodeRune(buf, r) |
| 490 nbytes, err := w.WriteRune(r) |
| 491 if err != nil { |
| 492 t.Fatalf("WriteRune(0x%x) error: %s", r, err) |
| 493 } |
| 494 if nbytes != size { |
| 495 t.Fatalf("WriteRune(0x%x) expected %d, got %d", r, size,
nbytes) |
| 496 } |
| 497 } |
| 498 w.Flush() |
| 499 |
| 500 r := NewReader(byteBuf) |
| 501 // Read them back with ReadRune |
| 502 for r1 := rune(0); r1 < NRune; r1++ { |
| 503 size := utf8.EncodeRune(buf, r1) |
| 504 nr, nbytes, err := r.ReadRune() |
| 505 if nr != r1 || nbytes != size || err != nil { |
| 506 t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s
)", r1, nr, nbytes, r1, size, err) |
| 507 } |
| 508 } |
| 509 } |
| 510 |
| 511 func TestWriter(t *testing.T) { |
| 512 var data [8192]byte |
| 513 |
| 514 for i := 0; i < len(data); i++ { |
| 515 data[i] = byte(' ' + i%('~'-' ')) |
| 516 } |
| 517 w := new(bytes.Buffer) |
| 518 for i := 0; i < len(bufsizes); i++ { |
| 519 for j := 0; j < len(bufsizes); j++ { |
| 520 nwrite := bufsizes[i] |
| 521 bs := bufsizes[j] |
| 522 |
| 523 // Write nwrite bytes using buffer size bs. |
| 524 // Check that the right amount makes it out |
| 525 // and that the data is correct. |
| 526 |
| 527 w.Reset() |
| 528 buf := NewWriterSize(w, bs) |
| 529 context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, b
s) |
| 530 n, e1 := buf.Write(data[0:nwrite]) |
| 531 if e1 != nil || n != nwrite { |
| 532 t.Errorf("%s: buf.Write %d = %d, %v", context, n
write, n, e1) |
| 533 continue |
| 534 } |
| 535 if e := buf.Flush(); e != nil { |
| 536 t.Errorf("%s: buf.Flush = %v", context, e) |
| 537 } |
| 538 |
| 539 written := w.Bytes() |
| 540 if len(written) != nwrite { |
| 541 t.Errorf("%s: %d bytes written", context, len(wr
itten)) |
| 542 } |
| 543 for l := 0; l < len(written); l++ { |
| 544 if written[i] != data[i] { |
| 545 t.Errorf("wrong bytes written") |
| 546 t.Errorf("want=%q", data[0:len(written)]
) |
| 547 t.Errorf("have=%q", written) |
| 548 } |
| 549 } |
| 550 } |
| 551 } |
| 552 } |
| 553 |
| 554 // Check that write errors are returned properly. |
| 555 |
| 556 type errorWriterTest struct { |
| 557 n, m int |
| 558 err error |
| 559 expect error |
| 560 } |
| 561 |
| 562 func (w errorWriterTest) Write(p []byte) (int, error) { |
| 563 return len(p) * w.n / w.m, w.err |
| 564 } |
| 565 |
| 566 var errorWriterTests = []errorWriterTest{ |
| 567 {0, 1, nil, io.ErrShortWrite}, |
| 568 {1, 2, nil, io.ErrShortWrite}, |
| 569 {1, 1, nil, nil}, |
| 570 {0, 1, io.ErrClosedPipe, io.ErrClosedPipe}, |
| 571 {1, 2, io.ErrClosedPipe, io.ErrClosedPipe}, |
| 572 {1, 1, io.ErrClosedPipe, io.ErrClosedPipe}, |
| 573 } |
| 574 |
| 575 func TestWriteErrors(t *testing.T) { |
| 576 for _, w := range errorWriterTests { |
| 577 buf := NewWriter(w) |
| 578 _, e := buf.Write([]byte("hello world")) |
| 579 if e != nil { |
| 580 t.Errorf("Write hello to %v: %v", w, e) |
| 581 continue |
| 582 } |
| 583 // Two flushes, to verify the error is sticky. |
| 584 for i := 0; i < 2; i++ { |
| 585 e = buf.Flush() |
| 586 if e != w.expect { |
| 587 t.Errorf("Flush %d/2 %v: got %v, wanted %v", i+1
, w, e, w.expect) |
| 588 } |
| 589 } |
| 590 } |
| 591 } |
| 592 |
| 593 func TestNewReaderSizeIdempotent(t *testing.T) { |
| 594 const BufSize = 1000 |
| 595 b := NewReaderSize(strings.NewReader("hello world"), BufSize) |
| 596 // Does it recognize itself? |
| 597 b1 := NewReaderSize(b, BufSize) |
| 598 if b1 != b { |
| 599 t.Error("NewReaderSize did not detect underlying Reader") |
| 600 } |
| 601 // Does it wrap if existing buffer is too small? |
| 602 b2 := NewReaderSize(b, 2*BufSize) |
| 603 if b2 == b { |
| 604 t.Error("NewReaderSize did not enlarge buffer") |
| 605 } |
| 606 } |
| 607 |
| 608 func TestNewWriterSizeIdempotent(t *testing.T) { |
| 609 const BufSize = 1000 |
| 610 b := NewWriterSize(new(bytes.Buffer), BufSize) |
| 611 // Does it recognize itself? |
| 612 b1 := NewWriterSize(b, BufSize) |
| 613 if b1 != b { |
| 614 t.Error("NewWriterSize did not detect underlying Writer") |
| 615 } |
| 616 // Does it wrap if existing buffer is too small? |
| 617 b2 := NewWriterSize(b, 2*BufSize) |
| 618 if b2 == b { |
| 619 t.Error("NewWriterSize did not enlarge buffer") |
| 620 } |
| 621 } |
| 622 |
| 623 func TestWriteString(t *testing.T) { |
| 624 const BufSize = 8 |
| 625 buf := new(bytes.Buffer) |
| 626 b := NewWriterSize(buf, BufSize) |
| 627 b.WriteString("0") // easy |
| 628 b.WriteString("123456") // still easy |
| 629 b.WriteString("7890") // easy after flush |
| 630 b.WriteString("abcdefghijklmnopqrstuvwxy") // hard |
| 631 b.WriteString("z") |
| 632 if err := b.Flush(); err != nil { |
| 633 t.Error("WriteString", err) |
| 634 } |
| 635 s := "01234567890abcdefghijklmnopqrstuvwxyz" |
| 636 if string(buf.Bytes()) != s { |
| 637 t.Errorf("WriteString wants %q gets %q", s, string(buf.Bytes())) |
| 638 } |
| 639 } |
| 640 |
| 641 func TestBufferFull(t *testing.T) { |
| 642 const longString = "And now, hello, world! It is the time for all good m
en to come to the aid of their party" |
| 643 buf := NewReaderSize(strings.NewReader(longString), minReadBufferSize) |
| 644 line, err := buf.ReadSlice('!') |
| 645 if string(line) != "And now, hello, " || err != ErrBufferFull { |
| 646 t.Errorf("first ReadSlice(,) = %q, %v", line, err) |
| 647 } |
| 648 line, err = buf.ReadSlice('!') |
| 649 if string(line) != "world!" || err != nil { |
| 650 t.Errorf("second ReadSlice(,) = %q, %v", line, err) |
| 651 } |
| 652 } |
| 653 |
| 654 func TestPeek(t *testing.T) { |
| 655 p := make([]byte, 10) |
| 656 // string is 16 (minReadBufferSize) long. |
| 657 buf := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBuffe
rSize) |
| 658 if s, err := buf.Peek(1); string(s) != "a" || err != nil { |
| 659 t.Fatalf("want %q got %q, err=%v", "a", string(s), err) |
| 660 } |
| 661 if s, err := buf.Peek(4); string(s) != "abcd" || err != nil { |
| 662 t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err) |
| 663 } |
| 664 if _, err := buf.Peek(-1); err != ErrNegativeCount { |
| 665 t.Fatalf("want ErrNegativeCount got %v", err) |
| 666 } |
| 667 if _, err := buf.Peek(32); err != ErrBufferFull { |
| 668 t.Fatalf("want ErrBufFull got %v", err) |
| 669 } |
| 670 if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil { |
| 671 t.Fatalf("want %q got %q, err=%v", "abc", string(p[0:3]), err) |
| 672 } |
| 673 if s, err := buf.Peek(1); string(s) != "d" || err != nil { |
| 674 t.Fatalf("want %q got %q, err=%v", "d", string(s), err) |
| 675 } |
| 676 if s, err := buf.Peek(2); string(s) != "de" || err != nil { |
| 677 t.Fatalf("want %q got %q, err=%v", "de", string(s), err) |
| 678 } |
| 679 if _, err := buf.Read(p[0:3]); string(p[0:3]) != "def" || err != nil { |
| 680 t.Fatalf("want %q got %q, err=%v", "def", string(p[0:3]), err) |
| 681 } |
| 682 if s, err := buf.Peek(4); string(s) != "ghij" || err != nil { |
| 683 t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err) |
| 684 } |
| 685 if _, err := buf.Read(p[0:]); string(p[0:]) != "ghijklmnop" || err != ni
l { |
| 686 t.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p[0:minR
eadBufferSize]), err) |
| 687 } |
| 688 if s, err := buf.Peek(0); string(s) != "" || err != nil { |
| 689 t.Fatalf("want %q got %q, err=%v", "", string(s), err) |
| 690 } |
| 691 if _, err := buf.Peek(1); err != io.EOF { |
| 692 t.Fatalf("want EOF got %v", err) |
| 693 } |
| 694 |
| 695 // Test for issue 3022, not exposing a reader's error on a successful Pe
ek. |
| 696 buf = NewReaderSize(dataAndEOFReader("abcd"), 32) |
| 697 if s, err := buf.Peek(2); string(s) != "ab" || err != nil { |
| 698 t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, stri
ng(s), err) |
| 699 } |
| 700 if s, err := buf.Peek(4); string(s) != "abcd" || err != nil { |
| 701 t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, st
ring(s), err) |
| 702 } |
| 703 if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil { |
| 704 t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err
) |
| 705 } |
| 706 if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF { |
| 707 t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n]
, err) |
| 708 } |
| 709 } |
| 710 |
| 711 type dataAndEOFReader string |
| 712 |
| 713 func (r dataAndEOFReader) Read(p []byte) (int, error) { |
| 714 return copy(p, r), io.EOF |
| 715 } |
| 716 |
| 717 func TestPeekThenUnreadRune(t *testing.T) { |
| 718 // This sequence used to cause a crash. |
| 719 r := NewReader(strings.NewReader("x")) |
| 720 r.ReadRune() |
| 721 r.Peek(1) |
| 722 r.UnreadRune() |
| 723 r.ReadRune() // Used to panic here |
| 724 } |
| 725 |
| 726 var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy") |
| 727 var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nx
y") |
| 728 var testInputrn = []byte("012\r\n345\r\n678\r\n9ab\r\ncde\r\nfgh\r\nijk\r\nlmn\r
\nopq\r\nrst\r\nuvw\r\nxy\r\n\n\r\n") |
| 729 |
| 730 // TestReader wraps a []byte and returns reads of a specific length. |
| 731 type testReader struct { |
| 732 data []byte |
| 733 stride int |
| 734 } |
| 735 |
| 736 func (t *testReader) Read(buf []byte) (n int, err error) { |
| 737 n = t.stride |
| 738 if n > len(t.data) { |
| 739 n = len(t.data) |
| 740 } |
| 741 if n > len(buf) { |
| 742 n = len(buf) |
| 743 } |
| 744 copy(buf, t.data) |
| 745 t.data = t.data[n:] |
| 746 if len(t.data) == 0 { |
| 747 err = io.EOF |
| 748 } |
| 749 return |
| 750 } |
| 751 |
| 752 func testReadLine(t *testing.T, input []byte) { |
| 753 //for stride := 1; stride < len(input); stride++ { |
| 754 for stride := 1; stride < 2; stride++ { |
| 755 done := 0 |
| 756 reader := testReader{input, stride} |
| 757 l := NewReaderSize(&reader, len(input)+1) |
| 758 for { |
| 759 line, isPrefix, err := l.ReadLine() |
| 760 if len(line) > 0 && err != nil { |
| 761 t.Errorf("ReadLine returned both data and error:
%s", err) |
| 762 } |
| 763 if isPrefix { |
| 764 t.Errorf("ReadLine returned prefix") |
| 765 } |
| 766 if err != nil { |
| 767 if err != io.EOF { |
| 768 t.Fatalf("Got unknown error: %s", err) |
| 769 } |
| 770 break |
| 771 } |
| 772 if want := testOutput[done : done+len(line)]; !bytes.Equ
al(want, line) { |
| 773 t.Errorf("Bad line at stride %d: want: %x got: %
x", stride, want, line) |
| 774 } |
| 775 done += len(line) |
| 776 } |
| 777 if done != len(testOutput) { |
| 778 t.Errorf("ReadLine didn't return everything: got: %d, wa
nt: %d (stride: %d)", done, len(testOutput), stride) |
| 779 } |
| 780 } |
| 781 } |
| 782 |
| 783 func TestReadLine(t *testing.T) { |
| 784 testReadLine(t, testInput) |
| 785 testReadLine(t, testInputrn) |
| 786 } |
| 787 |
| 788 func TestLineTooLong(t *testing.T) { |
| 789 data := make([]byte, 0) |
| 790 for i := 0; i < minReadBufferSize*5/2; i++ { |
| 791 data = append(data, '0'+byte(i%10)) |
| 792 } |
| 793 buf := bytes.NewReader(data) |
| 794 l := NewReaderSize(buf, minReadBufferSize) |
| 795 line, isPrefix, err := l.ReadLine() |
| 796 if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != n
il { |
| 797 t.Errorf("bad result for first line: got %q want %q %v", line, d
ata[:minReadBufferSize], err) |
| 798 } |
| 799 data = data[len(line):] |
| 800 line, isPrefix, err = l.ReadLine() |
| 801 if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != n
il { |
| 802 t.Errorf("bad result for second line: got %q want %q %v", line,
data[:minReadBufferSize], err) |
| 803 } |
| 804 data = data[len(line):] |
| 805 line, isPrefix, err = l.ReadLine() |
| 806 if isPrefix || !bytes.Equal(line, data[:minReadBufferSize/2]) || err !=
nil { |
| 807 t.Errorf("bad result for third line: got %q want %q %v", line, d
ata[:minReadBufferSize/2], err) |
| 808 } |
| 809 line, isPrefix, err = l.ReadLine() |
| 810 if isPrefix || err == nil { |
| 811 t.Errorf("expected no more lines: %x %s", line, err) |
| 812 } |
| 813 } |
| 814 |
| 815 func TestReadAfterLines(t *testing.T) { |
| 816 line1 := "this is line1" |
| 817 restData := "this is line2\nthis is line 3\n" |
| 818 inbuf := bytes.NewReader([]byte(line1 + "\n" + restData)) |
| 819 outbuf := new(bytes.Buffer) |
| 820 maxLineLength := len(line1) + len(restData)/2 |
| 821 l := NewReaderSize(inbuf, maxLineLength) |
| 822 line, isPrefix, err := l.ReadLine() |
| 823 if isPrefix || err != nil || string(line) != line1 { |
| 824 t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q"
, isPrefix, err, string(line)) |
| 825 } |
| 826 n, err := io.Copy(outbuf, l) |
| 827 if int(n) != len(restData) || err != nil { |
| 828 t.Errorf("bad result for Read: n=%d err=%v", n, err) |
| 829 } |
| 830 if outbuf.String() != restData { |
| 831 t.Errorf("bad result for Read: got %q; expected %q", outbuf.Stri
ng(), restData) |
| 832 } |
| 833 } |
| 834 |
| 835 func TestReadEmptyBuffer(t *testing.T) { |
| 836 l := NewReaderSize(new(bytes.Buffer), minReadBufferSize) |
| 837 line, isPrefix, err := l.ReadLine() |
| 838 if err != io.EOF { |
| 839 t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isP
refix, err) |
| 840 } |
| 841 } |
| 842 |
| 843 func TestLinesAfterRead(t *testing.T) { |
| 844 l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize) |
| 845 _, err := ioutil.ReadAll(l) |
| 846 if err != nil { |
| 847 t.Error(err) |
| 848 return |
| 849 } |
| 850 |
| 851 line, isPrefix, err := l.ReadLine() |
| 852 if err != io.EOF { |
| 853 t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isP
refix, err) |
| 854 } |
| 855 } |
| 856 |
| 857 func TestReadLineNonNilLineOrError(t *testing.T) { |
| 858 r := NewReader(strings.NewReader("line 1\n")) |
| 859 for i := 0; i < 2; i++ { |
| 860 l, _, err := r.ReadLine() |
| 861 if l != nil && err != nil { |
| 862 t.Fatalf("on line %d/2; ReadLine=%#v, %v; want non-nil l
ine or Error, but not both", |
| 863 i+1, l, err) |
| 864 } |
| 865 } |
| 866 } |
| 867 |
| 868 type readLineResult struct { |
| 869 line []byte |
| 870 isPrefix bool |
| 871 err error |
| 872 } |
| 873 |
| 874 var readLineNewlinesTests = []struct { |
| 875 input string |
| 876 expect []readLineResult |
| 877 }{ |
| 878 {"012345678901234\r\n012345678901234\r\n", []readLineResult{ |
| 879 {[]byte("012345678901234"), true, nil}, |
| 880 {nil, false, nil}, |
| 881 {[]byte("012345678901234"), true, nil}, |
| 882 {nil, false, nil}, |
| 883 {nil, false, io.EOF}, |
| 884 }}, |
| 885 {"0123456789012345\r012345678901234\r", []readLineResult{ |
| 886 {[]byte("0123456789012345"), true, nil}, |
| 887 {[]byte("\r012345678901234"), true, nil}, |
| 888 {[]byte("\r"), false, nil}, |
| 889 {nil, false, io.EOF}, |
| 890 }}, |
| 891 } |
| 892 |
| 893 func TestReadLineNewlines(t *testing.T) { |
| 894 for _, e := range readLineNewlinesTests { |
| 895 testReadLineNewlines(t, e.input, e.expect) |
| 896 } |
| 897 } |
| 898 |
| 899 func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) { |
| 900 b := NewReaderSize(strings.NewReader(input), minReadBufferSize) |
| 901 for i, e := range expect { |
| 902 line, isPrefix, err := b.ReadLine() |
| 903 if !bytes.Equal(line, e.line) { |
| 904 t.Errorf("%q call %d, line == %q, want %q", input, i, li
ne, e.line) |
| 905 return |
| 906 } |
| 907 if isPrefix != e.isPrefix { |
| 908 t.Errorf("%q call %d, isPrefix == %v, want %v", input, i
, isPrefix, e.isPrefix) |
| 909 return |
| 910 } |
| 911 if err != e.err { |
| 912 t.Errorf("%q call %d, err == %v, want %v", input, i, err
, e.err) |
| 913 return |
| 914 } |
| 915 } |
| 916 } |
| 917 |
| 918 func createTestInput(n int) []byte { |
| 919 input := make([]byte, n) |
| 920 for i := range input { |
| 921 // 101 and 251 are arbitrary prime numbers. |
| 922 // The idea is to create an input sequence |
| 923 // which doesn't repeat too frequently. |
| 924 input[i] = byte(i % 251) |
| 925 if i%101 == 0 { |
| 926 input[i] ^= byte(i / 101) |
| 927 } |
| 928 } |
| 929 return input |
| 930 } |
| 931 |
| 932 func TestReaderWriteTo(t *testing.T) { |
| 933 input := createTestInput(8192) |
| 934 r := NewReader(onlyReader{bytes.NewReader(input)}) |
| 935 w := new(bytes.Buffer) |
| 936 if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) { |
| 937 t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(inpu
t)) |
| 938 } |
| 939 |
| 940 for i, val := range w.Bytes() { |
| 941 if val != input[i] { |
| 942 t.Errorf("after write: out[%d] = %#x, want %#x", i, val,
input[i]) |
| 943 } |
| 944 } |
| 945 } |
| 946 |
| 947 type errorWriterToTest struct { |
| 948 rn, wn int |
| 949 rerr, werr error |
| 950 expected error |
| 951 } |
| 952 |
| 953 func (r errorWriterToTest) Read(p []byte) (int, error) { |
| 954 return len(p) * r.rn, r.rerr |
| 955 } |
| 956 |
| 957 func (w errorWriterToTest) Write(p []byte) (int, error) { |
| 958 return len(p) * w.wn, w.werr |
| 959 } |
| 960 |
| 961 var errorWriterToTests = []errorWriterToTest{ |
| 962 {1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe}, |
| 963 {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe}, |
| 964 {0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe}, |
| 965 {0, 1, io.EOF, nil, nil}, |
| 966 } |
| 967 |
| 968 func TestReaderWriteToErrors(t *testing.T) { |
| 969 for i, rw := range errorWriterToTests { |
| 970 r := NewReader(rw) |
| 971 if _, err := r.WriteTo(rw); err != rw.expected { |
| 972 t.Errorf("r.WriteTo(errorWriterToTests[%d]) = _, %v, wan
t _,%v", i, err, rw.expected) |
| 973 } |
| 974 } |
| 975 } |
| 976 |
| 977 func TestWriterReadFrom(t *testing.T) { |
| 978 ws := []func(io.Writer) io.Writer{ |
| 979 func(w io.Writer) io.Writer { return onlyWriter{w} }, |
| 980 func(w io.Writer) io.Writer { return w }, |
| 981 } |
| 982 |
| 983 rs := []func(io.Reader) io.Reader{ |
| 984 iotest.DataErrReader, |
| 985 func(r io.Reader) io.Reader { return r }, |
| 986 } |
| 987 |
| 988 for ri, rfunc := range rs { |
| 989 for wi, wfunc := range ws { |
| 990 input := createTestInput(8192) |
| 991 b := new(bytes.Buffer) |
| 992 w := NewWriter(wfunc(b)) |
| 993 r := rfunc(bytes.NewReader(input)) |
| 994 if n, err := w.ReadFrom(r); err != nil || n != int64(len
(input)) { |
| 995 t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v,
want %d, nil", wi, ri, n, err, len(input)) |
| 996 continue |
| 997 } |
| 998 if err := w.Flush(); err != nil { |
| 999 t.Errorf("Flush returned %v", err) |
| 1000 continue |
| 1001 } |
| 1002 if got, want := b.String(), string(input); got != want { |
| 1003 t.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n",
wi, ri, got, want) |
| 1004 } |
| 1005 } |
| 1006 } |
| 1007 } |
| 1008 |
| 1009 type errorReaderFromTest struct { |
| 1010 rn, wn int |
| 1011 rerr, werr error |
| 1012 expected error |
| 1013 } |
| 1014 |
| 1015 func (r errorReaderFromTest) Read(p []byte) (int, error) { |
| 1016 return len(p) * r.rn, r.rerr |
| 1017 } |
| 1018 |
| 1019 func (w errorReaderFromTest) Write(p []byte) (int, error) { |
| 1020 return len(p) * w.wn, w.werr |
| 1021 } |
| 1022 |
| 1023 var errorReaderFromTests = []errorReaderFromTest{ |
| 1024 {0, 1, io.EOF, nil, nil}, |
| 1025 {1, 1, io.EOF, nil, nil}, |
| 1026 {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe}, |
| 1027 {0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe}, |
| 1028 {1, 0, nil, io.ErrShortWrite, io.ErrShortWrite}, |
| 1029 } |
| 1030 |
| 1031 func TestWriterReadFromErrors(t *testing.T) { |
| 1032 for i, rw := range errorReaderFromTests { |
| 1033 w := NewWriter(rw) |
| 1034 if _, err := w.ReadFrom(rw); err != rw.expected { |
| 1035 t.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v,
want _,%v", i, err, rw.expected) |
| 1036 } |
| 1037 } |
| 1038 } |
| 1039 |
| 1040 // TestWriterReadFromCounts tests that using io.Copy to copy into a |
| 1041 // bufio.Writer does not prematurely flush the buffer. For example, when |
| 1042 // buffering writes to a network socket, excessive network writes should be |
| 1043 // avoided. |
| 1044 func TestWriterReadFromCounts(t *testing.T) { |
| 1045 var w0 writeCountingDiscard |
| 1046 b0 := NewWriterSize(&w0, 1234) |
| 1047 b0.WriteString(strings.Repeat("x", 1000)) |
| 1048 if w0 != 0 { |
| 1049 t.Fatalf("write 1000 'x's: got %d writes, want 0", w0) |
| 1050 } |
| 1051 b0.WriteString(strings.Repeat("x", 200)) |
| 1052 if w0 != 0 { |
| 1053 t.Fatalf("write 1200 'x's: got %d writes, want 0", w0) |
| 1054 } |
| 1055 io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 30))}) |
| 1056 if w0 != 0 { |
| 1057 t.Fatalf("write 1230 'x's: got %d writes, want 0", w0) |
| 1058 } |
| 1059 io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 9))}) |
| 1060 if w0 != 1 { |
| 1061 t.Fatalf("write 1239 'x's: got %d writes, want 1", w0) |
| 1062 } |
| 1063 |
| 1064 var w1 writeCountingDiscard |
| 1065 b1 := NewWriterSize(&w1, 1234) |
| 1066 b1.WriteString(strings.Repeat("x", 1200)) |
| 1067 b1.Flush() |
| 1068 if w1 != 1 { |
| 1069 t.Fatalf("flush 1200 'x's: got %d writes, want 1", w1) |
| 1070 } |
| 1071 b1.WriteString(strings.Repeat("x", 89)) |
| 1072 if w1 != 1 { |
| 1073 t.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1) |
| 1074 } |
| 1075 io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 700))}) |
| 1076 if w1 != 1 { |
| 1077 t.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1) |
| 1078 } |
| 1079 io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 600))}) |
| 1080 if w1 != 2 { |
| 1081 t.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1) |
| 1082 } |
| 1083 b1.Flush() |
| 1084 if w1 != 3 { |
| 1085 t.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1) |
| 1086 } |
| 1087 } |
| 1088 |
| 1089 // A writeCountingDiscard is like ioutil.Discard and counts the number of times |
| 1090 // Write is called on it. |
| 1091 type writeCountingDiscard int |
| 1092 |
| 1093 func (w *writeCountingDiscard) Write(p []byte) (int, error) { |
| 1094 *w++ |
| 1095 return len(p), nil |
| 1096 } |
| 1097 |
| 1098 type negativeReader int |
| 1099 |
| 1100 func (r *negativeReader) Read([]byte) (int, error) { return -1, nil } |
| 1101 |
| 1102 func TestNegativeRead(t *testing.T) { |
| 1103 // should panic with a description pointing at the reader, not at itself
. |
| 1104 // (should NOT panic with slice index error, for example.) |
| 1105 b := NewReader(new(negativeReader)) |
| 1106 defer func() { |
| 1107 switch err := recover().(type) { |
| 1108 case nil: |
| 1109 t.Fatal("read did not panic") |
| 1110 case error: |
| 1111 if !strings.Contains(err.Error(), "reader returned negat
ive count from Read") { |
| 1112 t.Fatalf("wrong panic: %v", err) |
| 1113 } |
| 1114 default: |
| 1115 t.Fatalf("unexpected panic value: %T(%v)", err, err) |
| 1116 } |
| 1117 }() |
| 1118 b.Read(make([]byte, 100)) |
| 1119 } |
| 1120 |
| 1121 var errFake = errors.New("fake error") |
| 1122 |
| 1123 type errorThenGoodReader struct { |
| 1124 didErr bool |
| 1125 nread int |
| 1126 } |
| 1127 |
| 1128 func (r *errorThenGoodReader) Read(p []byte) (int, error) { |
| 1129 r.nread++ |
| 1130 if !r.didErr { |
| 1131 r.didErr = true |
| 1132 return 0, errFake |
| 1133 } |
| 1134 return len(p), nil |
| 1135 } |
| 1136 |
| 1137 func TestReaderClearError(t *testing.T) { |
| 1138 r := &errorThenGoodReader{} |
| 1139 b := NewReader(r) |
| 1140 buf := make([]byte, 1) |
| 1141 if _, err := b.Read(nil); err != nil { |
| 1142 t.Fatalf("1st nil Read = %v; want nil", err) |
| 1143 } |
| 1144 if _, err := b.Read(buf); err != errFake { |
| 1145 t.Fatalf("1st Read = %v; want errFake", err) |
| 1146 } |
| 1147 if _, err := b.Read(nil); err != nil { |
| 1148 t.Fatalf("2nd nil Read = %v; want nil", err) |
| 1149 } |
| 1150 if _, err := b.Read(buf); err != nil { |
| 1151 t.Fatalf("3rd Read with buffer = %v; want nil", err) |
| 1152 } |
| 1153 if r.nread != 2 { |
| 1154 t.Errorf("num reads = %d; want 2", r.nread) |
| 1155 } |
| 1156 } |
| 1157 |
| 1158 // Test for golang.org/issue/5947 |
| 1159 func TestWriterReadFromWhileFull(t *testing.T) { |
| 1160 buf := new(bytes.Buffer) |
| 1161 w := NewWriterSize(buf, 10) |
| 1162 |
| 1163 // Fill buffer exactly. |
| 1164 n, err := w.Write([]byte("0123456789")) |
| 1165 if n != 10 || err != nil { |
| 1166 t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err) |
| 1167 } |
| 1168 |
| 1169 // Use ReadFrom to read in some data. |
| 1170 n2, err := w.ReadFrom(strings.NewReader("abcdef")) |
| 1171 if n2 != 6 || err != nil { |
| 1172 t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n2, err) |
| 1173 } |
| 1174 } |
| 1175 |
| 1176 type emptyThenNonEmptyReader struct { |
| 1177 r io.Reader |
| 1178 n int |
| 1179 } |
| 1180 |
| 1181 func (r *emptyThenNonEmptyReader) Read(p []byte) (int, error) { |
| 1182 if r.n <= 0 { |
| 1183 return r.r.Read(p) |
| 1184 } |
| 1185 r.n-- |
| 1186 return 0, nil |
| 1187 } |
| 1188 |
| 1189 // Test for golang.org/issue/7611 |
| 1190 func TestWriterReadFromUntilEOF(t *testing.T) { |
| 1191 buf := new(bytes.Buffer) |
| 1192 w := NewWriterSize(buf, 5) |
| 1193 |
| 1194 // Partially fill buffer |
| 1195 n, err := w.Write([]byte("0123")) |
| 1196 if n != 4 || err != nil { |
| 1197 t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err) |
| 1198 } |
| 1199 |
| 1200 // Use ReadFrom to read in some data. |
| 1201 r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 3} |
| 1202 n2, err := w.ReadFrom(r) |
| 1203 if n2 != 4 || err != nil { |
| 1204 t.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2, err) |
| 1205 } |
| 1206 w.Flush() |
| 1207 if got, want := string(buf.Bytes()), "0123abcd"; got != want { |
| 1208 t.Fatalf("buf.Bytes() returned %q, want %q", got, want) |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 func TestWriterReadFromErrNoProgress(t *testing.T) { |
| 1213 buf := new(bytes.Buffer) |
| 1214 w := NewWriterSize(buf, 5) |
| 1215 |
| 1216 // Partially fill buffer |
| 1217 n, err := w.Write([]byte("0123")) |
| 1218 if n != 4 || err != nil { |
| 1219 t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err) |
| 1220 } |
| 1221 |
| 1222 // Use ReadFrom to read in some data. |
| 1223 r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 100} |
| 1224 n2, err := w.ReadFrom(r) |
| 1225 if n2 != 0 || err != io.ErrNoProgress { |
| 1226 t.Fatalf("buf.Bytes() returned (%v, %v), want (0, io.ErrNoProgre
ss)", n2, err) |
| 1227 } |
| 1228 } |
| 1229 |
| 1230 func TestReaderReset(t *testing.T) { |
| 1231 r := NewReader(strings.NewReader("foo foo")) |
| 1232 buf := make([]byte, 3) |
| 1233 r.Read(buf) |
| 1234 if string(buf) != "foo" { |
| 1235 t.Errorf("buf = %q; want foo", buf) |
| 1236 } |
| 1237 r.Reset(strings.NewReader("bar bar")) |
| 1238 all, err := ioutil.ReadAll(r) |
| 1239 if err != nil { |
| 1240 t.Fatal(err) |
| 1241 } |
| 1242 if string(all) != "bar bar" { |
| 1243 t.Errorf("ReadAll = %q; want bar bar", all) |
| 1244 } |
| 1245 } |
| 1246 |
| 1247 func TestWriterReset(t *testing.T) { |
| 1248 var buf1, buf2 bytes.Buffer |
| 1249 w := NewWriter(&buf1) |
| 1250 w.WriteString("foo") |
| 1251 w.Reset(&buf2) // and not flushed |
| 1252 w.WriteString("bar") |
| 1253 w.Flush() |
| 1254 if buf1.String() != "" { |
| 1255 t.Errorf("buf1 = %q; want empty", buf1.String()) |
| 1256 } |
| 1257 if buf2.String() != "bar" { |
| 1258 t.Errorf("buf2 = %q; want bar", buf2.String()) |
| 1259 } |
| 1260 } |
| 1261 |
| 1262 // An onlyReader only implements io.Reader, no matter what other methods the und
erlying implementation may have. |
| 1263 type onlyReader struct { |
| 1264 io.Reader |
| 1265 } |
| 1266 |
| 1267 // An onlyWriter only implements io.Writer, no matter what other methods the und
erlying implementation may have. |
| 1268 type onlyWriter struct { |
| 1269 io.Writer |
| 1270 } |
| 1271 |
| 1272 func BenchmarkReaderCopyOptimal(b *testing.B) { |
| 1273 // Optimal case is where the underlying reader implements io.WriterTo |
| 1274 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1275 src := NewReader(srcBuf) |
| 1276 dstBuf := new(bytes.Buffer) |
| 1277 dst := onlyWriter{dstBuf} |
| 1278 for i := 0; i < b.N; i++ { |
| 1279 srcBuf.Reset() |
| 1280 src.Reset(srcBuf) |
| 1281 dstBuf.Reset() |
| 1282 io.Copy(dst, src) |
| 1283 } |
| 1284 } |
| 1285 |
| 1286 func BenchmarkReaderCopyUnoptimal(b *testing.B) { |
| 1287 // Unoptimal case is where the underlying reader doesn't implement io.Wr
iterTo |
| 1288 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1289 src := NewReader(onlyReader{srcBuf}) |
| 1290 dstBuf := new(bytes.Buffer) |
| 1291 dst := onlyWriter{dstBuf} |
| 1292 for i := 0; i < b.N; i++ { |
| 1293 srcBuf.Reset() |
| 1294 src.Reset(onlyReader{srcBuf}) |
| 1295 dstBuf.Reset() |
| 1296 io.Copy(dst, src) |
| 1297 } |
| 1298 } |
| 1299 |
| 1300 func BenchmarkReaderCopyNoWriteTo(b *testing.B) { |
| 1301 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1302 srcReader := NewReader(srcBuf) |
| 1303 src := onlyReader{srcReader} |
| 1304 dstBuf := new(bytes.Buffer) |
| 1305 dst := onlyWriter{dstBuf} |
| 1306 for i := 0; i < b.N; i++ { |
| 1307 srcBuf.Reset() |
| 1308 srcReader.Reset(srcBuf) |
| 1309 dstBuf.Reset() |
| 1310 io.Copy(dst, src) |
| 1311 } |
| 1312 } |
| 1313 |
| 1314 func BenchmarkReaderWriteToOptimal(b *testing.B) { |
| 1315 const bufSize = 16 << 10 |
| 1316 buf := make([]byte, bufSize) |
| 1317 r := bytes.NewReader(buf) |
| 1318 srcReader := NewReaderSize(onlyReader{r}, 1<<10) |
| 1319 if _, ok := ioutil.Discard.(io.ReaderFrom); !ok { |
| 1320 b.Fatal("ioutil.Discard doesn't support ReaderFrom") |
| 1321 } |
| 1322 for i := 0; i < b.N; i++ { |
| 1323 r.Seek(0, 0) |
| 1324 srcReader.Reset(onlyReader{r}) |
| 1325 n, err := srcReader.WriteTo(ioutil.Discard) |
| 1326 if err != nil { |
| 1327 b.Fatal(err) |
| 1328 } |
| 1329 if n != bufSize { |
| 1330 b.Fatalf("n = %d; want %d", n, bufSize) |
| 1331 } |
| 1332 } |
| 1333 } |
| 1334 |
| 1335 func BenchmarkWriterCopyOptimal(b *testing.B) { |
| 1336 // Optimal case is where the underlying writer implements io.ReaderFrom |
| 1337 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1338 src := onlyReader{srcBuf} |
| 1339 dstBuf := new(bytes.Buffer) |
| 1340 dst := NewWriter(dstBuf) |
| 1341 for i := 0; i < b.N; i++ { |
| 1342 srcBuf.Reset() |
| 1343 dstBuf.Reset() |
| 1344 dst.Reset(dstBuf) |
| 1345 io.Copy(dst, src) |
| 1346 } |
| 1347 } |
| 1348 |
| 1349 func BenchmarkWriterCopyUnoptimal(b *testing.B) { |
| 1350 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1351 src := onlyReader{srcBuf} |
| 1352 dstBuf := new(bytes.Buffer) |
| 1353 dst := NewWriter(onlyWriter{dstBuf}) |
| 1354 for i := 0; i < b.N; i++ { |
| 1355 srcBuf.Reset() |
| 1356 dstBuf.Reset() |
| 1357 dst.Reset(onlyWriter{dstBuf}) |
| 1358 io.Copy(dst, src) |
| 1359 } |
| 1360 } |
| 1361 |
| 1362 func BenchmarkWriterCopyNoReadFrom(b *testing.B) { |
| 1363 srcBuf := bytes.NewBuffer(make([]byte, 8192)) |
| 1364 src := onlyReader{srcBuf} |
| 1365 dstBuf := new(bytes.Buffer) |
| 1366 dstWriter := NewWriter(dstBuf) |
| 1367 dst := onlyWriter{dstWriter} |
| 1368 for i := 0; i < b.N; i++ { |
| 1369 srcBuf.Reset() |
| 1370 dstBuf.Reset() |
| 1371 dstWriter.Reset(dstBuf) |
| 1372 io.Copy(dst, src) |
| 1373 } |
| 1374 } |
| 1375 |
| 1376 func BenchmarkReaderEmpty(b *testing.B) { |
| 1377 b.ReportAllocs() |
| 1378 str := strings.Repeat("x", 16<<10) |
| 1379 for i := 0; i < b.N; i++ { |
| 1380 br := NewReader(strings.NewReader(str)) |
| 1381 n, err := io.Copy(ioutil.Discard, br) |
| 1382 if err != nil { |
| 1383 b.Fatal(err) |
| 1384 } |
| 1385 if n != int64(len(str)) { |
| 1386 b.Fatal("wrong length") |
| 1387 } |
| 1388 } |
| 1389 } |
| 1390 |
| 1391 func BenchmarkWriterEmpty(b *testing.B) { |
| 1392 b.ReportAllocs() |
| 1393 str := strings.Repeat("x", 1<<10) |
| 1394 bs := []byte(str) |
| 1395 for i := 0; i < b.N; i++ { |
| 1396 bw := NewWriter(ioutil.Discard) |
| 1397 bw.Flush() |
| 1398 bw.WriteByte('a') |
| 1399 bw.Flush() |
| 1400 bw.WriteRune('B') |
| 1401 bw.Flush() |
| 1402 bw.Write(bs) |
| 1403 bw.Flush() |
| 1404 bw.WriteString(str) |
| 1405 bw.Flush() |
| 1406 } |
| 1407 } |
| 1408 |
| 1409 func BenchmarkWriterFlush(b *testing.B) { |
| 1410 b.ReportAllocs() |
| 1411 bw := NewWriter(ioutil.Discard) |
| 1412 str := strings.Repeat("x", 50) |
| 1413 for i := 0; i < b.N; i++ { |
| 1414 bw.WriteString(str) |
| 1415 bw.Flush() |
| 1416 } |
| 1417 } |
LEFT | RIGHT |