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.
16 // An version of bytes.Buffer without ReadFrom and WriteTo
19 ReaderFrom
// conflicts with and hides bytes.Buffer's ReaderFrom.
20 WriterTo
// conflicts with and hides bytes.Buffer's WriterTo.
23 // Simple tests, primarily to verify the ReadFrom and WriteTo callouts inside Copy and CopyN.
25 func TestCopy(t
*testing
.T
) {
28 rb
.WriteString("hello, world.")
30 if wb
.String() != "hello, world." {
31 t
.Errorf("Copy did not work properly")
35 func TestCopyReadFrom(t
*testing
.T
) {
37 wb
:= new(bytes
.Buffer
) // implements ReadFrom.
38 rb
.WriteString("hello, world.")
40 if wb
.String() != "hello, world." {
41 t
.Errorf("Copy did not work properly")
45 func TestCopyWriteTo(t
*testing
.T
) {
46 rb
:= new(bytes
.Buffer
) // implements WriteTo.
48 rb
.WriteString("hello, world.")
50 if wb
.String() != "hello, world." {
51 t
.Errorf("Copy did not work properly")
55 // Version of bytes.Buffer that checks whether WriteTo was called or not
56 type writeToChecker
struct {
61 func (wt
*writeToChecker
) WriteTo(w Writer
) (int64, error
) {
62 wt
.writeToCalled
= true
63 return wt
.Buffer
.WriteTo(w
)
66 // It's preferable to choose WriterTo over ReaderFrom, since a WriterTo can issue one large write,
67 // while the ReaderFrom must read until EOF, potentially allocating when running out of buffer.
68 // Make sure that we choose WriterTo when both are implemented.
69 func TestCopyPriority(t
*testing
.T
) {
70 rb
:= new(writeToChecker
)
71 wb
:= new(bytes
.Buffer
)
72 rb
.WriteString("hello, world.")
74 if wb
.String() != "hello, world." {
75 t
.Errorf("Copy did not work properly")
76 } else if !rb
.writeToCalled
{
77 t
.Errorf("WriteTo was not prioritized over ReadFrom")
81 func TestCopyN(t
*testing
.T
) {
84 rb
.WriteString("hello, world.")
86 if wb
.String() != "hello" {
87 t
.Errorf("CopyN did not work properly")
91 func TestCopyNReadFrom(t
*testing
.T
) {
93 wb
:= new(bytes
.Buffer
) // implements ReadFrom.
94 rb
.WriteString("hello")
96 if wb
.String() != "hello" {
97 t
.Errorf("CopyN did not work properly")
101 func TestCopyNWriteTo(t
*testing
.T
) {
102 rb
:= new(bytes
.Buffer
) // implements WriteTo.
104 rb
.WriteString("hello, world.")
106 if wb
.String() != "hello" {
107 t
.Errorf("CopyN did not work properly")
111 type noReadFrom
struct {
115 func (w
*noReadFrom
) Write(p
[]byte) (n
int, err error
) {
119 type wantedAndErrReader
struct{}
121 func (wantedAndErrReader
) Read(p
[]byte) (int, error
) {
122 return len(p
), errors
.New("wantedAndErrReader error")
125 func TestCopyNEOF(t
*testing
.T
) {
126 // Test that EOF behavior is the same regardless of whether
127 // argument to CopyN has ReadFrom.
129 b
:= new(bytes
.Buffer
)
131 n
, err
:= CopyN(&noReadFrom
{b
}, strings
.NewReader("foo"), 3)
132 if n
!= 3 || err
!= nil {
133 t
.Errorf("CopyN(noReadFrom, foo, 3) = %d, %v; want 3, nil", n
, err
)
136 n
, err
= CopyN(&noReadFrom
{b
}, strings
.NewReader("foo"), 4)
137 if n
!= 3 || err
!= EOF
{
138 t
.Errorf("CopyN(noReadFrom, foo, 4) = %d, %v; want 3, EOF", n
, err
)
141 n
, err
= CopyN(b
, strings
.NewReader("foo"), 3) // b has read from
142 if n
!= 3 || err
!= nil {
143 t
.Errorf("CopyN(bytes.Buffer, foo, 3) = %d, %v; want 3, nil", n
, err
)
146 n
, err
= CopyN(b
, strings
.NewReader("foo"), 4) // b has read from
147 if n
!= 3 || err
!= EOF
{
148 t
.Errorf("CopyN(bytes.Buffer, foo, 4) = %d, %v; want 3, EOF", n
, err
)
151 n
, err
= CopyN(b
, wantedAndErrReader
{}, 5)
152 if n
!= 5 || err
!= nil {
153 t
.Errorf("CopyN(bytes.Buffer, wantedAndErrReader, 5) = %d, %v; want 5, nil", n
, err
)
156 n
, err
= CopyN(&noReadFrom
{b
}, wantedAndErrReader
{}, 5)
157 if n
!= 5 || err
!= nil {
158 t
.Errorf("CopyN(noReadFrom, wantedAndErrReader, 5) = %d, %v; want 5, nil", n
, err
)
162 func TestReadAtLeast(t
*testing
.T
) {
164 testReadAtLeast(t
, &rb
)
167 // A version of bytes.Buffer that returns n > 0, err on Read
168 // when the input is exhausted.
169 type dataAndErrorBuffer
struct {
174 func (r
*dataAndErrorBuffer
) Read(p
[]byte) (n
int, err error
) {
175 n
, err
= r
.Buffer
.Read(p
)
176 if n
> 0 && r
.Buffer
.Len() == 0 && err
== nil {
182 func TestReadAtLeastWithDataAndEOF(t
*testing
.T
) {
183 var rb dataAndErrorBuffer
185 testReadAtLeast(t
, &rb
)
188 func TestReadAtLeastWithDataAndError(t
*testing
.T
) {
189 var rb dataAndErrorBuffer
190 rb
.err
= fmt
.Errorf("fake error")
191 testReadAtLeast(t
, &rb
)
194 func testReadAtLeast(t
*testing
.T
, rb ReadWriter
) {
195 rb
.Write([]byte("0123"))
196 buf
:= make([]byte, 2)
197 n
, err
:= ReadAtLeast(rb
, buf
, 2)
201 n
, err
= ReadAtLeast(rb
, buf
, 4)
202 if err
!= ErrShortBuffer
{
203 t
.Errorf("expected ErrShortBuffer got %v", err
)
206 t
.Errorf("expected to have read 0 bytes, got %v", n
)
208 n
, err
= ReadAtLeast(rb
, buf
, 1)
213 t
.Errorf("expected to have read 2 bytes, got %v", n
)
215 n
, err
= ReadAtLeast(rb
, buf
, 2)
217 t
.Errorf("expected EOF, got %v", err
)
220 t
.Errorf("expected to have read 0 bytes, got %v", n
)
222 rb
.Write([]byte("4"))
223 n
, err
= ReadAtLeast(rb
, buf
, 2)
224 want
:= ErrUnexpectedEOF
225 if rb
, ok
:= rb
.(*dataAndErrorBuffer
); ok
&& rb
.err
!= EOF
{
229 t
.Errorf("expected %v, got %v", want
, err
)
232 t
.Errorf("expected to have read 1 bytes, got %v", n
)
236 func TestTeeReader(t
*testing
.T
) {
237 src
:= []byte("hello, world")
238 dst
:= make([]byte, len(src
))
239 rb
:= bytes
.NewBuffer(src
)
240 wb
:= new(bytes
.Buffer
)
241 r
:= TeeReader(rb
, wb
)
242 if n
, err
:= ReadFull(r
, dst
); err
!= nil || n
!= len(src
) {
243 t
.Fatalf("ReadFull(r, dst) = %d, %v; want %d, nil", n
, err
, len(src
))
245 if !bytes
.Equal(dst
, src
) {
246 t
.Errorf("bytes read = %q want %q", dst
, src
)
248 if !bytes
.Equal(wb
.Bytes(), src
) {
249 t
.Errorf("bytes written = %q want %q", wb
.Bytes(), src
)
251 if n
, err
:= r
.Read(dst
); n
!= 0 || err
!= EOF
{
252 t
.Errorf("r.Read at EOF = %d, %v want 0, EOF", n
, err
)
254 rb
= bytes
.NewBuffer(src
)
257 r
= TeeReader(rb
, pw
)
258 if n
, err
:= ReadFull(r
, dst
); n
!= 0 || err
!= ErrClosedPipe
{
259 t
.Errorf("closed tee: ReadFull(r, dst) = %d, %v; want 0, EPIPE", n
, err
)
263 func TestSectionReader_ReadAt(t
*testing
.T
) {
264 dat
:= "a long sample data, 1234567890"
274 {data
: "", off
: 0, n
: 10, bufLen
: 2, at
: 0, exp
: "", err
: EOF
},
275 {data
: dat
, off
: 0, n
: len(dat
), bufLen
: 0, at
: 0, exp
: "", err
: nil},
276 {data
: dat
, off
: len(dat
), n
: 1, bufLen
: 1, at
: 0, exp
: "", err
: EOF
},
277 {data
: dat
, off
: 0, n
: len(dat
) + 2, bufLen
: len(dat
), at
: 0, exp
: dat
, err
: nil},
278 {data
: dat
, off
: 0, n
: len(dat
), bufLen
: len(dat
) / 2, at
: 0, exp
: dat
[:len(dat
)/2], err
: nil},
279 {data
: dat
, off
: 0, n
: len(dat
), bufLen
: len(dat
), at
: 0, exp
: dat
, err
: nil},
280 {data
: dat
, off
: 0, n
: len(dat
), bufLen
: len(dat
) / 2, at
: 2, exp
: dat
[2 : 2+len(dat
)/2], err
: nil},
281 {data
: dat
, off
: 3, n
: len(dat
), bufLen
: len(dat
) / 2, at
: 2, exp
: dat
[5 : 5+len(dat
)/2], err
: nil},
282 {data
: dat
, off
: 3, n
: len(dat
) / 2, bufLen
: len(dat
)/2 - 2, at
: 2, exp
: dat
[5 : 5+len(dat
)/2-2], err
: nil},
283 {data
: dat
, off
: 3, n
: len(dat
) / 2, bufLen
: len(dat
)/2 + 2, at
: 2, exp
: dat
[5 : 5+len(dat
)/2-2], err
: EOF
},
285 for i
, tt
:= range tests
{
286 r
:= strings
.NewReader(tt
.data
)
287 s
:= NewSectionReader(r
, int64(tt
.off
), int64(tt
.n
))
288 buf
:= make([]byte, tt
.bufLen
)
289 if n
, err
:= s
.ReadAt(buf
, int64(tt
.at
)); n
!= len(tt
.exp
) ||
string(buf
[:n
]) != tt
.exp || err
!= tt
.err
{
290 t
.Fatalf("%d: ReadAt(%d) = %q, %v; expected %q, %v", i
, tt
.at
, buf
[:n
], err
, tt
.exp
, tt
.err
)
295 func TestSectionReader_Seek(t
*testing
.T
) {
296 // Verifies that NewSectionReader's Seeker behaves like bytes.NewReader (which is like strings.NewReader)
297 br
:= bytes
.NewReader([]byte("foo"))
298 sr
:= NewSectionReader(br
, 0, int64(len("foo")))
300 for whence
:= 0; whence
<= 2; whence
++ {
301 for offset
:= int64(-3); offset
<= 4; offset
++ {
302 brOff
, brErr
:= br
.Seek(offset
, whence
)
303 srOff
, srErr
:= sr
.Seek(offset
, whence
)
304 if (brErr
!= nil) != (srErr
!= nil) || brOff
!= srOff
{
305 t
.Errorf("For whence %d, offset %d: bytes.Reader.Seek = (%v, %v) != SectionReader.Seek = (%v, %v)",
306 whence
, offset
, brOff
, brErr
, srErr
, srOff
)
311 // And verify we can just seek past the end and get an EOF
312 got
, err
:= sr
.Seek(100, 0)
313 if err
!= nil || got
!= 100 {
314 t
.Errorf("Seek = %v, %v; want 100, nil", got
, err
)
317 n
, err
:= sr
.Read(make([]byte, 10))
318 if n
!= 0 || err
!= EOF
{
319 t
.Errorf("Read = %v, %v; want 0, EOF", n
, err
)