544 lines · 13.5 KB · Go
RawDownload
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file. package bytes_test import (	. "bytes"	"io"	"math/rand"	"runtime"	"testing"	"unicode/utf8") const N = 10000      // make this bigger for a larger (and slower) testvar data string      // test data for write testsvar testBytes []byte // test data; same as data but as a slice. func init() {	testBytes = make([]byte, N)	for i := 0; i < N; i++ {		testBytes[i] = 'a' + byte(i%26)	}	data = string(testBytes)} // Verify that contents of buf match the string s.func check(t *testing.T, testname string, buf *Buffer, s string) {	bytes := buf.Bytes()	str := buf.String()	if buf.Len() != len(bytes) {		t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))	} 	if buf.Len() != len(str) {		t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))	} 	if buf.Len() != len(s) {		t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))	} 	if string(bytes) != s {		t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)	}} // Fill buf through n writes of string fus.// The initial contents of buf corresponds to the string s;// the result is the final contents of buf returned as a string.func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {	check(t, testname+" (fill 1)", buf, s)	for ; n > 0; n-- {		m, err := buf.WriteString(fus)		if m != len(fus) {			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))		}		if err != nil {			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)		}		s += fus		check(t, testname+" (fill 4)", buf, s)	}	return s} // Fill buf through n writes of byte slice fub.// The initial contents of buf corresponds to the string s;// the result is the final contents of buf returned as a string.func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {	check(t, testname+" (fill 1)", buf, s)	for ; n > 0; n-- {		m, err := buf.Write(fub)		if m != len(fub) {			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))		}		if err != nil {			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)		}		s += string(fub)		check(t, testname+" (fill 4)", buf, s)	}	return s} func TestNewBuffer(t *testing.T) {	buf := NewBuffer(testBytes)	check(t, "NewBuffer", buf, data)} func TestNewBufferString(t *testing.T) {	buf := NewBufferString(data)	check(t, "NewBufferString", buf, data)} // Empty buf through repeated reads into fub.// The initial contents of buf corresponds to the string s.func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {	check(t, testname+" (empty 1)", buf, s) 	for {		n, err := buf.Read(fub)		if n == 0 {			break		}		if err != nil {			t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)		}		s = s[n:]		check(t, testname+" (empty 3)", buf, s)	} 	check(t, testname+" (empty 4)", buf, "")} func TestBasicOperations(t *testing.T) {	var buf Buffer 	for i := 0; i < 5; i++ {		check(t, "TestBasicOperations (1)", &buf, "") 		buf.Reset()		check(t, "TestBasicOperations (2)", &buf, "") 		buf.Truncate(0)		check(t, "TestBasicOperations (3)", &buf, "") 		n, err := buf.Write([]byte(data[0:1]))		if n != 1 {			t.Errorf("wrote 1 byte, but n == %d", n)		}		if err != nil {			t.Errorf("err should always be nil, but err == %s", err)		}		check(t, "TestBasicOperations (4)", &buf, "a") 		buf.WriteByte(data[1])		check(t, "TestBasicOperations (5)", &buf, "ab") 		n, err = buf.Write([]byte(data[2:26]))		if n != 24 {			t.Errorf("wrote 25 bytes, but n == %d", n)		}		check(t, "TestBasicOperations (6)", &buf, string(data[0:26])) 		buf.Truncate(26)		check(t, "TestBasicOperations (7)", &buf, string(data[0:26])) 		buf.Truncate(20)		check(t, "TestBasicOperations (8)", &buf, string(data[0:20])) 		empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5))		empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100)) 		buf.WriteByte(data[1])		c, err := buf.ReadByte()		if err != nil {			t.Error("ReadByte unexpected eof")		}		if c != data[1] {			t.Errorf("ReadByte wrong value c=%v", c)		}		c, err = buf.ReadByte()		if err == nil {			t.Error("ReadByte unexpected not eof")		}	}} func TestLargeStringWrites(t *testing.T) {	var buf Buffer	limit := 30	if testing.Short() {		limit = 9	}	for i := 3; i < limit; i += 3 {		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, data)		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(data)/i))	}	check(t, "TestLargeStringWrites (3)", &buf, "")} func TestLargeByteWrites(t *testing.T) {	var buf Buffer	limit := 30	if testing.Short() {		limit = 9	}	for i := 3; i < limit; i += 3 {		s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))	}	check(t, "TestLargeByteWrites (3)", &buf, "")} func TestLargeStringReads(t *testing.T) {	var buf Buffer	for i := 3; i < 30; i += 3 {		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, data[0:len(data)/i])		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))	}	check(t, "TestLargeStringReads (3)", &buf, "")} func TestLargeByteReads(t *testing.T) {	var buf Buffer	for i := 3; i < 30; i += 3 {		s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))	}	check(t, "TestLargeByteReads (3)", &buf, "")} func TestMixedReadsAndWrites(t *testing.T) {	var buf Buffer	s := ""	for i := 0; i < 50; i++ {		wlen := rand.Intn(len(data))		if i%2 == 0 {			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, data[0:wlen])		} else {			s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])		} 		rlen := rand.Intn(len(data))		fub := make([]byte, rlen)		n, _ := buf.Read(fub)		s = s[n:]	}	empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))} func TestCapWithPreallocatedSlice(t *testing.T) {	buf := NewBuffer(make([]byte, 10))	n := buf.Cap()	if n != 10 {		t.Errorf("expected 10, got %d", n)	}} func TestCapWithSliceAndWrittenData(t *testing.T) {	buf := NewBuffer(make([]byte, 0, 10))	buf.Write([]byte("test"))	n := buf.Cap()	if n != 10 {		t.Errorf("expected 10, got %d", n)	}} func TestNil(t *testing.T) {	var b *Buffer	if b.String() != "<nil>" {		t.Errorf("expected <nil>; got %q", b.String())	}} func TestReadFrom(t *testing.T) {	var buf Buffer	for i := 3; i < 30; i += 3 {		s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])		var b Buffer		b.ReadFrom(&buf)		empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))	}} func TestWriteTo(t *testing.T) {	var buf Buffer	for i := 3; i < 30; i += 3 {		s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])		var b Buffer		buf.WriteTo(&b)		empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))	}} func TestRuneIO(t *testing.T) {	const NRune = 1000	// Built a test slice while we write the data	b := make([]byte, utf8.UTFMax*NRune)	var buf Buffer	n := 0	for r := rune(0); r < NRune; r++ {		size := utf8.EncodeRune(b[n:], r)		nbytes, err := buf.WriteRune(r)		if err != nil {			t.Fatalf("WriteRune(%U) error: %s", r, err)		}		if nbytes != size {			t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes)		}		n += size	}	b = b[0:n] 	// Check the resulting bytes	if !Equal(buf.Bytes(), b) {		t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b)	} 	p := make([]byte, utf8.UTFMax)	// Read it back with ReadRune	for r := rune(0); r < NRune; r++ {		size := utf8.EncodeRune(p, r)		nr, nbytes, err := buf.ReadRune()		if nr != r || nbytes != size || err != nil {			t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err)		}	} 	// Check that UnreadRune works	buf.Reset()	buf.Write(b)	for r := rune(0); r < NRune; r++ {		r1, size, _ := buf.ReadRune()		if err := buf.UnreadRune(); err != nil {			t.Fatalf("UnreadRune(%U) got error %q", r, err)		}		r2, nbytes, err := buf.ReadRune()		if r1 != r2 || r1 != r || nbytes != size || err != nil {			t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err)		}	}} func TestNext(t *testing.T) {	b := []byte{0, 1, 2, 3, 4}	tmp := make([]byte, 5)	for i := 0; i <= 5; i++ {		for j := i; j <= 5; j++ {			for k := 0; k <= 6; k++ {				// 0 <= i <= j <= 5; 0 <= k <= 6				// Check that if we start with a buffer				// of length j at offset i and ask for				// Next(k), we get the right bytes.				buf := NewBuffer(b[0:j])				n, _ := buf.Read(tmp[0:i])				if n != i {					t.Fatalf("Read %d returned %d", i, n)				}				bb := buf.Next(k)				want := k				if want > j-i {					want = j - i				}				if len(bb) != want {					t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))				}				for l, v := range bb {					if v != byte(l+i) {						t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)					}				}			}		}	}} var readBytesTests = []struct {	buffer   string	delim    byte	expected []string	err      error}{	{"", 0, []string{""}, io.EOF},	{"a\x00", 0, []string{"a\x00"}, nil},	{"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},	{"hello\x01world", 1, []string{"hello\x01"}, nil},	{"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},	{"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},	{"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},} func TestReadBytes(t *testing.T) {	for _, test := range readBytesTests {		buf := NewBufferString(test.buffer)		var err error		for _, expected := range test.expected {			var bytes []byte			bytes, err = buf.ReadBytes(test.delim)			if string(bytes) != expected {				t.Errorf("expected %q, got %q", expected, bytes)			}			if err != nil {				break			}		}		if err != test.err {			t.Errorf("expected error %v, got %v", test.err, err)		}	}} func TestReadString(t *testing.T) {	for _, test := range readBytesTests {		buf := NewBufferString(test.buffer)		var err error		for _, expected := range test.expected {			var s string			s, err = buf.ReadString(test.delim)			if s != expected {				t.Errorf("expected %q, got %q", expected, s)			}			if err != nil {				break			}		}		if err != test.err {			t.Errorf("expected error %v, got %v", test.err, err)		}	}} func BenchmarkReadString(b *testing.B) {	const n = 32 << 10 	data := make([]byte, n)	data[n-1] = 'x'	b.SetBytes(int64(n))	for i := 0; i < b.N; i++ {		buf := NewBuffer(data)		_, err := buf.ReadString('x')		if err != nil {			b.Fatal(err)		}	}} func TestGrow(t *testing.T) {	x := []byte{'x'}	y := []byte{'y'}	tmp := make([]byte, 72)	for _, startLen := range []int{0, 100, 1000, 10000, 100000} {		xBytes := Repeat(x, startLen)		for _, growLen := range []int{0, 100, 1000, 10000, 100000} {			buf := NewBuffer(xBytes)			// If we read, this affects buf.off, which is good to test.			readBytes, _ := buf.Read(tmp)			buf.Grow(growLen)			yBytes := Repeat(y, growLen)			// Check no allocation occurs in write, as long as we're single-threaded.			var m1, m2 runtime.MemStats			runtime.ReadMemStats(&m1)			buf.Write(yBytes)			runtime.ReadMemStats(&m2)			if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {				t.Errorf("allocation occurred during write")			}			// Check that buffer has correct data.			if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {				t.Errorf("bad initial data at %d %d", startLen, growLen)			}			if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {				t.Errorf("bad written data at %d %d", startLen, growLen)			}		}	}} // Was a bug: used to give EOF reading empty slice at EOF.func TestReadEmptyAtEOF(t *testing.T) {	b := new(Buffer)	slice := make([]byte, 0)	n, err := b.Read(slice)	if err != nil {		t.Errorf("read error: %v", err)	}	if n != 0 {		t.Errorf("wrong count; got %d want 0", n)	}} func TestUnreadByte(t *testing.T) {	b := new(Buffer)	b.WriteString("abcdefghijklmnopqrstuvwxyz") 	_, err := b.ReadBytes('m')	if err != nil {		t.Fatalf("ReadBytes: %v", err)	} 	err = b.UnreadByte()	if err != nil {		t.Fatalf("UnreadByte: %v", err)	}	c, err := b.ReadByte()	if err != nil {		t.Fatalf("ReadByte: %v", err)	}	if c != 'm' {		t.Errorf("ReadByte = %q; want %q", c, 'm')	}} // Tests that we occasionally compact. Issue 5154.func TestBufferGrowth(t *testing.T) {	var b Buffer	buf := make([]byte, 1024)	b.Write(buf[0:1])

Lines 1–500 of 544.