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.
21 // Reads from a reader and rot13s the result.
22 type rot13Reader
struct {
26 func newRot13Reader(r io
.Reader
) *rot13Reader
{
27 r13
:= new(rot13Reader
)
32 func (r13
*rot13Reader
) Read(p
[]byte) (int, error
) {
33 n
, err
:= r13
.r
.Read(p
)
34 for i
:= 0; i
< n
; i
++ {
35 c
:= p
[i
] |
0x20 // lowercase byte
36 if 'a' <= c
&& c
<= 'm' {
38 } else if 'n' <= c
&& c
<= 'z' {
45 // Call ReadByte to accumulate the text of a file
46 func readBytes(buf
*Reader
) string {
50 c
, err
:= buf
.ReadByte()
57 } else if err
!= iotest
.ErrTimeout
{
58 panic("Data: " + err
.Error())
61 return string(b
[0:nb
])
64 func TestReaderSimple(t
*testing
.T
) {
66 b
:= NewReader(strings
.NewReader(data
))
67 if s
:= readBytes(b
); s
!= "hello world" {
68 t
.Errorf("simple hello world test failed: got %q", s
)
71 b
= NewReader(newRot13Reader(strings
.NewReader(data
)))
72 if s
:= readBytes(b
); s
!= "uryyb jbeyq" {
73 t
.Errorf("rot13 hello world test failed: got %q", s
)
77 type readMaker
struct {
79 fn
func(io
.Reader
) io
.Reader
82 var readMakers
= []readMaker
{
83 {"full", func(r io
.Reader
) io
.Reader
{ return r
}},
84 {"byte", iotest
.OneByteReader
},
85 {"half", iotest
.HalfReader
},
86 {"data+err", iotest
.DataErrReader
},
87 {"timeout", iotest
.TimeoutReader
},
90 // Call ReadString (which ends up calling everything else)
91 // to accumulate the text of a file.
92 func readLines(b
*Reader
) string {
95 s1
, err
:= b
.ReadString('\n')
99 if err
!= nil && err
!= iotest
.ErrTimeout
{
100 panic("GetLines: " + err
.Error())
107 // Call Read to accumulate the text of a file
108 func reads(buf
*Reader
, m
int) string {
112 n
, err
:= buf
.Read(b
[nb
: nb
+m
])
118 return string(b
[0:nb
])
121 type bufReader
struct {
123 fn
func(*Reader
) string
126 var bufreaders
= []bufReader
{
127 {"1", func(b
*Reader
) string { return reads(b
, 1) }},
128 {"2", func(b
*Reader
) string { return reads(b
, 2) }},
129 {"3", func(b
*Reader
) string { return reads(b
, 3) }},
130 {"4", func(b
*Reader
) string { return reads(b
, 4) }},
131 {"5", func(b
*Reader
) string { return reads(b
, 5) }},
132 {"7", func(b
*Reader
) string { return reads(b
, 7) }},
133 {"bytes", readBytes
},
134 {"lines", readLines
},
137 const minReadBufferSize
= 16
139 var bufsizes
= []int{
140 0, minReadBufferSize
, 23, 32, 46, 64, 93, 128, 1024, 4096,
143 func TestReader(t
*testing
.T
) {
147 for i
:= 0; i
< len(texts
)-1; i
++ {
148 texts
[i
] = str
+ "\n"
150 str
+= string(i%26
+ 'a')
152 texts
[len(texts
)-1] = all
154 for h
:= 0; h
< len(texts
); h
++ {
156 for i
:= 0; i
< len(readMakers
); i
++ {
157 for j
:= 0; j
< len(bufreaders
); j
++ {
158 for k
:= 0; k
< len(bufsizes
); k
++ {
159 readmaker
:= readMakers
[i
]
160 bufreader
:= bufreaders
[j
]
161 bufsize
:= bufsizes
[k
]
162 read
:= readmaker
.fn(strings
.NewReader(text
))
163 buf
:= NewReaderSize(read
, bufsize
)
164 s
:= bufreader
.fn(buf
)
166 t
.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
167 readmaker
.name
, bufreader
.name
, bufsize
, text
, s
)
175 type zeroReader
struct{}
177 func (zeroReader
) Read(p
[]byte) (int, error
) {
181 func TestZeroReader(t
*testing
.T
) {
185 c
:= make(chan error
)
187 _
, err
:= r
.ReadByte()
194 t
.Error("error expected")
195 } else if err
!= io
.ErrNoProgress
{
196 t
.Error("unexpected error:", err
)
198 case <-time
.After(time
.Second
):
199 t
.Error("test timed out (endless loop in ReadByte?)")
203 // A StringReader delivers its data one string segment at a time via Read.
204 type StringReader
struct {
209 func (r
*StringReader
) Read(p
[]byte) (n
int, err error
) {
210 if r
.step
< len(r
.data
) {
220 func readRuneSegments(t
*testing
.T
, segments
[]string) {
222 want
:= strings
.Join(segments
, "")
223 r
:= NewReader(&StringReader
{data
: segments
})
225 r
, _
, err
:= r
.ReadRune()
235 t
.Errorf("segments=%v got=%s want=%s", segments
, got
, want
)
239 var segmentList
= [][]string{
243 {"\u65e5", "\u672c", "\u8a9e"},
244 {"\U000065e5", "\U0000672c", "\U00008a9e"},
245 {"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
246 {"Hello", ", ", "World", "!"},
247 {"Hello", ", ", "", "World", "!"},
250 func TestReadRune(t
*testing
.T
) {
251 for _
, s
:= range segmentList
{
252 readRuneSegments(t
, s
)
256 func TestUnreadRune(t
*testing
.T
) {
257 segments
:= []string{"Hello, world:", "日本語"}
258 r
:= NewReader(&StringReader
{data
: segments
})
260 want
:= strings
.Join(segments
, "")
263 r1
, _
, err
:= r
.ReadRune()
266 t
.Error("unexpected error on ReadRune:", err
)
271 // Put it back and read it again.
272 if err
= r
.UnreadRune(); err
!= nil {
273 t
.Fatal("unexpected error on UnreadRune:", err
)
275 r2
, _
, err
:= r
.ReadRune()
277 t
.Fatal("unexpected error reading after unreading:", err
)
280 t
.Fatalf("incorrect rune after unread: got %c, want %c", r1
, r2
)
284 t
.Errorf("got %q, want %q", got
, want
)
288 func TestNoUnreadRuneAfterPeek(t
*testing
.T
) {
289 br
:= NewReader(strings
.NewReader("example"))
292 if err
:= br
.UnreadRune(); err
== nil {
293 t
.Error("UnreadRune didn't fail after Peek")
297 func TestNoUnreadByteAfterPeek(t
*testing
.T
) {
298 br
:= NewReader(strings
.NewReader("example"))
301 if err
:= br
.UnreadByte(); err
== nil {
302 t
.Error("UnreadByte didn't fail after Peek")
306 func TestUnreadByte(t
*testing
.T
) {
307 segments
:= []string{"Hello, ", "world"}
308 r
:= NewReader(&StringReader
{data
: segments
})
310 want
:= strings
.Join(segments
, "")
313 b1
, err
:= r
.ReadByte()
316 t
.Error("unexpected error on ReadByte:", err
)
321 // Put it back and read it again.
322 if err
= r
.UnreadByte(); err
!= nil {
323 t
.Fatal("unexpected error on UnreadByte:", err
)
325 b2
, err
:= r
.ReadByte()
327 t
.Fatal("unexpected error reading after unreading:", err
)
330 t
.Fatalf("incorrect byte after unread: got %q, want %q", b1
, b2
)
334 t
.Errorf("got %q, want %q", got
, want
)
338 func TestUnreadByteMultiple(t
*testing
.T
) {
339 segments
:= []string{"Hello, ", "world"}
340 data
:= strings
.Join(segments
, "")
341 for n
:= 0; n
<= len(data
); n
++ {
342 r
:= NewReader(&StringReader
{data
: segments
})
344 for i
:= 0; i
< n
; i
++ {
345 b
, err
:= r
.ReadByte()
347 t
.Fatalf("n = %d: unexpected error on ReadByte: %v", n
, err
)
350 t
.Fatalf("n = %d: incorrect byte returned from ReadByte: got %q, want %q", n
, b
, data
[i
])
353 // Unread one byte if there is one.
355 if err
:= r
.UnreadByte(); err
!= nil {
356 t
.Errorf("n = %d: unexpected error on UnreadByte: %v", n
, err
)
359 // Test that we cannot unread any further.
360 if err
:= r
.UnreadByte(); err
== nil {
361 t
.Errorf("n = %d: expected error on UnreadByte", n
)
366 func TestUnreadByteOthers(t
*testing
.T
) {
367 // A list of readers to use in conjunction with UnreadByte.
368 var readers
= []func(*Reader
, byte) ([]byte, error
){
371 func(r
*Reader
, delim
byte) ([]byte, error
) {
372 data
, err
:= r
.ReadString(delim
)
373 return []byte(data
), err
375 // ReadLine doesn't fit the data/pattern easily
376 // so we leave it out. It should be covered via
377 // the ReadSlice test since ReadLine simply calls
378 // ReadSlice, and it's that function that handles
382 // Try all readers with UnreadByte.
383 for rno
, read
:= range readers
{
384 // Some input data that is longer than the minimum reader buffer size.
387 for i
:= 0; i
< n
; i
++ {
388 buf
.WriteString("abcdefg")
391 r
:= NewReaderSize(&buf
, minReadBufferSize
)
392 readTo
:= func(delim
byte, want
string) {
393 data
, err
:= read(r
, delim
)
395 t
.Fatalf("#%d: unexpected error reading to %c: %v", rno
, delim
, err
)
397 if got
:= string(data
); got
!= want
{
398 t
.Fatalf("#%d: got %q, want %q", rno
, got
, want
)
402 // Read the data with occasional UnreadByte calls.
403 for i
:= 0; i
< n
; i
++ {
405 for j
:= 0; j
< 3; j
++ {
406 if err
:= r
.UnreadByte(); err
!= nil {
407 t
.Fatalf("#%d: unexpected error on UnreadByte: %v", rno
, err
)
414 // All data should have been read.
415 _
, err
:= r
.ReadByte()
417 t
.Errorf("#%d: got error %v; want EOF", rno
, err
)
422 // Test that UnreadRune fails if the preceding operation was not a ReadRune.
423 func TestUnreadRuneError(t
*testing
.T
) {
424 buf
:= make([]byte, 3) // All runes in this test are 3 bytes long
425 r
:= NewReader(&StringReader
{data
: []string{"日本語日本語日本語"}})
426 if r
.UnreadRune() == nil {
427 t
.Error("expected error on UnreadRune from fresh buffer")
429 _
, _
, err
:= r
.ReadRune()
431 t
.Error("unexpected error on ReadRune (1):", err
)
433 if err
= r
.UnreadRune(); err
!= nil {
434 t
.Error("unexpected error on UnreadRune (1):", err
)
436 if r
.UnreadRune() == nil {
437 t
.Error("expected error after UnreadRune (1)")
439 // Test error after Read.
440 _
, _
, err
= r
.ReadRune() // reset state
442 t
.Error("unexpected error on ReadRune (2):", err
)
446 t
.Error("unexpected error on Read (2):", err
)
448 if r
.UnreadRune() == nil {
449 t
.Error("expected error after Read (2)")
451 // Test error after ReadByte.
452 _
, _
, err
= r
.ReadRune() // reset state
454 t
.Error("unexpected error on ReadRune (2):", err
)
457 _
, err
= r
.ReadByte()
459 t
.Error("unexpected error on ReadByte (2):", err
)
462 if r
.UnreadRune() == nil {
463 t
.Error("expected error after ReadByte")
465 // Test error after UnreadByte.
466 _
, _
, err
= r
.ReadRune() // reset state
468 t
.Error("unexpected error on ReadRune (3):", err
)
470 _
, err
= r
.ReadByte()
472 t
.Error("unexpected error on ReadByte (3):", err
)
476 t
.Error("unexpected error on UnreadByte (3):", err
)
478 if r
.UnreadRune() == nil {
479 t
.Error("expected error after UnreadByte (3)")
481 // Test error after ReadSlice.
482 _
, _
, err
= r
.ReadRune() // reset state
484 t
.Error("unexpected error on ReadRune (4):", err
)
486 _
, err
= r
.ReadSlice(0)
488 t
.Error("unexpected error on ReadSlice (4):", err
)
490 if r
.UnreadRune() == nil {
491 t
.Error("expected error after ReadSlice (4)")
495 func TestUnreadRuneAtEOF(t
*testing
.T
) {
496 // UnreadRune/ReadRune should error at EOF (was a bug; used to panic)
497 r
:= NewReader(strings
.NewReader("x"))
501 _
, _
, err
:= r
.ReadRune()
503 t
.Error("expected error at EOF")
504 } else if err
!= io
.EOF
{
505 t
.Error("expected EOF; got", err
)
509 func TestReadWriteRune(t
*testing
.T
) {
511 byteBuf
:= new(bytes
.Buffer
)
512 w
:= NewWriter(byteBuf
)
513 // Write the runes out using WriteRune
514 buf
:= make([]byte, utf8
.UTFMax
)
515 for r
:= rune(0); r
< NRune
; r
++ {
516 size
:= utf8
.EncodeRune(buf
, r
)
517 nbytes
, err
:= w
.WriteRune(r
)
519 t
.Fatalf("WriteRune(0x%x) error: %s", r
, err
)
522 t
.Fatalf("WriteRune(0x%x) expected %d, got %d", r
, size
, nbytes
)
527 r
:= NewReader(byteBuf
)
528 // Read them back with ReadRune
529 for r1
:= rune(0); r1
< NRune
; r1
++ {
530 size
:= utf8
.EncodeRune(buf
, r1
)
531 nr
, nbytes
, err
:= r
.ReadRune()
532 if nr
!= r1 || nbytes
!= size || err
!= nil {
533 t
.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r1
, nr
, nbytes
, r1
, size
, err
)
538 func TestWriter(t
*testing
.T
) {
541 for i
:= 0; i
< len(data
); i
++ {
542 data
[i
] = byte(' ' + i
%('~'-' '))
544 w
:= new(bytes
.Buffer
)
545 for i
:= 0; i
< len(bufsizes
); i
++ {
546 for j
:= 0; j
< len(bufsizes
); j
++ {
547 nwrite
:= bufsizes
[i
]
550 // Write nwrite bytes using buffer size bs.
551 // Check that the right amount makes it out
552 // and that the data is correct.
555 buf
:= NewWriterSize(w
, bs
)
556 context
:= fmt
.Sprintf("nwrite=%d bufsize=%d", nwrite
, bs
)
557 n
, e1
:= buf
.Write(data
[0:nwrite
])
558 if e1
!= nil || n
!= nwrite
{
559 t
.Errorf("%s: buf.Write %d = %d, %v", context
, nwrite
, n
, e1
)
562 if e
:= buf
.Flush(); e
!= nil {
563 t
.Errorf("%s: buf.Flush = %v", context
, e
)
567 if len(written
) != nwrite
{
568 t
.Errorf("%s: %d bytes written", context
, len(written
))
570 for l
:= 0; l
< len(written
); l
++ {
571 if written
[l
] != data
[l
] {
572 t
.Errorf("wrong bytes written")
573 t
.Errorf("want=%q", data
[0:len(written
)])
574 t
.Errorf("have=%q", written
)
581 // Check that write errors are returned properly.
583 type errorWriterTest
struct {
589 func (w errorWriterTest
) Write(p
[]byte) (int, error
) {
590 return len(p
) * w
.n
/ w
.m
, w
.err
593 var errorWriterTests
= []errorWriterTest
{
594 {0, 1, nil, io
.ErrShortWrite
},
595 {1, 2, nil, io
.ErrShortWrite
},
597 {0, 1, io
.ErrClosedPipe
, io
.ErrClosedPipe
},
598 {1, 2, io
.ErrClosedPipe
, io
.ErrClosedPipe
},
599 {1, 1, io
.ErrClosedPipe
, io
.ErrClosedPipe
},
602 func TestWriteErrors(t
*testing
.T
) {
603 for _
, w
:= range errorWriterTests
{
605 _
, e
:= buf
.Write([]byte("hello world"))
607 t
.Errorf("Write hello to %v: %v", w
, e
)
610 // Two flushes, to verify the error is sticky.
611 for i
:= 0; i
< 2; i
++ {
614 t
.Errorf("Flush %d/2 %v: got %v, wanted %v", i
+1, w
, e
, w
.expect
)
620 func TestNewReaderSizeIdempotent(t
*testing
.T
) {
622 b
:= NewReaderSize(strings
.NewReader("hello world"), BufSize
)
623 // Does it recognize itself?
624 b1
:= NewReaderSize(b
, BufSize
)
626 t
.Error("NewReaderSize did not detect underlying Reader")
628 // Does it wrap if existing buffer is too small?
629 b2
:= NewReaderSize(b
, 2*BufSize
)
631 t
.Error("NewReaderSize did not enlarge buffer")
635 func TestNewWriterSizeIdempotent(t
*testing
.T
) {
637 b
:= NewWriterSize(new(bytes
.Buffer
), BufSize
)
638 // Does it recognize itself?
639 b1
:= NewWriterSize(b
, BufSize
)
641 t
.Error("NewWriterSize did not detect underlying Writer")
643 // Does it wrap if existing buffer is too small?
644 b2
:= NewWriterSize(b
, 2*BufSize
)
646 t
.Error("NewWriterSize did not enlarge buffer")
650 func TestWriteString(t
*testing
.T
) {
652 buf
:= new(bytes
.Buffer
)
653 b
:= NewWriterSize(buf
, BufSize
)
654 b
.WriteString("0") // easy
655 b
.WriteString("123456") // still easy
656 b
.WriteString("7890") // easy after flush
657 b
.WriteString("abcdefghijklmnopqrstuvwxy") // hard
659 if err
:= b
.Flush(); err
!= nil {
660 t
.Error("WriteString", err
)
662 s
:= "01234567890abcdefghijklmnopqrstuvwxyz"
663 if string(buf
.Bytes()) != s
{
664 t
.Errorf("WriteString wants %q gets %q", s
, string(buf
.Bytes()))
668 func TestBufferFull(t
*testing
.T
) {
669 const longString
= "And now, hello, world! It is the time for all good men to come to the aid of their party"
670 buf
:= NewReaderSize(strings
.NewReader(longString
), minReadBufferSize
)
671 line
, err
:= buf
.ReadSlice('!')
672 if string(line
) != "And now, hello, " || err
!= ErrBufferFull
{
673 t
.Errorf("first ReadSlice(,) = %q, %v", line
, err
)
675 line
, err
= buf
.ReadSlice('!')
676 if string(line
) != "world!" || err
!= nil {
677 t
.Errorf("second ReadSlice(,) = %q, %v", line
, err
)
681 func TestPeek(t
*testing
.T
) {
682 p
:= make([]byte, 10)
683 // string is 16 (minReadBufferSize) long.
684 buf
:= NewReaderSize(strings
.NewReader("abcdefghijklmnop"), minReadBufferSize
)
685 if s
, err
:= buf
.Peek(1); string(s
) != "a" || err
!= nil {
686 t
.Fatalf("want %q got %q, err=%v", "a", string(s
), err
)
688 if s
, err
:= buf
.Peek(4); string(s
) != "abcd" || err
!= nil {
689 t
.Fatalf("want %q got %q, err=%v", "abcd", string(s
), err
)
691 if _
, err
:= buf
.Peek(-1); err
!= ErrNegativeCount
{
692 t
.Fatalf("want ErrNegativeCount got %v", err
)
694 if s
, err
:= buf
.Peek(32); string(s
) != "abcdefghijklmnop" || err
!= ErrBufferFull
{
695 t
.Fatalf("want %q, ErrBufFull got %q, err=%v", "abcdefghijklmnop", string(s
), err
)
697 if _
, err
:= buf
.Read(p
[0:3]); string(p
[0:3]) != "abc" || err
!= nil {
698 t
.Fatalf("want %q got %q, err=%v", "abc", string(p
[0:3]), err
)
700 if s
, err
:= buf
.Peek(1); string(s
) != "d" || err
!= nil {
701 t
.Fatalf("want %q got %q, err=%v", "d", string(s
), err
)
703 if s
, err
:= buf
.Peek(2); string(s
) != "de" || err
!= nil {
704 t
.Fatalf("want %q got %q, err=%v", "de", string(s
), err
)
706 if _
, err
:= buf
.Read(p
[0:3]); string(p
[0:3]) != "def" || err
!= nil {
707 t
.Fatalf("want %q got %q, err=%v", "def", string(p
[0:3]), err
)
709 if s
, err
:= buf
.Peek(4); string(s
) != "ghij" || err
!= nil {
710 t
.Fatalf("want %q got %q, err=%v", "ghij", string(s
), err
)
712 if _
, err
:= buf
.Read(p
[0:]); string(p
[0:]) != "ghijklmnop" || err
!= nil {
713 t
.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p
[0:minReadBufferSize
]), err
)
715 if s
, err
:= buf
.Peek(0); string(s
) != "" || err
!= nil {
716 t
.Fatalf("want %q got %q, err=%v", "", string(s
), err
)
718 if _
, err
:= buf
.Peek(1); err
!= io
.EOF
{
719 t
.Fatalf("want EOF got %v", err
)
722 // Test for issue 3022, not exposing a reader's error on a successful Peek.
723 buf
= NewReaderSize(dataAndEOFReader("abcd"), 32)
724 if s
, err
:= buf
.Peek(2); string(s
) != "ab" || err
!= nil {
725 t
.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s
), err
)
727 if s
, err
:= buf
.Peek(4); string(s
) != "abcd" || err
!= nil {
728 t
.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s
), err
)
730 if n
, err
:= buf
.Read(p
[0:5]); string(p
[0:n
]) != "abcd" || err
!= nil {
731 t
.Fatalf("Read after peek = %q, %v; want abcd, EOF", p
[0:n
], err
)
733 if n
, err
:= buf
.Read(p
[0:1]); string(p
[0:n
]) != "" || err
!= io
.EOF
{
734 t
.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p
[0:n
], err
)
738 type dataAndEOFReader
string
740 func (r dataAndEOFReader
) Read(p
[]byte) (int, error
) {
741 return copy(p
, r
), io
.EOF
744 func TestPeekThenUnreadRune(t
*testing
.T
) {
745 // This sequence used to cause a crash.
746 r
:= NewReader(strings
.NewReader("x"))
750 r
.ReadRune() // Used to panic here
753 var testOutput
= []byte("0123456789abcdefghijklmnopqrstuvwxy")
754 var testInput
= []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")
755 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")
757 // TestReader wraps a []byte and returns reads of a specific length.
758 type testReader
struct {
763 func (t
*testReader
) Read(buf
[]byte) (n
int, err error
) {
773 if len(t
.data
) == 0 {
779 func testReadLine(t
*testing
.T
, input
[]byte) {
780 //for stride := 1; stride < len(input); stride++ {
781 for stride
:= 1; stride
< 2; stride
++ {
783 reader
:= testReader
{input
, stride
}
784 l
:= NewReaderSize(&reader
, len(input
)+1)
786 line
, isPrefix
, err
:= l
.ReadLine()
787 if len(line
) > 0 && err
!= nil {
788 t
.Errorf("ReadLine returned both data and error: %s", err
)
791 t
.Errorf("ReadLine returned prefix")
795 t
.Fatalf("Got unknown error: %s", err
)
799 if want
:= testOutput
[done
: done
+len(line
)]; !bytes
.Equal(want
, line
) {
800 t
.Errorf("Bad line at stride %d: want: %x got: %x", stride
, want
, line
)
804 if done
!= len(testOutput
) {
805 t
.Errorf("ReadLine didn't return everything: got: %d, want: %d (stride: %d)", done
, len(testOutput
), stride
)
810 func TestReadLine(t
*testing
.T
) {
811 testReadLine(t
, testInput
)
812 testReadLine(t
, testInputrn
)
815 func TestLineTooLong(t
*testing
.T
) {
816 data
:= make([]byte, 0)
817 for i
:= 0; i
< minReadBufferSize
*5/2; i
++ {
818 data
= append(data
, '0'+byte(i%10
))
820 buf
:= bytes
.NewReader(data
)
821 l
:= NewReaderSize(buf
, minReadBufferSize
)
822 line
, isPrefix
, err
:= l
.ReadLine()
823 if !isPrefix ||
!bytes
.Equal(line
, data
[:minReadBufferSize
]) || err
!= nil {
824 t
.Errorf("bad result for first line: got %q want %q %v", line
, data
[:minReadBufferSize
], err
)
826 data
= data
[len(line
):]
827 line
, isPrefix
, err
= l
.ReadLine()
828 if !isPrefix ||
!bytes
.Equal(line
, data
[:minReadBufferSize
]) || err
!= nil {
829 t
.Errorf("bad result for second line: got %q want %q %v", line
, data
[:minReadBufferSize
], err
)
831 data
= data
[len(line
):]
832 line
, isPrefix
, err
= l
.ReadLine()
833 if isPrefix ||
!bytes
.Equal(line
, data
[:minReadBufferSize
/2]) || err
!= nil {
834 t
.Errorf("bad result for third line: got %q want %q %v", line
, data
[:minReadBufferSize
/2], err
)
836 line
, isPrefix
, err
= l
.ReadLine()
837 if isPrefix || err
== nil {
838 t
.Errorf("expected no more lines: %x %s", line
, err
)
842 func TestReadAfterLines(t
*testing
.T
) {
843 line1
:= "this is line1"
844 restData
:= "this is line2\nthis is line 3\n"
845 inbuf
:= bytes
.NewReader([]byte(line1
+ "\n" + restData
))
846 outbuf
:= new(bytes
.Buffer
)
847 maxLineLength
:= len(line1
) + len(restData
)/2
848 l
:= NewReaderSize(inbuf
, maxLineLength
)
849 line
, isPrefix
, err
:= l
.ReadLine()
850 if isPrefix || err
!= nil ||
string(line
) != line1
{
851 t
.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix
, err
, string(line
))
853 n
, err
:= io
.Copy(outbuf
, l
)
854 if int(n
) != len(restData
) || err
!= nil {
855 t
.Errorf("bad result for Read: n=%d err=%v", n
, err
)
857 if outbuf
.String() != restData
{
858 t
.Errorf("bad result for Read: got %q; expected %q", outbuf
.String(), restData
)
862 func TestReadEmptyBuffer(t
*testing
.T
) {
863 l
:= NewReaderSize(new(bytes
.Buffer
), minReadBufferSize
)
864 line
, isPrefix
, err
:= l
.ReadLine()
866 t
.Errorf("expected EOF from ReadLine, got '%s' %t %s", line
, isPrefix
, err
)
870 func TestLinesAfterRead(t
*testing
.T
) {
871 l
:= NewReaderSize(bytes
.NewReader([]byte("foo")), minReadBufferSize
)
872 _
, err
:= ioutil
.ReadAll(l
)
878 line
, isPrefix
, err
:= l
.ReadLine()
880 t
.Errorf("expected EOF from ReadLine, got '%s' %t %s", line
, isPrefix
, err
)
884 func TestReadLineNonNilLineOrError(t
*testing
.T
) {
885 r
:= NewReader(strings
.NewReader("line 1\n"))
886 for i
:= 0; i
< 2; i
++ {
887 l
, _
, err
:= r
.ReadLine()
888 if l
!= nil && err
!= nil {
889 t
.Fatalf("on line %d/2; ReadLine=%#v, %v; want non-nil line or Error, but not both",
895 type readLineResult
struct {
901 var readLineNewlinesTests
= []struct {
903 expect
[]readLineResult
905 {"012345678901234\r\n012345678901234\r\n", []readLineResult
{
906 {[]byte("012345678901234"), true, nil},
908 {[]byte("012345678901234"), true, nil},
910 {nil, false, io
.EOF
},
912 {"0123456789012345\r012345678901234\r", []readLineResult
{
913 {[]byte("0123456789012345"), true, nil},
914 {[]byte("\r012345678901234"), true, nil},
915 {[]byte("\r"), false, nil},
916 {nil, false, io
.EOF
},
920 func TestReadLineNewlines(t
*testing
.T
) {
921 for _
, e
:= range readLineNewlinesTests
{
922 testReadLineNewlines(t
, e
.input
, e
.expect
)
926 func testReadLineNewlines(t
*testing
.T
, input
string, expect
[]readLineResult
) {
927 b
:= NewReaderSize(strings
.NewReader(input
), minReadBufferSize
)
928 for i
, e
:= range expect
{
929 line
, isPrefix
, err
:= b
.ReadLine()
930 if !bytes
.Equal(line
, e
.line
) {
931 t
.Errorf("%q call %d, line == %q, want %q", input
, i
, line
, e
.line
)
934 if isPrefix
!= e
.isPrefix
{
935 t
.Errorf("%q call %d, isPrefix == %v, want %v", input
, i
, isPrefix
, e
.isPrefix
)
939 t
.Errorf("%q call %d, err == %v, want %v", input
, i
, err
, e
.err
)
945 func createTestInput(n
int) []byte {
946 input
:= make([]byte, n
)
947 for i
:= range input
{
948 // 101 and 251 are arbitrary prime numbers.
949 // The idea is to create an input sequence
950 // which doesn't repeat too frequently.
951 input
[i
] = byte(i
% 251)
953 input
[i
] ^= byte(i
/ 101)
959 func TestReaderWriteTo(t
*testing
.T
) {
960 input
:= createTestInput(8192)
961 r
:= NewReader(onlyReader
{bytes
.NewReader(input
)})
962 w
:= new(bytes
.Buffer
)
963 if n
, err
:= r
.WriteTo(w
); err
!= nil || n
!= int64(len(input
)) {
964 t
.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n
, err
, len(input
))
967 for i
, val
:= range w
.Bytes() {
969 t
.Errorf("after write: out[%d] = %#x, want %#x", i
, val
, input
[i
])
974 type errorWriterToTest
struct {
980 func (r errorWriterToTest
) Read(p
[]byte) (int, error
) {
981 return len(p
) * r
.rn
, r
.rerr
984 func (w errorWriterToTest
) Write(p
[]byte) (int, error
) {
985 return len(p
) * w
.wn
, w
.werr
988 var errorWriterToTests
= []errorWriterToTest
{
989 {1, 0, nil, io
.ErrClosedPipe
, io
.ErrClosedPipe
},
990 {0, 1, io
.ErrClosedPipe
, nil, io
.ErrClosedPipe
},
991 {0, 0, io
.ErrUnexpectedEOF
, io
.ErrClosedPipe
, io
.ErrClosedPipe
},
992 {0, 1, io
.EOF
, nil, nil},
995 func TestReaderWriteToErrors(t
*testing
.T
) {
996 for i
, rw
:= range errorWriterToTests
{
998 if _
, err
:= r
.WriteTo(rw
); err
!= rw
.expected
{
999 t
.Errorf("r.WriteTo(errorWriterToTests[%d]) = _, %v, want _,%v", i
, err
, rw
.expected
)
1004 func TestWriterReadFrom(t
*testing
.T
) {
1005 ws
:= []func(io
.Writer
) io
.Writer
{
1006 func(w io
.Writer
) io
.Writer
{ return onlyWriter
{w
} },
1007 func(w io
.Writer
) io
.Writer
{ return w
},
1010 rs
:= []func(io
.Reader
) io
.Reader
{
1011 iotest
.DataErrReader
,
1012 func(r io
.Reader
) io
.Reader
{ return r
},
1015 for ri
, rfunc
:= range rs
{
1016 for wi
, wfunc
:= range ws
{
1017 input
:= createTestInput(8192)
1018 b
:= new(bytes
.Buffer
)
1019 w
:= NewWriter(wfunc(b
))
1020 r
:= rfunc(bytes
.NewReader(input
))
1021 if n
, err
:= w
.ReadFrom(r
); err
!= nil || n
!= int64(len(input
)) {
1022 t
.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi
, ri
, n
, err
, len(input
))
1025 if err
:= w
.Flush(); err
!= nil {
1026 t
.Errorf("Flush returned %v", err
)
1029 if got
, want
:= b
.String(), string(input
); got
!= want
{
1030 t
.Errorf("ws[%d], rs[%d]:\ngot %q\nwant %q\n", wi
, ri
, got
, want
)
1036 type errorReaderFromTest
struct {
1042 func (r errorReaderFromTest
) Read(p
[]byte) (int, error
) {
1043 return len(p
) * r
.rn
, r
.rerr
1046 func (w errorReaderFromTest
) Write(p
[]byte) (int, error
) {
1047 return len(p
) * w
.wn
, w
.werr
1050 var errorReaderFromTests
= []errorReaderFromTest
{
1051 {0, 1, io
.EOF
, nil, nil},
1052 {1, 1, io
.EOF
, nil, nil},
1053 {0, 1, io
.ErrClosedPipe
, nil, io
.ErrClosedPipe
},
1054 {0, 0, io
.ErrClosedPipe
, io
.ErrShortWrite
, io
.ErrClosedPipe
},
1055 {1, 0, nil, io
.ErrShortWrite
, io
.ErrShortWrite
},
1058 func TestWriterReadFromErrors(t
*testing
.T
) {
1059 for i
, rw
:= range errorReaderFromTests
{
1061 if _
, err
:= w
.ReadFrom(rw
); err
!= rw
.expected
{
1062 t
.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v, want _,%v", i
, err
, rw
.expected
)
1067 // TestWriterReadFromCounts tests that using io.Copy to copy into a
1068 // bufio.Writer does not prematurely flush the buffer. For example, when
1069 // buffering writes to a network socket, excessive network writes should be
1071 func TestWriterReadFromCounts(t
*testing
.T
) {
1072 var w0 writeCountingDiscard
1073 b0
:= NewWriterSize(&w0
, 1234)
1074 b0
.WriteString(strings
.Repeat("x", 1000))
1076 t
.Fatalf("write 1000 'x's: got %d writes, want 0", w0
)
1078 b0
.WriteString(strings
.Repeat("x", 200))
1080 t
.Fatalf("write 1200 'x's: got %d writes, want 0", w0
)
1082 io
.Copy(b0
, onlyReader
{strings
.NewReader(strings
.Repeat("x", 30))})
1084 t
.Fatalf("write 1230 'x's: got %d writes, want 0", w0
)
1086 io
.Copy(b0
, onlyReader
{strings
.NewReader(strings
.Repeat("x", 9))})
1088 t
.Fatalf("write 1239 'x's: got %d writes, want 1", w0
)
1091 var w1 writeCountingDiscard
1092 b1
:= NewWriterSize(&w1
, 1234)
1093 b1
.WriteString(strings
.Repeat("x", 1200))
1096 t
.Fatalf("flush 1200 'x's: got %d writes, want 1", w1
)
1098 b1
.WriteString(strings
.Repeat("x", 89))
1100 t
.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1
)
1102 io
.Copy(b1
, onlyReader
{strings
.NewReader(strings
.Repeat("x", 700))})
1104 t
.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1
)
1106 io
.Copy(b1
, onlyReader
{strings
.NewReader(strings
.Repeat("x", 600))})
1108 t
.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1
)
1112 t
.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1
)
1116 // A writeCountingDiscard is like ioutil.Discard and counts the number of times
1117 // Write is called on it.
1118 type writeCountingDiscard
int
1120 func (w
*writeCountingDiscard
) Write(p
[]byte) (int, error
) {
1125 type negativeReader
int
1127 func (r
*negativeReader
) Read([]byte) (int, error
) { return -1, nil }
1129 func TestNegativeRead(t
*testing
.T
) {
1130 // should panic with a description pointing at the reader, not at itself.
1131 // (should NOT panic with slice index error, for example.)
1132 b
:= NewReader(new(negativeReader
))
1134 switch err
:= recover().(type) {
1136 t
.Fatal("read did not panic")
1138 if !strings
.Contains(err
.Error(), "reader returned negative count from Read") {
1139 t
.Fatalf("wrong panic: %v", err
)
1142 t
.Fatalf("unexpected panic value: %T(%v)", err
, err
)
1145 b
.Read(make([]byte, 100))
1148 var errFake
= errors
.New("fake error")
1150 type errorThenGoodReader
struct {
1155 func (r
*errorThenGoodReader
) Read(p
[]byte) (int, error
) {
1164 func TestReaderClearError(t
*testing
.T
) {
1165 r
:= &errorThenGoodReader
{}
1167 buf
:= make([]byte, 1)
1168 if _
, err
:= b
.Read(nil); err
!= nil {
1169 t
.Fatalf("1st nil Read = %v; want nil", err
)
1171 if _
, err
:= b
.Read(buf
); err
!= errFake
{
1172 t
.Fatalf("1st Read = %v; want errFake", err
)
1174 if _
, err
:= b
.Read(nil); err
!= nil {
1175 t
.Fatalf("2nd nil Read = %v; want nil", err
)
1177 if _
, err
:= b
.Read(buf
); err
!= nil {
1178 t
.Fatalf("3rd Read with buffer = %v; want nil", err
)
1181 t
.Errorf("num reads = %d; want 2", r
.nread
)
1185 // Test for golang.org/issue/5947
1186 func TestWriterReadFromWhileFull(t
*testing
.T
) {
1187 buf
:= new(bytes
.Buffer
)
1188 w
:= NewWriterSize(buf
, 10)
1190 // Fill buffer exactly.
1191 n
, err
:= w
.Write([]byte("0123456789"))
1192 if n
!= 10 || err
!= nil {
1193 t
.Fatalf("Write returned (%v, %v), want (10, nil)", n
, err
)
1196 // Use ReadFrom to read in some data.
1197 n2
, err
:= w
.ReadFrom(strings
.NewReader("abcdef"))
1198 if n2
!= 6 || err
!= nil {
1199 t
.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n2
, err
)
1203 type emptyThenNonEmptyReader
struct {
1208 func (r
*emptyThenNonEmptyReader
) Read(p
[]byte) (int, error
) {
1216 // Test for golang.org/issue/7611
1217 func TestWriterReadFromUntilEOF(t
*testing
.T
) {
1218 buf
:= new(bytes
.Buffer
)
1219 w
:= NewWriterSize(buf
, 5)
1221 // Partially fill buffer
1222 n
, err
:= w
.Write([]byte("0123"))
1223 if n
!= 4 || err
!= nil {
1224 t
.Fatalf("Write returned (%v, %v), want (4, nil)", n
, err
)
1227 // Use ReadFrom to read in some data.
1228 r
:= &emptyThenNonEmptyReader
{r
: strings
.NewReader("abcd"), n
: 3}
1229 n2
, err
:= w
.ReadFrom(r
)
1230 if n2
!= 4 || err
!= nil {
1231 t
.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2
, err
)
1234 if got
, want
:= string(buf
.Bytes()), "0123abcd"; got
!= want
{
1235 t
.Fatalf("buf.Bytes() returned %q, want %q", got
, want
)
1239 func TestWriterReadFromErrNoProgress(t
*testing
.T
) {
1240 buf
:= new(bytes
.Buffer
)
1241 w
:= NewWriterSize(buf
, 5)
1243 // Partially fill buffer
1244 n
, err
:= w
.Write([]byte("0123"))
1245 if n
!= 4 || err
!= nil {
1246 t
.Fatalf("Write returned (%v, %v), want (4, nil)", n
, err
)
1249 // Use ReadFrom to read in some data.
1250 r
:= &emptyThenNonEmptyReader
{r
: strings
.NewReader("abcd"), n
: 100}
1251 n2
, err
:= w
.ReadFrom(r
)
1252 if n2
!= 0 || err
!= io
.ErrNoProgress
{
1253 t
.Fatalf("buf.Bytes() returned (%v, %v), want (0, io.ErrNoProgress)", n2
, err
)
1257 func TestReadZero(t
*testing
.T
) {
1258 for _
, size
:= range []int{100, 2} {
1259 t
.Run(fmt
.Sprintf("bufsize=%d", size
), func(t
*testing
.T
) {
1260 r
:= io
.MultiReader(strings
.NewReader("abc"), &emptyThenNonEmptyReader
{r
: strings
.NewReader("def"), n
: 1})
1261 br
:= NewReaderSize(r
, size
)
1262 want
:= func(s
string, wantErr error
) {
1263 p
:= make([]byte, 50)
1264 n
, err
:= br
.Read(p
)
1265 if err
!= wantErr || n
!= len(s
) ||
string(p
[:n
]) != s
{
1266 t
.Fatalf("read(%d) = %q, %v, want %q, %v", len(p
), string(p
[:n
]), err
, s
, wantErr
)
1268 t
.Logf("read(%d) = %q, %v", len(p
), string(p
[:n
]), err
)
1278 func TestReaderReset(t
*testing
.T
) {
1279 r
:= NewReader(strings
.NewReader("foo foo"))
1280 buf
:= make([]byte, 3)
1282 if string(buf
) != "foo" {
1283 t
.Errorf("buf = %q; want foo", buf
)
1285 r
.Reset(strings
.NewReader("bar bar"))
1286 all
, err
:= ioutil
.ReadAll(r
)
1290 if string(all
) != "bar bar" {
1291 t
.Errorf("ReadAll = %q; want bar bar", all
)
1295 func TestWriterReset(t
*testing
.T
) {
1296 var buf1
, buf2 bytes
.Buffer
1297 w
:= NewWriter(&buf1
)
1298 w
.WriteString("foo")
1299 w
.Reset(&buf2
) // and not flushed
1300 w
.WriteString("bar")
1302 if buf1
.String() != "" {
1303 t
.Errorf("buf1 = %q; want empty", buf1
.String())
1305 if buf2
.String() != "bar" {
1306 t
.Errorf("buf2 = %q; want bar", buf2
.String())
1310 func TestReaderDiscard(t
*testing
.T
) {
1314 bufSize
int // 0 means 16
1317 n
int // input to Discard
1319 want
int // from Discard
1320 wantErr error
// from Discard
1325 name
: "normal case",
1326 r
: strings
.NewReader("abcdefghijklmnopqrstuvwxyz"),
1333 name
: "discard causing read",
1334 r
: strings
.NewReader("abcdefghijklmnopqrstuvwxyz"),
1340 name
: "discard all without peek",
1341 r
: strings
.NewReader("abcdefghijklmnopqrstuvwxyz"),
1347 name
: "discard more than end",
1348 r
: strings
.NewReader("abcdefghijklmnopqrstuvwxyz"),
1354 // Any error from filling shouldn't show up until we
1355 // get past the valid bytes. Here we return we return 5 valid bytes at the same time
1356 // as an error, but test that we don't see the error from Discard.
1358 name
: "fill error, discard less",
1359 r
: newScriptedReader(func(p
[]byte) (n
int, err error
) {
1361 panic("unexpected small read")
1363 return 5, errors
.New("5-then-error")
1371 name
: "fill error, discard equal",
1372 r
: newScriptedReader(func(p
[]byte) (n
int, err error
) {
1374 panic("unexpected small read")
1376 return 5, errors
.New("5-then-error")
1384 name
: "fill error, discard more",
1385 r
: newScriptedReader(func(p
[]byte) (n
int, err error
) {
1387 panic("unexpected small read")
1389 return 5, errors
.New("5-then-error")
1393 wantErr
: errors
.New("5-then-error"),
1396 // Discard of 0 shouldn't cause a read:
1398 name
: "discard zero",
1399 r
: newScriptedReader(), // will panic on Read
1406 name
: "discard negative",
1407 r
: newScriptedReader(), // will panic on Read
1410 wantErr
: ErrNegativeCount
,
1414 for _
, tt
:= range tests
{
1415 br
:= NewReaderSize(tt
.r
, tt
.bufSize
)
1416 if tt
.peekSize
> 0 {
1417 peekBuf
, err
:= br
.Peek(tt
.peekSize
)
1419 t
.Errorf("%s: Peek(%d): %v", tt
.name
, tt
.peekSize
, err
)
1422 if len(peekBuf
) != tt
.peekSize
{
1423 t
.Errorf("%s: len(Peek(%d)) = %v; want %v", tt
.name
, tt
.peekSize
, len(peekBuf
), tt
.peekSize
)
1427 discarded
, err
:= br
.Discard(tt
.n
)
1428 if ge
, we
:= fmt
.Sprint(err
), fmt
.Sprint(tt
.wantErr
); discarded
!= tt
.want || ge
!= we
{
1429 t
.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt
.name
, tt
.n
, discarded
, ge
, tt
.want
, we
)
1432 if bn
:= br
.Buffered(); bn
!= tt
.wantBuffered
{
1433 t
.Errorf("%s: after Discard, Buffered = %d; want %d", tt
.name
, bn
, tt
.wantBuffered
)
1439 func TestReaderSize(t
*testing
.T
) {
1440 if got
, want
:= NewReader(nil).Size(), DefaultBufSize
; got
!= want
{
1441 t
.Errorf("NewReader's Reader.Size = %d; want %d", got
, want
)
1443 if got
, want
:= NewReaderSize(nil, 1234).Size(), 1234; got
!= want
{
1444 t
.Errorf("NewReaderSize's Reader.Size = %d; want %d", got
, want
)
1448 func TestWriterSize(t
*testing
.T
) {
1449 if got
, want
:= NewWriter(nil).Size(), DefaultBufSize
; got
!= want
{
1450 t
.Errorf("NewWriter's Writer.Size = %d; want %d", got
, want
)
1452 if got
, want
:= NewWriterSize(nil, 1234).Size(), 1234; got
!= want
{
1453 t
.Errorf("NewWriterSize's Writer.Size = %d; want %d", got
, want
)
1457 // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
1458 type onlyReader
struct {
1462 // An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
1463 type onlyWriter
struct {
1467 // A scriptedReader is an io.Reader that executes its steps sequentially.
1468 type scriptedReader
[]func(p
[]byte) (n
int, err error
)
1470 func (sr
*scriptedReader
) Read(p
[]byte) (n
int, err error
) {
1472 panic("too many Read calls on scripted Reader. No steps remain.")
1479 func newScriptedReader(steps
...func(p
[]byte) (n
int, err error
)) io
.Reader
{
1480 sr
:= scriptedReader(steps
)
1484 // eofReader returns the number of bytes read and io.EOF for the read that consumes the last of the content.
1485 type eofReader
struct {
1489 func (r
*eofReader
) Read(p
[]byte) (int, error
) {
1490 read
:= copy(p
, r
.buf
)
1491 r
.buf
= r
.buf
[read
:]
1495 // As allowed in the documentation, this will return io.EOF
1496 // in the same call that consumes the last of the data.
1497 // https://godoc.org/io#Reader
1504 func TestPartialReadEOF(t
*testing
.T
) {
1505 src
:= make([]byte, 10)
1506 eofR
:= &eofReader
{buf
: src
}
1507 r
:= NewReader(eofR
)
1509 // Start by reading 5 of the 10 available bytes.
1510 dest
:= make([]byte, 5)
1511 read
, err
:= r
.Read(dest
)
1513 t
.Fatalf("unexpected error: %v", err
)
1515 if n
:= len(dest
); read
!= n
{
1516 t
.Fatalf("read %d bytes; wanted %d bytes", read
, n
)
1519 // The Reader should have buffered all the content from the io.Reader.
1520 if n
:= len(eofR
.buf
); n
!= 0 {
1521 t
.Fatalf("got %d bytes left in bufio.Reader source; want 0 bytes", n
)
1523 // To prove the point, check that there are still 5 bytes available to read.
1524 if n
:= r
.Buffered(); n
!= 5 {
1525 t
.Fatalf("got %d bytes buffered in bufio.Reader; want 5 bytes", n
)
1528 // This is the second read of 0 bytes.
1529 read
, err
= r
.Read([]byte{})
1531 t
.Fatalf("unexpected error: %v", err
)
1534 t
.Fatalf("read %d bytes; want 0 bytes", read
)
1538 type writerWithReadFromError
struct{}
1540 func (w writerWithReadFromError
) ReadFrom(r io
.Reader
) (int64, error
) {
1541 return 0, errors
.New("writerWithReadFromError error")
1544 func (w writerWithReadFromError
) Write(b
[]byte) (n
int, err error
) {
1548 func TestWriterReadFromMustSetUnderlyingError(t
*testing
.T
) {
1549 var wr
= NewWriter(writerWithReadFromError
{})
1550 if _
, err
:= wr
.ReadFrom(strings
.NewReader("test2")); err
== nil {
1551 t
.Fatal("expected ReadFrom returns error, got nil")
1553 if _
, err
:= wr
.Write([]byte("123")); err
== nil {
1554 t
.Fatal("expected Write returns error, got nil")
1558 type writeErrorOnlyWriter
struct{}
1560 func (w writeErrorOnlyWriter
) Write(p
[]byte) (n
int, err error
) {
1561 return 0, errors
.New("writeErrorOnlyWriter error")
1564 // Ensure that previous Write errors are immediately returned
1565 // on any ReadFrom. See golang.org/issue/35194.
1566 func TestWriterReadFromMustReturnUnderlyingError(t
*testing
.T
) {
1567 var wr
= NewWriter(writeErrorOnlyWriter
{})
1569 wantBuffered
:= len(s
)
1570 if _
, err
:= wr
.WriteString(s
); err
!= nil {
1571 t
.Fatalf("unexpected error: %v", err
)
1573 if err
:= wr
.Flush(); err
== nil {
1574 t
.Error("expected flush error, got nil")
1576 if _
, err
:= wr
.ReadFrom(strings
.NewReader("test2")); err
== nil {
1577 t
.Fatal("expected error, got nil")
1579 if buffered
:= wr
.Buffered(); buffered
!= wantBuffered
{
1580 t
.Fatalf("Buffered = %v; want %v", buffered
, wantBuffered
)
1584 func BenchmarkReaderCopyOptimal(b
*testing
.B
) {
1585 // Optimal case is where the underlying reader implements io.WriterTo
1586 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1587 src
:= NewReader(srcBuf
)
1588 dstBuf
:= new(bytes
.Buffer
)
1589 dst
:= onlyWriter
{dstBuf
}
1590 for i
:= 0; i
< b
.N
; i
++ {
1598 func BenchmarkReaderCopyUnoptimal(b
*testing
.B
) {
1599 // Unoptimal case is where the underlying reader doesn't implement io.WriterTo
1600 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1601 src
:= NewReader(onlyReader
{srcBuf
})
1602 dstBuf
:= new(bytes
.Buffer
)
1603 dst
:= onlyWriter
{dstBuf
}
1604 for i
:= 0; i
< b
.N
; i
++ {
1606 src
.Reset(onlyReader
{srcBuf
})
1612 func BenchmarkReaderCopyNoWriteTo(b
*testing
.B
) {
1613 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1614 srcReader
:= NewReader(srcBuf
)
1615 src
:= onlyReader
{srcReader
}
1616 dstBuf
:= new(bytes
.Buffer
)
1617 dst
:= onlyWriter
{dstBuf
}
1618 for i
:= 0; i
< b
.N
; i
++ {
1620 srcReader
.Reset(srcBuf
)
1626 func BenchmarkReaderWriteToOptimal(b
*testing
.B
) {
1627 const bufSize
= 16 << 10
1628 buf
:= make([]byte, bufSize
)
1629 r
:= bytes
.NewReader(buf
)
1630 srcReader
:= NewReaderSize(onlyReader
{r
}, 1<<10)
1631 if _
, ok
:= ioutil
.Discard
.(io
.ReaderFrom
); !ok
{
1632 b
.Fatal("ioutil.Discard doesn't support ReaderFrom")
1634 for i
:= 0; i
< b
.N
; i
++ {
1635 r
.Seek(0, io
.SeekStart
)
1636 srcReader
.Reset(onlyReader
{r
})
1637 n
, err
:= srcReader
.WriteTo(ioutil
.Discard
)
1642 b
.Fatalf("n = %d; want %d", n
, bufSize
)
1647 func BenchmarkWriterCopyOptimal(b
*testing
.B
) {
1648 // Optimal case is where the underlying writer implements io.ReaderFrom
1649 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1650 src
:= onlyReader
{srcBuf
}
1651 dstBuf
:= new(bytes
.Buffer
)
1652 dst
:= NewWriter(dstBuf
)
1653 for i
:= 0; i
< b
.N
; i
++ {
1661 func BenchmarkWriterCopyUnoptimal(b
*testing
.B
) {
1662 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1663 src
:= onlyReader
{srcBuf
}
1664 dstBuf
:= new(bytes
.Buffer
)
1665 dst
:= NewWriter(onlyWriter
{dstBuf
})
1666 for i
:= 0; i
< b
.N
; i
++ {
1669 dst
.Reset(onlyWriter
{dstBuf
})
1674 func BenchmarkWriterCopyNoReadFrom(b
*testing
.B
) {
1675 srcBuf
:= bytes
.NewBuffer(make([]byte, 8192))
1676 src
:= onlyReader
{srcBuf
}
1677 dstBuf
:= new(bytes
.Buffer
)
1678 dstWriter
:= NewWriter(dstBuf
)
1679 dst
:= onlyWriter
{dstWriter
}
1680 for i
:= 0; i
< b
.N
; i
++ {
1683 dstWriter
.Reset(dstBuf
)
1688 func BenchmarkReaderEmpty(b
*testing
.B
) {
1690 str
:= strings
.Repeat("x", 16<<10)
1691 for i
:= 0; i
< b
.N
; i
++ {
1692 br
:= NewReader(strings
.NewReader(str
))
1693 n
, err
:= io
.Copy(ioutil
.Discard
, br
)
1697 if n
!= int64(len(str
)) {
1698 b
.Fatal("wrong length")
1703 func BenchmarkWriterEmpty(b
*testing
.B
) {
1705 str
:= strings
.Repeat("x", 1<<10)
1707 for i
:= 0; i
< b
.N
; i
++ {
1708 bw
:= NewWriter(ioutil
.Discard
)
1721 func BenchmarkWriterFlush(b
*testing
.B
) {
1723 bw
:= NewWriter(ioutil
.Discard
)
1724 str
:= strings
.Repeat("x", 50)
1725 for i
:= 0; i
< b
.N
; i
++ {