...

Source file src/bytes/buffer_test.go

Documentation: bytes

		 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 bytes_test
		 6  
		 7  import (
		 8  	. "bytes"
		 9  	"fmt"
		10  	"io"
		11  	"math/rand"
		12  	"testing"
		13  	"unicode/utf8"
		14  )
		15  
		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.
		19  
		20  type negativeReader struct{}
		21  
		22  func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
		23  
		24  func init() {
		25  	testBytes = make([]byte, N)
		26  	for i := 0; i < N; i++ {
		27  		testBytes[i] = 'a' + byte(i%26)
		28  	}
		29  	testString = string(testBytes)
		30  }
		31  
		32  // Verify that contents of buf match the string s.
		33  func check(t *testing.T, testname string, buf *Buffer, s string) {
		34  	bytes := buf.Bytes()
		35  	str := buf.String()
		36  	if buf.Len() != len(bytes) {
		37  		t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
		38  	}
		39  
		40  	if buf.Len() != len(str) {
		41  		t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
		42  	}
		43  
		44  	if buf.Len() != len(s) {
		45  		t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
		46  	}
		47  
		48  	if string(bytes) != s {
		49  		t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
		50  	}
		51  }
		52  
		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)
		58  	for ; n > 0; n-- {
		59  		m, err := buf.WriteString(fus)
		60  		if m != len(fus) {
		61  			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))
		62  		}
		63  		if err != nil {
		64  			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
		65  		}
		66  		s += fus
		67  		check(t, testname+" (fill 4)", buf, s)
		68  	}
		69  	return s
		70  }
		71  
		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)
		77  	for ; n > 0; n-- {
		78  		m, err := buf.Write(fub)
		79  		if m != len(fub) {
		80  			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
		81  		}
		82  		if err != nil {
		83  			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
		84  		}
		85  		s += string(fub)
		86  		check(t, testname+" (fill 4)", buf, s)
		87  	}
		88  	return s
		89  }
		90  
		91  func TestNewBuffer(t *testing.T) {
		92  	buf := NewBuffer(testBytes)
		93  	check(t, "NewBuffer", buf, testString)
		94  }
		95  
		96  func TestNewBufferString(t *testing.T) {
		97  	buf := NewBufferString(testString)
		98  	check(t, "NewBufferString", buf, testString)
		99  }
	 100  
	 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)
	 105  
	 106  	for {
	 107  		n, err := buf.Read(fub)
	 108  		if n == 0 {
	 109  			break
	 110  		}
	 111  		if err != nil {
	 112  			t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
	 113  		}
	 114  		s = s[n:]
	 115  		check(t, testname+" (empty 3)", buf, s)
	 116  	}
	 117  
	 118  	check(t, testname+" (empty 4)", buf, "")
	 119  }
	 120  
	 121  func TestBasicOperations(t *testing.T) {
	 122  	var buf Buffer
	 123  
	 124  	for i := 0; i < 5; i++ {
	 125  		check(t, "TestBasicOperations (1)", &buf, "")
	 126  
	 127  		buf.Reset()
	 128  		check(t, "TestBasicOperations (2)", &buf, "")
	 129  
	 130  		buf.Truncate(0)
	 131  		check(t, "TestBasicOperations (3)", &buf, "")
	 132  
	 133  		n, err := buf.Write(testBytes[0:1])
	 134  		if want := 1; err != nil || n != want {
	 135  			t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
	 136  		}
	 137  		check(t, "TestBasicOperations (4)", &buf, "a")
	 138  
	 139  		buf.WriteByte(testString[1])
	 140  		check(t, "TestBasicOperations (5)", &buf, "ab")
	 141  
	 142  		n, err = buf.Write(testBytes[2:26])
	 143  		if want := 24; err != nil || n != want {
	 144  			t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
	 145  		}
	 146  		check(t, "TestBasicOperations (6)", &buf, testString[0:26])
	 147  
	 148  		buf.Truncate(26)
	 149  		check(t, "TestBasicOperations (7)", &buf, testString[0:26])
	 150  
	 151  		buf.Truncate(20)
	 152  		check(t, "TestBasicOperations (8)", &buf, testString[0:20])
	 153  
	 154  		empty(t, "TestBasicOperations (9)", &buf, testString[0:20], make([]byte, 5))
	 155  		empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
	 156  
	 157  		buf.WriteByte(testString[1])
	 158  		c, err := buf.ReadByte()
	 159  		if want := testString[1]; err != nil || c != want {
	 160  			t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, want, nil)
	 161  		}
	 162  		c, err = buf.ReadByte()
	 163  		if err != io.EOF {
	 164  			t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, byte(0), io.EOF)
	 165  		}
	 166  	}
	 167  }
	 168  
	 169  func TestLargeStringWrites(t *testing.T) {
	 170  	var buf Buffer
	 171  	limit := 30
	 172  	if testing.Short() {
	 173  		limit = 9
	 174  	}
	 175  	for i := 3; i < limit; i += 3 {
	 176  		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, testString)
	 177  		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(testString)/i))
	 178  	}
	 179  	check(t, "TestLargeStringWrites (3)", &buf, "")
	 180  }
	 181  
	 182  func TestLargeByteWrites(t *testing.T) {
	 183  	var buf Buffer
	 184  	limit := 30
	 185  	if testing.Short() {
	 186  		limit = 9
	 187  	}
	 188  	for i := 3; i < limit; i += 3 {
	 189  		s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
	 190  		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(testString)/i))
	 191  	}
	 192  	check(t, "TestLargeByteWrites (3)", &buf, "")
	 193  }
	 194  
	 195  func TestLargeStringReads(t *testing.T) {
	 196  	var buf Buffer
	 197  	for i := 3; i < 30; i += 3 {
	 198  		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, testString[0:len(testString)/i])
	 199  		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
	 200  	}
	 201  	check(t, "TestLargeStringReads (3)", &buf, "")
	 202  }
	 203  
	 204  func TestLargeByteReads(t *testing.T) {
	 205  	var buf Buffer
	 206  	for i := 3; i < 30; i += 3 {
	 207  		s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
	 208  		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
	 209  	}
	 210  	check(t, "TestLargeByteReads (3)", &buf, "")
	 211  }
	 212  
	 213  func TestMixedReadsAndWrites(t *testing.T) {
	 214  	var buf Buffer
	 215  	s := ""
	 216  	for i := 0; i < 50; i++ {
	 217  		wlen := rand.Intn(len(testString))
	 218  		if i%2 == 0 {
	 219  			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testString[0:wlen])
	 220  		} else {
	 221  			s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
	 222  		}
	 223  
	 224  		rlen := rand.Intn(len(testString))
	 225  		fub := make([]byte, rlen)
	 226  		n, _ := buf.Read(fub)
	 227  		s = s[n:]
	 228  	}
	 229  	empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
	 230  }
	 231  
	 232  func TestCapWithPreallocatedSlice(t *testing.T) {
	 233  	buf := NewBuffer(make([]byte, 10))
	 234  	n := buf.Cap()
	 235  	if n != 10 {
	 236  		t.Errorf("expected 10, got %d", n)
	 237  	}
	 238  }
	 239  
	 240  func TestCapWithSliceAndWrittenData(t *testing.T) {
	 241  	buf := NewBuffer(make([]byte, 0, 10))
	 242  	buf.Write([]byte("test"))
	 243  	n := buf.Cap()
	 244  	if n != 10 {
	 245  		t.Errorf("expected 10, got %d", n)
	 246  	}
	 247  }
	 248  
	 249  func TestNil(t *testing.T) {
	 250  	var b *Buffer
	 251  	if b.String() != "<nil>" {
	 252  		t.Errorf("expected <nil>; got %q", b.String())
	 253  	}
	 254  }
	 255  
	 256  func TestReadFrom(t *testing.T) {
	 257  	var buf Buffer
	 258  	for i := 3; i < 30; i += 3 {
	 259  		s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
	 260  		var b Buffer
	 261  		b.ReadFrom(&buf)
	 262  		empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(testString)))
	 263  	}
	 264  }
	 265  
	 266  type panicReader struct{ panic bool }
	 267  
	 268  func (r panicReader) Read(p []byte) (int, error) {
	 269  	if r.panic {
	 270  		panic(nil)
	 271  	}
	 272  	return 0, io.EOF
	 273  }
	 274  
	 275  // Make sure that an empty Buffer remains empty when
	 276  // it is "grown" before a Read that panics
	 277  func TestReadFromPanicReader(t *testing.T) {
	 278  
	 279  	// First verify non-panic behaviour
	 280  	var buf Buffer
	 281  	i, err := buf.ReadFrom(panicReader{})
	 282  	if err != nil {
	 283  		t.Fatal(err)
	 284  	}
	 285  	if i != 0 {
	 286  		t.Fatalf("unexpected return from bytes.ReadFrom (1): got: %d, want %d", i, 0)
	 287  	}
	 288  	check(t, "TestReadFromPanicReader (1)", &buf, "")
	 289  
	 290  	// Confirm that when Reader panics, the empty buffer remains empty
	 291  	var buf2 Buffer
	 292  	defer func() {
	 293  		recover()
	 294  		check(t, "TestReadFromPanicReader (2)", &buf2, "")
	 295  	}()
	 296  	buf2.ReadFrom(panicReader{panic: true})
	 297  }
	 298  
	 299  func TestReadFromNegativeReader(t *testing.T) {
	 300  	var b Buffer
	 301  	defer func() {
	 302  		switch err := recover().(type) {
	 303  		case nil:
	 304  			t.Fatal("bytes.Buffer.ReadFrom didn't panic")
	 305  		case error:
	 306  			// this is the error string of errNegativeRead
	 307  			wantError := "bytes.Buffer: reader returned negative count from Read"
	 308  			if err.Error() != wantError {
	 309  				t.Fatalf("recovered panic: got %v, want %v", err.Error(), wantError)
	 310  			}
	 311  		default:
	 312  			t.Fatalf("unexpected panic value: %#v", err)
	 313  		}
	 314  	}()
	 315  
	 316  	b.ReadFrom(new(negativeReader))
	 317  }
	 318  
	 319  func TestWriteTo(t *testing.T) {
	 320  	var buf Buffer
	 321  	for i := 3; i < 30; i += 3 {
	 322  		s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
	 323  		var b Buffer
	 324  		buf.WriteTo(&b)
	 325  		empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(testString)))
	 326  	}
	 327  }
	 328  
	 329  func TestRuneIO(t *testing.T) {
	 330  	const NRune = 1000
	 331  	// Built a test slice while we write the data
	 332  	b := make([]byte, utf8.UTFMax*NRune)
	 333  	var buf Buffer
	 334  	n := 0
	 335  	for r := rune(0); r < NRune; r++ {
	 336  		size := utf8.EncodeRune(b[n:], r)
	 337  		nbytes, err := buf.WriteRune(r)
	 338  		if err != nil {
	 339  			t.Fatalf("WriteRune(%U) error: %s", r, err)
	 340  		}
	 341  		if nbytes != size {
	 342  			t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes)
	 343  		}
	 344  		n += size
	 345  	}
	 346  	b = b[0:n]
	 347  
	 348  	// Check the resulting bytes
	 349  	if !Equal(buf.Bytes(), b) {
	 350  		t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b)
	 351  	}
	 352  
	 353  	p := make([]byte, utf8.UTFMax)
	 354  	// Read it back with ReadRune
	 355  	for r := rune(0); r < NRune; r++ {
	 356  		size := utf8.EncodeRune(p, r)
	 357  		nr, nbytes, err := buf.ReadRune()
	 358  		if nr != r || nbytes != size || err != nil {
	 359  			t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err)
	 360  		}
	 361  	}
	 362  
	 363  	// Check that UnreadRune works
	 364  	buf.Reset()
	 365  
	 366  	// check at EOF
	 367  	if err := buf.UnreadRune(); err == nil {
	 368  		t.Fatal("UnreadRune at EOF: got no error")
	 369  	}
	 370  	if _, _, err := buf.ReadRune(); err == nil {
	 371  		t.Fatal("ReadRune at EOF: got no error")
	 372  	}
	 373  	if err := buf.UnreadRune(); err == nil {
	 374  		t.Fatal("UnreadRune after ReadRune at EOF: got no error")
	 375  	}
	 376  
	 377  	// check not at EOF
	 378  	buf.Write(b)
	 379  	for r := rune(0); r < NRune; r++ {
	 380  		r1, size, _ := buf.ReadRune()
	 381  		if err := buf.UnreadRune(); err != nil {
	 382  			t.Fatalf("UnreadRune(%U) got error %q", r, err)
	 383  		}
	 384  		r2, nbytes, err := buf.ReadRune()
	 385  		if r1 != r2 || r1 != r || nbytes != size || err != nil {
	 386  			t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err)
	 387  		}
	 388  	}
	 389  }
	 390  
	 391  func TestWriteInvalidRune(t *testing.T) {
	 392  	// Invalid runes, including negative ones, should be written as
	 393  	// utf8.RuneError.
	 394  	for _, r := range []rune{-1, utf8.MaxRune + 1} {
	 395  		var buf Buffer
	 396  		buf.WriteRune(r)
	 397  		check(t, fmt.Sprintf("TestWriteInvalidRune (%d)", r), &buf, "\uFFFD")
	 398  	}
	 399  }
	 400  
	 401  func TestNext(t *testing.T) {
	 402  	b := []byte{0, 1, 2, 3, 4}
	 403  	tmp := make([]byte, 5)
	 404  	for i := 0; i <= 5; i++ {
	 405  		for j := i; j <= 5; j++ {
	 406  			for k := 0; k <= 6; k++ {
	 407  				// 0 <= i <= j <= 5; 0 <= k <= 6
	 408  				// Check that if we start with a buffer
	 409  				// of length j at offset i and ask for
	 410  				// Next(k), we get the right bytes.
	 411  				buf := NewBuffer(b[0:j])
	 412  				n, _ := buf.Read(tmp[0:i])
	 413  				if n != i {
	 414  					t.Fatalf("Read %d returned %d", i, n)
	 415  				}
	 416  				bb := buf.Next(k)
	 417  				want := k
	 418  				if want > j-i {
	 419  					want = j - i
	 420  				}
	 421  				if len(bb) != want {
	 422  					t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
	 423  				}
	 424  				for l, v := range bb {
	 425  					if v != byte(l+i) {
	 426  						t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
	 427  					}
	 428  				}
	 429  			}
	 430  		}
	 431  	}
	 432  }
	 433  
	 434  var readBytesTests = []struct {
	 435  	buffer	 string
	 436  	delim		byte
	 437  	expected []string
	 438  	err			error
	 439  }{
	 440  	{"", 0, []string{""}, io.EOF},
	 441  	{"a\x00", 0, []string{"a\x00"}, nil},
	 442  	{"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
	 443  	{"hello\x01world", 1, []string{"hello\x01"}, nil},
	 444  	{"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
	 445  	{"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
	 446  	{"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
	 447  }
	 448  
	 449  func TestReadBytes(t *testing.T) {
	 450  	for _, test := range readBytesTests {
	 451  		buf := NewBufferString(test.buffer)
	 452  		var err error
	 453  		for _, expected := range test.expected {
	 454  			var bytes []byte
	 455  			bytes, err = buf.ReadBytes(test.delim)
	 456  			if string(bytes) != expected {
	 457  				t.Errorf("expected %q, got %q", expected, bytes)
	 458  			}
	 459  			if err != nil {
	 460  				break
	 461  			}
	 462  		}
	 463  		if err != test.err {
	 464  			t.Errorf("expected error %v, got %v", test.err, err)
	 465  		}
	 466  	}
	 467  }
	 468  
	 469  func TestReadString(t *testing.T) {
	 470  	for _, test := range readBytesTests {
	 471  		buf := NewBufferString(test.buffer)
	 472  		var err error
	 473  		for _, expected := range test.expected {
	 474  			var s string
	 475  			s, err = buf.ReadString(test.delim)
	 476  			if s != expected {
	 477  				t.Errorf("expected %q, got %q", expected, s)
	 478  			}
	 479  			if err != nil {
	 480  				break
	 481  			}
	 482  		}
	 483  		if err != test.err {
	 484  			t.Errorf("expected error %v, got %v", test.err, err)
	 485  		}
	 486  	}
	 487  }
	 488  
	 489  func BenchmarkReadString(b *testing.B) {
	 490  	const n = 32 << 10
	 491  
	 492  	data := make([]byte, n)
	 493  	data[n-1] = 'x'
	 494  	b.SetBytes(int64(n))
	 495  	for i := 0; i < b.N; i++ {
	 496  		buf := NewBuffer(data)
	 497  		_, err := buf.ReadString('x')
	 498  		if err != nil {
	 499  			b.Fatal(err)
	 500  		}
	 501  	}
	 502  }
	 503  
	 504  func TestGrow(t *testing.T) {
	 505  	x := []byte{'x'}
	 506  	y := []byte{'y'}
	 507  	tmp := make([]byte, 72)
	 508  	for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
	 509  		for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
	 510  			xBytes := Repeat(x, startLen)
	 511  
	 512  			buf := NewBuffer(xBytes)
	 513  			// If we read, this affects buf.off, which is good to test.
	 514  			readBytes, _ := buf.Read(tmp)
	 515  			yBytes := Repeat(y, growLen)
	 516  			allocs := testing.AllocsPerRun(100, func() {
	 517  				buf.Grow(growLen)
	 518  				buf.Write(yBytes)
	 519  			})
	 520  			// Check no allocation occurs in write, as long as we're single-threaded.
	 521  			if allocs != 0 {
	 522  				t.Errorf("allocation occurred during write")
	 523  			}
	 524  			// Check that buffer has correct data.
	 525  			if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
	 526  				t.Errorf("bad initial data at %d %d", startLen, growLen)
	 527  			}
	 528  			if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
	 529  				t.Errorf("bad written data at %d %d", startLen, growLen)
	 530  			}
	 531  		}
	 532  	}
	 533  }
	 534  
	 535  func TestGrowOverflow(t *testing.T) {
	 536  	defer func() {
	 537  		if err := recover(); err != ErrTooLarge {
	 538  			t.Errorf("after too-large Grow, recover() = %v; want %v", err, ErrTooLarge)
	 539  		}
	 540  	}()
	 541  
	 542  	buf := NewBuffer(make([]byte, 1))
	 543  	const maxInt = int(^uint(0) >> 1)
	 544  	buf.Grow(maxInt)
	 545  }
	 546  
	 547  // Was a bug: used to give EOF reading empty slice at EOF.
	 548  func TestReadEmptyAtEOF(t *testing.T) {
	 549  	b := new(Buffer)
	 550  	slice := make([]byte, 0)
	 551  	n, err := b.Read(slice)
	 552  	if err != nil {
	 553  		t.Errorf("read error: %v", err)
	 554  	}
	 555  	if n != 0 {
	 556  		t.Errorf("wrong count; got %d want 0", n)
	 557  	}
	 558  }
	 559  
	 560  func TestUnreadByte(t *testing.T) {
	 561  	b := new(Buffer)
	 562  
	 563  	// check at EOF
	 564  	if err := b.UnreadByte(); err == nil {
	 565  		t.Fatal("UnreadByte at EOF: got no error")
	 566  	}
	 567  	if _, err := b.ReadByte(); err == nil {
	 568  		t.Fatal("ReadByte at EOF: got no error")
	 569  	}
	 570  	if err := b.UnreadByte(); err == nil {
	 571  		t.Fatal("UnreadByte after ReadByte at EOF: got no error")
	 572  	}
	 573  
	 574  	// check not at EOF
	 575  	b.WriteString("abcdefghijklmnopqrstuvwxyz")
	 576  
	 577  	// after unsuccessful read
	 578  	if n, err := b.Read(nil); n != 0 || err != nil {
	 579  		t.Fatalf("Read(nil) = %d,%v; want 0,nil", n, err)
	 580  	}
	 581  	if err := b.UnreadByte(); err == nil {
	 582  		t.Fatal("UnreadByte after Read(nil): got no error")
	 583  	}
	 584  
	 585  	// after successful read
	 586  	if _, err := b.ReadBytes('m'); err != nil {
	 587  		t.Fatalf("ReadBytes: %v", err)
	 588  	}
	 589  	if err := b.UnreadByte(); err != nil {
	 590  		t.Fatalf("UnreadByte: %v", err)
	 591  	}
	 592  	c, err := b.ReadByte()
	 593  	if err != nil {
	 594  		t.Fatalf("ReadByte: %v", err)
	 595  	}
	 596  	if c != 'm' {
	 597  		t.Errorf("ReadByte = %q; want %q", c, 'm')
	 598  	}
	 599  }
	 600  
	 601  // Tests that we occasionally compact. Issue 5154.
	 602  func TestBufferGrowth(t *testing.T) {
	 603  	var b Buffer
	 604  	buf := make([]byte, 1024)
	 605  	b.Write(buf[0:1])
	 606  	var cap0 int
	 607  	for i := 0; i < 5<<10; i++ {
	 608  		b.Write(buf)
	 609  		b.Read(buf)
	 610  		if i == 0 {
	 611  			cap0 = b.Cap()
	 612  		}
	 613  	}
	 614  	cap1 := b.Cap()
	 615  	// (*Buffer).grow allows for 2x capacity slop before sliding,
	 616  	// so set our error threshold at 3x.
	 617  	if cap1 > cap0*3 {
	 618  		t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
	 619  	}
	 620  }
	 621  
	 622  func BenchmarkWriteByte(b *testing.B) {
	 623  	const n = 4 << 10
	 624  	b.SetBytes(n)
	 625  	buf := NewBuffer(make([]byte, n))
	 626  	for i := 0; i < b.N; i++ {
	 627  		buf.Reset()
	 628  		for i := 0; i < n; i++ {
	 629  			buf.WriteByte('x')
	 630  		}
	 631  	}
	 632  }
	 633  
	 634  func BenchmarkWriteRune(b *testing.B) {
	 635  	const n = 4 << 10
	 636  	const r = '☺'
	 637  	b.SetBytes(int64(n * utf8.RuneLen(r)))
	 638  	buf := NewBuffer(make([]byte, n*utf8.UTFMax))
	 639  	for i := 0; i < b.N; i++ {
	 640  		buf.Reset()
	 641  		for i := 0; i < n; i++ {
	 642  			buf.WriteRune(r)
	 643  		}
	 644  	}
	 645  }
	 646  
	 647  // From Issue 5154.
	 648  func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
	 649  	buf := make([]byte, 1024)
	 650  	for i := 0; i < b.N; i++ {
	 651  		var b Buffer
	 652  		b.Write(buf[0:1])
	 653  		for i := 0; i < 5<<10; i++ {
	 654  			b.Write(buf)
	 655  			b.Read(buf)
	 656  		}
	 657  	}
	 658  }
	 659  
	 660  // Check that we don't compact too often. From Issue 5154.
	 661  func BenchmarkBufferFullSmallReads(b *testing.B) {
	 662  	buf := make([]byte, 1024)
	 663  	for i := 0; i < b.N; i++ {
	 664  		var b Buffer
	 665  		b.Write(buf)
	 666  		for b.Len()+20 < b.Cap() {
	 667  			b.Write(buf[:10])
	 668  		}
	 669  		for i := 0; i < 5<<10; i++ {
	 670  			b.Read(buf[:1])
	 671  			b.Write(buf[:1])
	 672  		}
	 673  	}
	 674  }
	 675  

View as plain text