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 const N
= 10000 // make this bigger for a larger (and slower) test
17 var testString
string // test data for write tests
18 var testBytes
[]byte // test data; same as testString but as a slice.
20 type negativeReader
struct{}
22 func (r
*negativeReader
) Read([]byte) (int, error
) { return -1, nil }
25 testBytes
= make([]byte, N
)
26 for i
:= 0; i
< N
; i
++ {
27 testBytes
[i
] = 'a' + byte(i%26
)
29 testString
= string(testBytes
)
32 // Verify that contents of buf match the string s.
33 func check(t
*testing
.T
, testname
string, buf
*Buffer
, s
string) {
36 if buf
.Len() != len(bytes
) {
37 t
.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname
, buf
.Len(), len(bytes
))
40 if buf
.Len() != len(str
) {
41 t
.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname
, buf
.Len(), len(str
))
44 if buf
.Len() != len(s
) {
45 t
.Errorf("%s: buf.Len() == %d, len(s) == %d", testname
, buf
.Len(), len(s
))
48 if string(bytes
) != s
{
49 t
.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname
, string(bytes
), s
)
53 // Fill buf through n writes of string fus.
54 // The initial contents of buf corresponds to the string s;
55 // the result is the final contents of buf returned as a string.
56 func fillString(t
*testing
.T
, testname
string, buf
*Buffer
, s
string, n
int, fus
string) string {
57 check(t
, testname
+" (fill 1)", buf
, s
)
59 m
, err
:= buf
.WriteString(fus
)
61 t
.Errorf(testname
+" (fill 2): m == %d, expected %d", m
, len(fus
))
64 t
.Errorf(testname
+" (fill 3): err should always be nil, found err == %s", err
)
67 check(t
, testname
+" (fill 4)", buf
, s
)
72 // Fill buf through n writes of byte slice fub.
73 // The initial contents of buf corresponds to the string s;
74 // the result is the final contents of buf returned as a string.
75 func fillBytes(t
*testing
.T
, testname
string, buf
*Buffer
, s
string, n
int, fub
[]byte) string {
76 check(t
, testname
+" (fill 1)", buf
, s
)
78 m
, err
:= buf
.Write(fub
)
80 t
.Errorf(testname
+" (fill 2): m == %d, expected %d", m
, len(fub
))
83 t
.Errorf(testname
+" (fill 3): err should always be nil, found err == %s", err
)
86 check(t
, testname
+" (fill 4)", buf
, s
)
91 func TestNewBuffer(t
*testing
.T
) {
92 buf
:= NewBuffer(testBytes
)
93 check(t
, "NewBuffer", buf
, testString
)
96 func TestNewBufferString(t
*testing
.T
) {
97 buf
:= NewBufferString(testString
)
98 check(t
, "NewBufferString", buf
, testString
)
101 // Empty buf through repeated reads into fub.
102 // The initial contents of buf corresponds to the string s.
103 func empty(t
*testing
.T
, testname
string, buf
*Buffer
, s
string, fub
[]byte) {
104 check(t
, testname
+" (empty 1)", buf
, s
)
107 n
, err
:= buf
.Read(fub
)
112 t
.Errorf(testname
+" (empty 2): err should always be nil, found err == %s", err
)
115 check(t
, testname
+" (empty 3)", buf
, s
)
118 check(t
, testname
+" (empty 4)", buf
, "")
121 func TestBasicOperations(t
*testing
.T
) {
124 for i
:= 0; i
< 5; i
++ {
125 check(t
, "TestBasicOperations (1)", &buf
, "")
128 check(t
, "TestBasicOperations (2)", &buf
, "")
131 check(t
, "TestBasicOperations (3)", &buf
, "")
133 n
, err
:= buf
.Write(testBytes
[0:1])
135 t
.Errorf("wrote 1 byte, but n == %d", n
)
138 t
.Errorf("err should always be nil, but err == %s", err
)
140 check(t
, "TestBasicOperations (4)", &buf
, "a")
142 buf
.WriteByte(testString
[1])
143 check(t
, "TestBasicOperations (5)", &buf
, "ab")
145 n
, err
= buf
.Write(testBytes
[2:26])
147 t
.Errorf("wrote 24 bytes, but n == %d", n
)
149 check(t
, "TestBasicOperations (6)", &buf
, testString
[0:26])
152 check(t
, "TestBasicOperations (7)", &buf
, testString
[0:26])
155 check(t
, "TestBasicOperations (8)", &buf
, testString
[0:20])
157 empty(t
, "TestBasicOperations (9)", &buf
, testString
[0:20], make([]byte, 5))
158 empty(t
, "TestBasicOperations (10)", &buf
, "", make([]byte, 100))
160 buf
.WriteByte(testString
[1])
161 c
, err
:= buf
.ReadByte()
163 t
.Error("ReadByte unexpected eof")
165 if c
!= testString
[1] {
166 t
.Errorf("ReadByte wrong value c=%v", c
)
168 c
, err
= buf
.ReadByte()
170 t
.Error("ReadByte unexpected not eof")
175 func TestLargeStringWrites(t
*testing
.T
) {
181 for i
:= 3; i
< limit
; i
+= 3 {
182 s
:= fillString(t
, "TestLargeWrites (1)", &buf
, "", 5, testString
)
183 empty(t
, "TestLargeStringWrites (2)", &buf
, s
, make([]byte, len(testString
)/i
))
185 check(t
, "TestLargeStringWrites (3)", &buf
, "")
188 func TestLargeByteWrites(t
*testing
.T
) {
194 for i
:= 3; i
< limit
; i
+= 3 {
195 s
:= fillBytes(t
, "TestLargeWrites (1)", &buf
, "", 5, testBytes
)
196 empty(t
, "TestLargeByteWrites (2)", &buf
, s
, make([]byte, len(testString
)/i
))
198 check(t
, "TestLargeByteWrites (3)", &buf
, "")
201 func TestLargeStringReads(t
*testing
.T
) {
203 for i
:= 3; i
< 30; i
+= 3 {
204 s
:= fillString(t
, "TestLargeReads (1)", &buf
, "", 5, testString
[0:len(testString
)/i
])
205 empty(t
, "TestLargeReads (2)", &buf
, s
, make([]byte, len(testString
)))
207 check(t
, "TestLargeStringReads (3)", &buf
, "")
210 func TestLargeByteReads(t
*testing
.T
) {
212 for i
:= 3; i
< 30; i
+= 3 {
213 s
:= fillBytes(t
, "TestLargeReads (1)", &buf
, "", 5, testBytes
[0:len(testBytes
)/i
])
214 empty(t
, "TestLargeReads (2)", &buf
, s
, make([]byte, len(testString
)))
216 check(t
, "TestLargeByteReads (3)", &buf
, "")
219 func TestMixedReadsAndWrites(t
*testing
.T
) {
222 for i
:= 0; i
< 50; i
++ {
223 wlen
:= rand
.Intn(len(testString
))
225 s
= fillString(t
, "TestMixedReadsAndWrites (1)", &buf
, s
, 1, testString
[0:wlen
])
227 s
= fillBytes(t
, "TestMixedReadsAndWrites (1)", &buf
, s
, 1, testBytes
[0:wlen
])
230 rlen
:= rand
.Intn(len(testString
))
231 fub
:= make([]byte, rlen
)
232 n
, _
:= buf
.Read(fub
)
235 empty(t
, "TestMixedReadsAndWrites (2)", &buf
, s
, make([]byte, buf
.Len()))
238 func TestCapWithPreallocatedSlice(t
*testing
.T
) {
239 buf
:= NewBuffer(make([]byte, 10))
242 t
.Errorf("expected 10, got %d", n
)
246 func TestCapWithSliceAndWrittenData(t
*testing
.T
) {
247 buf
:= NewBuffer(make([]byte, 0, 10))
248 buf
.Write([]byte("test"))
251 t
.Errorf("expected 10, got %d", n
)
255 func TestNil(t
*testing
.T
) {
257 if b
.String() != "<nil>" {
258 t
.Errorf("expected <nil>; got %q", b
.String())
262 func TestReadFrom(t
*testing
.T
) {
264 for i
:= 3; i
< 30; i
+= 3 {
265 s
:= fillBytes(t
, "TestReadFrom (1)", &buf
, "", 5, testBytes
[0:len(testBytes
)/i
])
268 empty(t
, "TestReadFrom (2)", &b
, s
, make([]byte, len(testString
)))
272 func TestReadFromNegativeReader(t
*testing
.T
) {
275 switch err
:= recover().(type) {
277 t
.Fatal("bytes.Buffer.ReadFrom didn't panic")
279 // this is the error string of errNegativeRead
280 wantError
:= "bytes.Buffer: reader returned negative count from Read"
281 if err
.Error() != wantError
{
282 t
.Fatalf("recovered panic: got %v, want %v", err
.Error(), wantError
)
285 t
.Fatalf("unexpected panic value: %#v", err
)
289 b
.ReadFrom(new(negativeReader
))
292 func TestWriteTo(t
*testing
.T
) {
294 for i
:= 3; i
< 30; i
+= 3 {
295 s
:= fillBytes(t
, "TestWriteTo (1)", &buf
, "", 5, testBytes
[0:len(testBytes
)/i
])
298 empty(t
, "TestWriteTo (2)", &b
, s
, make([]byte, len(testString
)))
302 func TestRuneIO(t
*testing
.T
) {
304 // Built a test slice while we write the data
305 b
:= make([]byte, utf8
.UTFMax
*NRune
)
308 for r
:= rune(0); r
< NRune
; r
++ {
309 size
:= utf8
.EncodeRune(b
[n
:], r
)
310 nbytes
, err
:= buf
.WriteRune(r
)
312 t
.Fatalf("WriteRune(%U) error: %s", r
, err
)
315 t
.Fatalf("WriteRune(%U) expected %d, got %d", r
, size
, nbytes
)
321 // Check the resulting bytes
322 if !Equal(buf
.Bytes(), b
) {
323 t
.Fatalf("incorrect result from WriteRune: %q not %q", buf
.Bytes(), b
)
326 p
:= make([]byte, utf8
.UTFMax
)
327 // Read it back with ReadRune
328 for r
:= rune(0); r
< NRune
; r
++ {
329 size
:= utf8
.EncodeRune(p
, r
)
330 nr
, nbytes
, err
:= buf
.ReadRune()
331 if nr
!= r || nbytes
!= size || err
!= nil {
332 t
.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r
, nr
, nbytes
, r
, size
, err
)
336 // Check that UnreadRune works
340 if err
:= buf
.UnreadRune(); err
== nil {
341 t
.Fatal("UnreadRune at EOF: got no error")
343 if _
, _
, err
:= buf
.ReadRune(); err
== nil {
344 t
.Fatal("ReadRune at EOF: got no error")
346 if err
:= buf
.UnreadRune(); err
== nil {
347 t
.Fatal("UnreadRune after ReadRune at EOF: got no error")
352 for r
:= rune(0); r
< NRune
; r
++ {
353 r1
, size
, _
:= buf
.ReadRune()
354 if err
:= buf
.UnreadRune(); err
!= nil {
355 t
.Fatalf("UnreadRune(%U) got error %q", r
, err
)
357 r2
, nbytes
, err
:= buf
.ReadRune()
358 if r1
!= r2 || r1
!= r || nbytes
!= size || err
!= nil {
359 t
.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r
, r2
, nbytes
, r
, size
, err
)
364 func TestNext(t
*testing
.T
) {
365 b
:= []byte{0, 1, 2, 3, 4}
366 tmp
:= make([]byte, 5)
367 for i
:= 0; i
<= 5; i
++ {
368 for j
:= i
; j
<= 5; j
++ {
369 for k
:= 0; k
<= 6; k
++ {
370 // 0 <= i <= j <= 5; 0 <= k <= 6
371 // Check that if we start with a buffer
372 // of length j at offset i and ask for
373 // Next(k), we get the right bytes.
374 buf
:= NewBuffer(b
[0:j
])
375 n
, _
:= buf
.Read(tmp
[0:i
])
377 t
.Fatalf("Read %d returned %d", i
, n
)
385 t
.Fatalf("in %d,%d: len(Next(%d)) == %d", i
, j
, k
, len(bb
))
387 for l
, v
:= range bb
{
389 t
.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i
, j
, k
, l
, v
, l
+i
)
397 var readBytesTests
= []struct {
403 {"", 0, []string{""}, io
.EOF
},
404 {"a\x00", 0, []string{"a\x00"}, nil},
405 {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
406 {"hello\x01world", 1, []string{"hello\x01"}, nil},
407 {"foo\nbar", 0, []string{"foo\nbar"}, io
.EOF
},
408 {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
409 {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io
.EOF
},
412 func TestReadBytes(t
*testing
.T
) {
413 for _
, test
:= range readBytesTests
{
414 buf
:= NewBufferString(test
.buffer
)
416 for _
, expected
:= range test
.expected
{
418 bytes
, err
= buf
.ReadBytes(test
.delim
)
419 if string(bytes
) != expected
{
420 t
.Errorf("expected %q, got %q", expected
, bytes
)
427 t
.Errorf("expected error %v, got %v", test
.err
, err
)
432 func TestReadString(t
*testing
.T
) {
433 for _
, test
:= range readBytesTests
{
434 buf
:= NewBufferString(test
.buffer
)
436 for _
, expected
:= range test
.expected
{
438 s
, err
= buf
.ReadString(test
.delim
)
440 t
.Errorf("expected %q, got %q", expected
, s
)
447 t
.Errorf("expected error %v, got %v", test
.err
, err
)
452 func BenchmarkReadString(b
*testing
.B
) {
455 data
:= make([]byte, n
)
458 for i
:= 0; i
< b
.N
; i
++ {
459 buf
:= NewBuffer(data
)
460 _
, err
:= buf
.ReadString('x')
467 func TestGrow(t
*testing
.T
) {
470 tmp
:= make([]byte, 72)
471 for _
, startLen
:= range []int{0, 100, 1000, 10000, 100000} {
472 xBytes
:= Repeat(x
, startLen
)
473 for _
, growLen
:= range []int{0, 100, 1000, 10000, 100000} {
474 buf
:= NewBuffer(xBytes
)
475 // If we read, this affects buf.off, which is good to test.
476 readBytes
, _
:= buf
.Read(tmp
)
478 yBytes
:= Repeat(y
, growLen
)
479 // Check no allocation occurs in write, as long as we're single-threaded.
480 var m1
, m2 runtime
.MemStats
481 runtime
.ReadMemStats(&m1
)
483 runtime
.ReadMemStats(&m2
)
484 if runtime
.GOMAXPROCS(-1) == 1 && m1
.Mallocs
!= m2
.Mallocs
{
485 t
.Errorf("allocation occurred during write")
487 // Check that buffer has correct data.
488 if !Equal(buf
.Bytes()[0:startLen
-readBytes
], xBytes
[readBytes
:]) {
489 t
.Errorf("bad initial data at %d %d", startLen
, growLen
)
491 if !Equal(buf
.Bytes()[startLen
-readBytes
:startLen
-readBytes
+growLen
], yBytes
) {
492 t
.Errorf("bad written data at %d %d", startLen
, growLen
)
498 func TestGrowOverflow(t
*testing
.T
) {
500 if err
:= recover(); err
!= ErrTooLarge
{
501 t
.Errorf("after too-large Grow, recover() = %v; want %v", err
, ErrTooLarge
)
505 buf
:= NewBuffer(make([]byte, 1))
506 const maxInt
= int(^uint(0) >> 1)
510 // Was a bug: used to give EOF reading empty slice at EOF.
511 func TestReadEmptyAtEOF(t
*testing
.T
) {
513 slice
:= make([]byte, 0)
514 n
, err
:= b
.Read(slice
)
516 t
.Errorf("read error: %v", err
)
519 t
.Errorf("wrong count; got %d want 0", n
)
523 func TestUnreadByte(t
*testing
.T
) {
527 if err
:= b
.UnreadByte(); err
== nil {
528 t
.Fatal("UnreadByte at EOF: got no error")
530 if _
, err
:= b
.ReadByte(); err
== nil {
531 t
.Fatal("ReadByte at EOF: got no error")
533 if err
:= b
.UnreadByte(); err
== nil {
534 t
.Fatal("UnreadByte after ReadByte at EOF: got no error")
538 b
.WriteString("abcdefghijklmnopqrstuvwxyz")
540 // after unsuccessful read
541 if n
, err
:= b
.Read(nil); n
!= 0 || err
!= nil {
542 t
.Fatalf("Read(nil) = %d,%v; want 0,nil", n
, err
)
544 if err
:= b
.UnreadByte(); err
== nil {
545 t
.Fatal("UnreadByte after Read(nil): got no error")
548 // after successful read
549 if _
, err
:= b
.ReadBytes('m'); err
!= nil {
550 t
.Fatalf("ReadBytes: %v", err
)
552 if err
:= b
.UnreadByte(); err
!= nil {
553 t
.Fatalf("UnreadByte: %v", err
)
555 c
, err
:= b
.ReadByte()
557 t
.Fatalf("ReadByte: %v", err
)
560 t
.Errorf("ReadByte = %q; want %q", c
, 'm')
564 // Tests that we occasionally compact. Issue 5154.
565 func TestBufferGrowth(t
*testing
.T
) {
567 buf
:= make([]byte, 1024)
570 for i
:= 0; i
< 5<<10; i
++ {
578 // (*Buffer).grow allows for 2x capacity slop before sliding,
579 // so set our error threshold at 3x.
581 t
.Errorf("buffer cap = %d; too big (grew from %d)", cap1
, cap0
)
585 func BenchmarkWriteByte(b
*testing
.B
) {
588 buf
:= NewBuffer(make([]byte, n
))
589 for i
:= 0; i
< b
.N
; i
++ {
591 for i
:= 0; i
< n
; i
++ {
597 func BenchmarkWriteRune(b
*testing
.B
) {
600 b
.SetBytes(int64(n
* utf8
.RuneLen(r
)))
601 buf
:= NewBuffer(make([]byte, n
*utf8
.UTFMax
))
602 for i
:= 0; i
< b
.N
; i
++ {
604 for i
:= 0; i
< n
; i
++ {
611 func BenchmarkBufferNotEmptyWriteRead(b
*testing
.B
) {
612 buf
:= make([]byte, 1024)
613 for i
:= 0; i
< b
.N
; i
++ {
616 for i
:= 0; i
< 5<<10; i
++ {
623 // Check that we don't compact too often. From Issue 5154.
624 func BenchmarkBufferFullSmallReads(b
*testing
.B
) {
625 buf
:= make([]byte, 1024)
626 for i
:= 0; i
< b
.N
; i
++ {
629 for b
.Len()+20 < b
.Cap() {
632 for i
:= 0; i
< 5<<10; i
++ {