Source file src/bufio/bufio_test.go

     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 bufio_test
     6  
     7  import (
     8  	. "bufio"
     9  	"bytes"
    10  	"errors"
    11  	"fmt"
    12  	"internal/asan"
    13  	"io"
    14  	"math/rand"
    15  	"strconv"
    16  	"strings"
    17  	"testing"
    18  	"testing/iotest"
    19  	"time"
    20  	"unicode/utf8"
    21  )
    22  
    23  // Reads from a reader and rot13s the result.
    24  type rot13Reader struct {
    25  	r io.Reader
    26  }
    27  
    28  func newRot13Reader(r io.Reader) *rot13Reader {
    29  	r13 := new(rot13Reader)
    30  	r13.r = r
    31  	return r13
    32  }
    33  
    34  func (r13 *rot13Reader) Read(p []byte) (int, error) {
    35  	n, err := r13.r.Read(p)
    36  	for i := 0; i < n; i++ {
    37  		c := p[i] | 0x20 // lowercase byte
    38  		if 'a' <= c && c <= 'm' {
    39  			p[i] += 13
    40  		} else if 'n' <= c && c <= 'z' {
    41  			p[i] -= 13
    42  		}
    43  	}
    44  	return n, err
    45  }
    46  
    47  // Call ReadByte to accumulate the text of a file
    48  func readBytes(buf *Reader) string {
    49  	var b [1000]byte
    50  	nb := 0
    51  	for {
    52  		c, err := buf.ReadByte()
    53  		if err == io.EOF {
    54  			break
    55  		}
    56  		if err == nil {
    57  			b[nb] = c
    58  			nb++
    59  		} else if err != iotest.ErrTimeout {
    60  			panic("Data: " + err.Error())
    61  		}
    62  	}
    63  	return string(b[0:nb])
    64  }
    65  
    66  func TestReaderSimple(t *testing.T) {
    67  	data := "hello world"
    68  	b := NewReader(strings.NewReader(data))
    69  	if s := readBytes(b); s != "hello world" {
    70  		t.Errorf("simple hello world test failed: got %q", s)
    71  	}
    72  
    73  	b = NewReader(newRot13Reader(strings.NewReader(data)))
    74  	if s := readBytes(b); s != "uryyb jbeyq" {
    75  		t.Errorf("rot13 hello world test failed: got %q", s)
    76  	}
    77  }
    78  
    79  type readMaker struct {
    80  	name string
    81  	fn   func(io.Reader) io.Reader
    82  }
    83  
    84  var readMakers = []readMaker{
    85  	{"full", func(r io.Reader) io.Reader { return r }},
    86  	{"byte", iotest.OneByteReader},
    87  	{"half", iotest.HalfReader},
    88  	{"data+err", iotest.DataErrReader},
    89  	{"timeout", iotest.TimeoutReader},
    90  }
    91  
    92  // Call ReadString (which ends up calling everything else)
    93  // to accumulate the text of a file.
    94  func readLines(b *Reader) string {
    95  	s := ""
    96  	for {
    97  		s1, err := b.ReadString('\n')
    98  		if err == io.EOF {
    99  			break
   100  		}
   101  		if err != nil && err != iotest.ErrTimeout {
   102  			panic("GetLines: " + err.Error())
   103  		}
   104  		s += s1
   105  	}
   106  	return s
   107  }
   108  
   109  // Call Read to accumulate the text of a file
   110  func reads(buf *Reader, m int) string {
   111  	var b [1000]byte
   112  	nb := 0
   113  	for {
   114  		n, err := buf.Read(b[nb : nb+m])
   115  		nb += n
   116  		if err == io.EOF {
   117  			break
   118  		}
   119  	}
   120  	return string(b[0:nb])
   121  }
   122  
   123  type bufReader struct {
   124  	name string
   125  	fn   func(*Reader) string
   126  }
   127  
   128  var bufreaders = []bufReader{
   129  	{"1", func(b *Reader) string { return reads(b, 1) }},
   130  	{"2", func(b *Reader) string { return reads(b, 2) }},
   131  	{"3", func(b *Reader) string { return reads(b, 3) }},
   132  	{"4", func(b *Reader) string { return reads(b, 4) }},
   133  	{"5", func(b *Reader) string { return reads(b, 5) }},
   134  	{"7", func(b *Reader) string { return reads(b, 7) }},
   135  	{"bytes", readBytes},
   136  	{"lines", readLines},
   137  }
   138  
   139  const minReadBufferSize = 16
   140  
   141  var bufsizes = []int{
   142  	0, minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096,
   143  }
   144  
   145  func TestReader(t *testing.T) {
   146  	var texts [31]string
   147  	str := ""
   148  	all := ""
   149  	for i := 0; i < len(texts)-1; i++ {
   150  		texts[i] = str + "\n"
   151  		all += texts[i]
   152  		str += string(rune(i%26 + 'a'))
   153  	}
   154  	texts[len(texts)-1] = all
   155  
   156  	for h := 0; h < len(texts); h++ {
   157  		text := texts[h]
   158  		for i := 0; i < len(readMakers); i++ {
   159  			for j := 0; j < len(bufreaders); j++ {
   160  				for k := 0; k < len(bufsizes); k++ {
   161  					readmaker := readMakers[i]
   162  					bufreader := bufreaders[j]
   163  					bufsize := bufsizes[k]
   164  					read := readmaker.fn(strings.NewReader(text))
   165  					buf := NewReaderSize(read, bufsize)
   166  					s := bufreader.fn(buf)
   167  					if s != text {
   168  						t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
   169  							readmaker.name, bufreader.name, bufsize, text, s)
   170  					}
   171  				}
   172  			}
   173  		}
   174  	}
   175  }
   176  
   177  type zeroReader struct{}
   178  
   179  func (zeroReader) Read(p []byte) (int, error) {
   180  	return 0, nil
   181  }
   182  
   183  func TestZeroReader(t *testing.T) {
   184  	var z zeroReader
   185  	r := NewReader(z)
   186  
   187  	c := make(chan error)
   188  	go func() {
   189  		_, err := r.ReadByte()
   190  		c <- err
   191  	}()
   192  
   193  	select {
   194  	case err := <-c:
   195  		if err == nil {
   196  			t.Error("error expected")
   197  		} else if err != io.ErrNoProgress {
   198  			t.Error("unexpected error:", err)
   199  		}
   200  	case <-time.After(time.Second):
   201  		t.Error("test timed out (endless loop in ReadByte?)")
   202  	}
   203  }
   204  
   205  // A StringReader delivers its data one string segment at a time via Read.
   206  type StringReader struct {
   207  	data []string
   208  	step int
   209  }
   210  
   211  func (r *StringReader) Read(p []byte) (n int, err error) {
   212  	if r.step < len(r.data) {
   213  		s := r.data[r.step]
   214  		n = copy(p, s)
   215  		r.step++
   216  	} else {
   217  		err = io.EOF
   218  	}
   219  	return
   220  }
   221  
   222  func readRuneSegments(t *testing.T, segments []string) {
   223  	got := ""
   224  	want := strings.Join(segments, "")
   225  	r := NewReader(&StringReader{data: segments})
   226  	for {
   227  		r, _, err := r.ReadRune()
   228  		if err != nil {
   229  			if err != io.EOF {
   230  				return
   231  			}
   232  			break
   233  		}
   234  		got += string(r)
   235  	}
   236  	if got != want {
   237  		t.Errorf("segments=%v got=%s want=%s", segments, got, want)
   238  	}
   239  }
   240  
   241  var segmentList = [][]string{
   242  	{},
   243  	{""},
   244  	{"日", "本語"},
   245  	{"\u65e5", "\u672c", "\u8a9e"},
   246  	{"\U000065e5", "\U0000672c", "\U00008a9e"},
   247  	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
   248  	{"Hello", ", ", "World", "!"},
   249  	{"Hello", ", ", "", "World", "!"},
   250  }
   251  
   252  func TestReadRune(t *testing.T) {
   253  	for _, s := range segmentList {
   254  		readRuneSegments(t, s)
   255  	}
   256  }
   257  
   258  func TestUnreadRune(t *testing.T) {
   259  	segments := []string{"Hello, world:", "日本語"}
   260  	r := NewReader(&StringReader{data: segments})
   261  	got := ""
   262  	want := strings.Join(segments, "")
   263  	// Normal execution.
   264  	for {
   265  		r1, _, err := r.ReadRune()
   266  		if err != nil {
   267  			if err != io.EOF {
   268  				t.Error("unexpected error on ReadRune:", err)
   269  			}
   270  			break
   271  		}
   272  		got += string(r1)
   273  		// Put it back and read it again.
   274  		if err = r.UnreadRune(); err != nil {
   275  			t.Fatal("unexpected error on UnreadRune:", err)
   276  		}
   277  		r2, _, err := r.ReadRune()
   278  		if err != nil {
   279  			t.Fatal("unexpected error reading after unreading:", err)
   280  		}
   281  		if r1 != r2 {
   282  			t.Fatalf("incorrect rune after unread: got %c, want %c", r1, r2)
   283  		}
   284  	}
   285  	if got != want {
   286  		t.Errorf("got %q, want %q", got, want)
   287  	}
   288  }
   289  
   290  func TestNoUnreadRuneAfterPeek(t *testing.T) {
   291  	br := NewReader(strings.NewReader("example"))
   292  	br.ReadRune()
   293  	br.Peek(1)
   294  	if err := br.UnreadRune(); err == nil {
   295  		t.Error("UnreadRune didn't fail after Peek")
   296  	}
   297  }
   298  
   299  func TestNoUnreadByteAfterPeek(t *testing.T) {
   300  	br := NewReader(strings.NewReader("example"))
   301  	br.ReadByte()
   302  	br.Peek(1)
   303  	if err := br.UnreadByte(); err == nil {
   304  		t.Error("UnreadByte didn't fail after Peek")
   305  	}
   306  }
   307  
   308  func TestNoUnreadRuneAfterDiscard(t *testing.T) {
   309  	br := NewReader(strings.NewReader("example"))
   310  	br.ReadRune()
   311  	br.Discard(1)
   312  	if err := br.UnreadRune(); err == nil {
   313  		t.Error("UnreadRune didn't fail after Discard")
   314  	}
   315  }
   316  
   317  func TestNoUnreadByteAfterDiscard(t *testing.T) {
   318  	br := NewReader(strings.NewReader("example"))
   319  	br.ReadByte()
   320  	br.Discard(1)
   321  	if err := br.UnreadByte(); err == nil {
   322  		t.Error("UnreadByte didn't fail after Discard")
   323  	}
   324  }
   325  
   326  func TestNoUnreadRuneAfterWriteTo(t *testing.T) {
   327  	br := NewReader(strings.NewReader("example"))
   328  	br.WriteTo(io.Discard)
   329  	if err := br.UnreadRune(); err == nil {
   330  		t.Error("UnreadRune didn't fail after WriteTo")
   331  	}
   332  }
   333  
   334  func TestNoUnreadByteAfterWriteTo(t *testing.T) {
   335  	br := NewReader(strings.NewReader("example"))
   336  	br.WriteTo(io.Discard)
   337  	if err := br.UnreadByte(); err == nil {
   338  		t.Error("UnreadByte didn't fail after WriteTo")
   339  	}
   340  }
   341  
   342  func TestUnreadByte(t *testing.T) {
   343  	segments := []string{"Hello, ", "world"}
   344  	r := NewReader(&StringReader{data: segments})
   345  	got := ""
   346  	want := strings.Join(segments, "")
   347  	// Normal execution.
   348  	for {
   349  		b1, err := r.ReadByte()
   350  		if err != nil {
   351  			if err != io.EOF {
   352  				t.Error("unexpected error on ReadByte:", err)
   353  			}
   354  			break
   355  		}
   356  		got += string(b1)
   357  		// Put it back and read it again.
   358  		if err = r.UnreadByte(); err != nil {
   359  			t.Fatal("unexpected error on UnreadByte:", err)
   360  		}
   361  		b2, err := r.ReadByte()
   362  		if err != nil {
   363  			t.Fatal("unexpected error reading after unreading:", err)
   364  		}
   365  		if b1 != b2 {
   366  			t.Fatalf("incorrect byte after unread: got %q, want %q", b1, b2)
   367  		}
   368  	}
   369  	if got != want {
   370  		t.Errorf("got %q, want %q", got, want)
   371  	}
   372  }
   373  
   374  func TestUnreadByteMultiple(t *testing.T) {
   375  	segments := []string{"Hello, ", "world"}
   376  	data := strings.Join(segments, "")
   377  	for n := 0; n <= len(data); n++ {
   378  		r := NewReader(&StringReader{data: segments})
   379  		// Read n bytes.
   380  		for i := 0; i < n; i++ {
   381  			b, err := r.ReadByte()
   382  			if err != nil {
   383  				t.Fatalf("n = %d: unexpected error on ReadByte: %v", n, err)
   384  			}
   385  			if b != data[i] {
   386  				t.Fatalf("n = %d: incorrect byte returned from ReadByte: got %q, want %q", n, b, data[i])
   387  			}
   388  		}
   389  		// Unread one byte if there is one.
   390  		if n > 0 {
   391  			if err := r.UnreadByte(); err != nil {
   392  				t.Errorf("n = %d: unexpected error on UnreadByte: %v", n, err)
   393  			}
   394  		}
   395  		// Test that we cannot unread any further.
   396  		if err := r.UnreadByte(); err == nil {
   397  			t.Errorf("n = %d: expected error on UnreadByte", n)
   398  		}
   399  	}
   400  }
   401  
   402  func TestUnreadByteOthers(t *testing.T) {
   403  	// A list of readers to use in conjunction with UnreadByte.
   404  	var readers = []func(*Reader, byte) ([]byte, error){
   405  		(*Reader).ReadBytes,
   406  		(*Reader).ReadSlice,
   407  		func(r *Reader, delim byte) ([]byte, error) {
   408  			data, err := r.ReadString(delim)
   409  			return []byte(data), err
   410  		},
   411  		// ReadLine doesn't fit the data/pattern easily
   412  		// so we leave it out. It should be covered via
   413  		// the ReadSlice test since ReadLine simply calls
   414  		// ReadSlice, and it's that function that handles
   415  		// the last byte.
   416  	}
   417  
   418  	// Try all readers with UnreadByte.
   419  	for rno, read := range readers {
   420  		// Some input data that is longer than the minimum reader buffer size.
   421  		const n = 10
   422  		var buf bytes.Buffer
   423  		for i := 0; i < n; i++ {
   424  			buf.WriteString("abcdefg")
   425  		}
   426  
   427  		r := NewReaderSize(&buf, minReadBufferSize)
   428  		readTo := func(delim byte, want string) {
   429  			data, err := read(r, delim)
   430  			if err != nil {
   431  				t.Fatalf("#%d: unexpected error reading to %c: %v", rno, delim, err)
   432  			}
   433  			if got := string(data); got != want {
   434  				t.Fatalf("#%d: got %q, want %q", rno, got, want)
   435  			}
   436  		}
   437  
   438  		// Read the data with occasional UnreadByte calls.
   439  		for i := 0; i < n; i++ {
   440  			readTo('d', "abcd")
   441  			for j := 0; j < 3; j++ {
   442  				if err := r.UnreadByte(); err != nil {
   443  					t.Fatalf("#%d: unexpected error on UnreadByte: %v", rno, err)
   444  				}
   445  				readTo('d', "d")
   446  			}
   447  			readTo('g', "efg")
   448  		}
   449  
   450  		// All data should have been read.
   451  		_, err := r.ReadByte()
   452  		if err != io.EOF {
   453  			t.Errorf("#%d: got error %v; want EOF", rno, err)
   454  		}
   455  	}
   456  }
   457  
   458  // Test that UnreadRune fails if the preceding operation was not a ReadRune.
   459  func TestUnreadRuneError(t *testing.T) {
   460  	buf := make([]byte, 3) // All runes in this test are 3 bytes long
   461  	r := NewReader(&StringReader{data: []string{"日本語日本語日本語"}})
   462  	if r.UnreadRune() == nil {
   463  		t.Error("expected error on UnreadRune from fresh buffer")
   464  	}
   465  	_, _, err := r.ReadRune()
   466  	if err != nil {
   467  		t.Error("unexpected error on ReadRune (1):", err)
   468  	}
   469  	if err = r.UnreadRune(); err != nil {
   470  		t.Error("unexpected error on UnreadRune (1):", err)
   471  	}
   472  	if r.UnreadRune() == nil {
   473  		t.Error("expected error after UnreadRune (1)")
   474  	}
   475  	// Test error after Read.
   476  	_, _, err = r.ReadRune() // reset state
   477  	if err != nil {
   478  		t.Error("unexpected error on ReadRune (2):", err)
   479  	}
   480  	_, err = r.Read(buf)
   481  	if err != nil {
   482  		t.Error("unexpected error on Read (2):", err)
   483  	}
   484  	if r.UnreadRune() == nil {
   485  		t.Error("expected error after Read (2)")
   486  	}
   487  	// Test error after ReadByte.
   488  	_, _, err = r.ReadRune() // reset state
   489  	if err != nil {
   490  		t.Error("unexpected error on ReadRune (2):", err)
   491  	}
   492  	for range buf {
   493  		_, err = r.ReadByte()
   494  		if err != nil {
   495  			t.Error("unexpected error on ReadByte (2):", err)
   496  		}
   497  	}
   498  	if r.UnreadRune() == nil {
   499  		t.Error("expected error after ReadByte")
   500  	}
   501  	// Test error after UnreadByte.
   502  	_, _, err = r.ReadRune() // reset state
   503  	if err != nil {
   504  		t.Error("unexpected error on ReadRune (3):", err)
   505  	}
   506  	_, err = r.ReadByte()
   507  	if err != nil {
   508  		t.Error("unexpected error on ReadByte (3):", err)
   509  	}
   510  	err = r.UnreadByte()
   511  	if err != nil {
   512  		t.Error("unexpected error on UnreadByte (3):", err)
   513  	}
   514  	if r.UnreadRune() == nil {
   515  		t.Error("expected error after UnreadByte (3)")
   516  	}
   517  	// Test error after ReadSlice.
   518  	_, _, err = r.ReadRune() // reset state
   519  	if err != nil {
   520  		t.Error("unexpected error on ReadRune (4):", err)
   521  	}
   522  	_, err = r.ReadSlice(0)
   523  	if err != io.EOF {
   524  		t.Error("unexpected error on ReadSlice (4):", err)
   525  	}
   526  	if r.UnreadRune() == nil {
   527  		t.Error("expected error after ReadSlice (4)")
   528  	}
   529  }
   530  
   531  func TestUnreadRuneAtEOF(t *testing.T) {
   532  	// UnreadRune/ReadRune should error at EOF (was a bug; used to panic)
   533  	r := NewReader(strings.NewReader("x"))
   534  	r.ReadRune()
   535  	r.ReadRune()
   536  	r.UnreadRune()
   537  	_, _, err := r.ReadRune()
   538  	if err == nil {
   539  		t.Error("expected error at EOF")
   540  	} else if err != io.EOF {
   541  		t.Error("expected EOF; got", err)
   542  	}
   543  }
   544  
   545  func TestReadWriteRune(t *testing.T) {
   546  	const NRune = 1000
   547  	byteBuf := new(bytes.Buffer)
   548  	w := NewWriter(byteBuf)
   549  	// Write the runes out using WriteRune
   550  	buf := make([]byte, utf8.UTFMax)
   551  	for r := rune(0); r < NRune; r++ {
   552  		size := utf8.EncodeRune(buf, r)
   553  		nbytes, err := w.WriteRune(r)
   554  		if err != nil {
   555  			t.Fatalf("WriteRune(0x%x) error: %s", r, err)
   556  		}
   557  		if nbytes != size {
   558  			t.Fatalf("WriteRune(0x%x) expected %d, got %d", r, size, nbytes)
   559  		}
   560  	}
   561  	w.Flush()
   562  
   563  	r := NewReader(byteBuf)
   564  	// Read them back with ReadRune
   565  	for r1 := rune(0); r1 < NRune; r1++ {
   566  		size := utf8.EncodeRune(buf, r1)
   567  		nr, nbytes, err := r.ReadRune()
   568  		if nr != r1 || nbytes != size || err != nil {
   569  			t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r1, nr, nbytes, r1, size, err)
   570  		}
   571  	}
   572  }
   573  
   574  func TestWriteInvalidRune(t *testing.T) {
   575  	// Invalid runes, including negative ones, should be written as the
   576  	// replacement character.
   577  	for _, r := range []rune{-1, utf8.MaxRune + 1} {
   578  		var buf strings.Builder
   579  		w := NewWriter(&buf)
   580  		w.WriteRune(r)
   581  		w.Flush()
   582  		if s := buf.String(); s != "\uFFFD" {
   583  			t.Errorf("WriteRune(%d) wrote %q, not replacement character", r, s)
   584  		}
   585  	}
   586  }
   587  
   588  func TestReadStringAllocs(t *testing.T) {
   589  	if asan.Enabled {
   590  		t.Skip("test allocates more with -asan; see #70079")
   591  	}
   592  	r := strings.NewReader("       foo       foo        42        42        42        42        42        42        42        42       4.2       4.2       4.2       4.2\n")
   593  	buf := NewReader(r)
   594  	allocs := testing.AllocsPerRun(100, func() {
   595  		r.Seek(0, io.SeekStart)
   596  		buf.Reset(r)
   597  
   598  		_, err := buf.ReadString('\n')
   599  		if err != nil {
   600  			t.Fatal(err)
   601  		}
   602  	})
   603  	if allocs != 1 {
   604  		t.Errorf("Unexpected number of allocations, got %f, want 1", allocs)
   605  	}
   606  }
   607  
   608  func TestWriter(t *testing.T) {
   609  	var data [8192]byte
   610  
   611  	for i := 0; i < len(data); i++ {
   612  		data[i] = byte(' ' + i%('~'-' '))
   613  	}
   614  	w := new(bytes.Buffer)
   615  	for i := 0; i < len(bufsizes); i++ {
   616  		for j := 0; j < len(bufsizes); j++ {
   617  			nwrite := bufsizes[i]
   618  			bs := bufsizes[j]
   619  
   620  			// Write nwrite bytes using buffer size bs.
   621  			// Check that the right amount makes it out
   622  			// and that the data is correct.
   623  
   624  			w.Reset()
   625  			buf := NewWriterSize(w, bs)
   626  			context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs)
   627  			n, e1 := buf.Write(data[0:nwrite])
   628  			if e1 != nil || n != nwrite {
   629  				t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1)
   630  				continue
   631  			}
   632  			if e := buf.Flush(); e != nil {
   633  				t.Errorf("%s: buf.Flush = %v", context, e)
   634  			}
   635  
   636  			written := w.Bytes()
   637  			if len(written) != nwrite {
   638  				t.Errorf("%s: %d bytes written", context, len(written))
   639  			}
   640  			for l := 0; l < len(written); l++ {
   641  				if written[l] != data[l] {
   642  					t.Errorf("wrong bytes written")
   643  					t.Errorf("want=%q", data[:len(written)])
   644  					t.Errorf("have=%q", written)
   645  				}
   646  			}
   647  		}
   648  	}
   649  }
   650  
   651  func TestWriterAppend(t *testing.T) {
   652  	got := new(bytes.Buffer)
   653  	var want []byte
   654  	rn := rand.New(rand.NewSource(0))
   655  	w := NewWriterSize(got, 64)
   656  	for i := 0; i < 100; i++ {
   657  		// Obtain a buffer to append to.
   658  		b := w.AvailableBuffer()
   659  		if w.Available() != cap(b) {
   660  			t.Fatalf("Available() = %v, want %v", w.Available(), cap(b))
   661  		}
   662  
   663  		// While not recommended, it is valid to append to a shifted buffer.
   664  		// This forces Write to copy the input.
   665  		if rn.Intn(8) == 0 && cap(b) > 0 {
   666  			b = b[1:1:cap(b)]
   667  		}
   668  
   669  		// Append a random integer of varying width.
   670  		n := int64(rn.Intn(1 << rn.Intn(30)))
   671  		want = append(strconv.AppendInt(want, n, 10), ' ')
   672  		b = append(strconv.AppendInt(b, n, 10), ' ')
   673  		w.Write(b)
   674  	}
   675  	w.Flush()
   676  
   677  	if !bytes.Equal(got.Bytes(), want) {
   678  		t.Errorf("output mismatch:\ngot  %s\nwant %s", got.Bytes(), want)
   679  	}
   680  }
   681  
   682  // Check that write errors are returned properly.
   683  
   684  type errorWriterTest struct {
   685  	n, m   int
   686  	err    error
   687  	expect error
   688  }
   689  
   690  func (w errorWriterTest) Write(p []byte) (int, error) {
   691  	return len(p) * w.n / w.m, w.err
   692  }
   693  
   694  var errorWriterTests = []errorWriterTest{
   695  	{0, 1, nil, io.ErrShortWrite},
   696  	{1, 2, nil, io.ErrShortWrite},
   697  	{1, 1, nil, nil},
   698  	{0, 1, io.ErrClosedPipe, io.ErrClosedPipe},
   699  	{1, 2, io.ErrClosedPipe, io.ErrClosedPipe},
   700  	{1, 1, io.ErrClosedPipe, io.ErrClosedPipe},
   701  }
   702  
   703  func TestWriteErrors(t *testing.T) {
   704  	for _, w := range errorWriterTests {
   705  		buf := NewWriter(w)
   706  		_, e := buf.Write([]byte("hello world"))
   707  		if e != nil {
   708  			t.Errorf("Write hello to %v: %v", w, e)
   709  			continue
   710  		}
   711  		// Two flushes, to verify the error is sticky.
   712  		for i := 0; i < 2; i++ {
   713  			e = buf.Flush()
   714  			if e != w.expect {
   715  				t.Errorf("Flush %d/2 %v: got %v, wanted %v", i+1, w, e, w.expect)
   716  			}
   717  		}
   718  	}
   719  }
   720  
   721  func TestNewReaderSizeIdempotent(t *testing.T) {
   722  	const BufSize = 1000
   723  	b := NewReaderSize(strings.NewReader("hello world"), BufSize)
   724  	// Does it recognize itself?
   725  	b1 := NewReaderSize(b, BufSize)
   726  	if b1 != b {
   727  		t.Error("NewReaderSize did not detect underlying Reader")
   728  	}
   729  	// Does it wrap if existing buffer is too small?
   730  	b2 := NewReaderSize(b, 2*BufSize)
   731  	if b2 == b {
   732  		t.Error("NewReaderSize did not enlarge buffer")
   733  	}
   734  }
   735  
   736  func TestNewWriterSizeIdempotent(t *testing.T) {
   737  	const BufSize = 1000
   738  	b := NewWriterSize(new(bytes.Buffer), BufSize)
   739  	// Does it recognize itself?
   740  	b1 := NewWriterSize(b, BufSize)
   741  	if b1 != b {
   742  		t.Error("NewWriterSize did not detect underlying Writer")
   743  	}
   744  	// Does it wrap if existing buffer is too small?
   745  	b2 := NewWriterSize(b, 2*BufSize)
   746  	if b2 == b {
   747  		t.Error("NewWriterSize did not enlarge buffer")
   748  	}
   749  }
   750  
   751  func TestWriteString(t *testing.T) {
   752  	const BufSize = 8
   753  	buf := new(strings.Builder)
   754  	b := NewWriterSize(buf, BufSize)
   755  	b.WriteString("0")                         // easy
   756  	b.WriteString("123456")                    // still easy
   757  	b.WriteString("7890")                      // easy after flush
   758  	b.WriteString("abcdefghijklmnopqrstuvwxy") // hard
   759  	b.WriteString("z")
   760  	if err := b.Flush(); err != nil {
   761  		t.Error("WriteString", err)
   762  	}
   763  	s := "01234567890abcdefghijklmnopqrstuvwxyz"
   764  	if buf.String() != s {
   765  		t.Errorf("WriteString wants %q gets %q", s, buf.String())
   766  	}
   767  }
   768  
   769  func TestWriteStringStringWriter(t *testing.T) {
   770  	const BufSize = 8
   771  	{
   772  		tw := &teststringwriter{}
   773  		b := NewWriterSize(tw, BufSize)
   774  		b.WriteString("1234")
   775  		tw.check(t, "", "")
   776  		b.WriteString("56789012")   // longer than BufSize
   777  		tw.check(t, "12345678", "") // but not enough (after filling the partially-filled buffer)
   778  		b.Flush()
   779  		tw.check(t, "123456789012", "")
   780  	}
   781  	{
   782  		tw := &teststringwriter{}
   783  		b := NewWriterSize(tw, BufSize)
   784  		b.WriteString("123456789")   // long string, empty buffer:
   785  		tw.check(t, "", "123456789") // use WriteString
   786  	}
   787  	{
   788  		tw := &teststringwriter{}
   789  		b := NewWriterSize(tw, BufSize)
   790  		b.WriteString("abc")
   791  		tw.check(t, "", "")
   792  		b.WriteString("123456789012345")      // long string, non-empty buffer
   793  		tw.check(t, "abc12345", "6789012345") // use Write and then WriteString since the remaining part is still longer than BufSize
   794  	}
   795  	{
   796  		tw := &teststringwriter{}
   797  		b := NewWriterSize(tw, BufSize)
   798  		b.Write([]byte("abc")) // same as above, but use Write instead of WriteString
   799  		tw.check(t, "", "")
   800  		b.WriteString("123456789012345")
   801  		tw.check(t, "abc12345", "6789012345") // same as above
   802  	}
   803  }
   804  
   805  type teststringwriter struct {
   806  	write       string
   807  	writeString string
   808  }
   809  
   810  func (w *teststringwriter) Write(b []byte) (int, error) {
   811  	w.write += string(b)
   812  	return len(b), nil
   813  }
   814  
   815  func (w *teststringwriter) WriteString(s string) (int, error) {
   816  	w.writeString += s
   817  	return len(s), nil
   818  }
   819  
   820  func (w *teststringwriter) check(t *testing.T, write, writeString string) {
   821  	t.Helper()
   822  	if w.write != write {
   823  		t.Errorf("write: expected %q, got %q", write, w.write)
   824  	}
   825  	if w.writeString != writeString {
   826  		t.Errorf("writeString: expected %q, got %q", writeString, w.writeString)
   827  	}
   828  }
   829  
   830  func TestBufferFull(t *testing.T) {
   831  	const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party"
   832  	buf := NewReaderSize(strings.NewReader(longString), minReadBufferSize)
   833  	line, err := buf.ReadSlice('!')
   834  	if string(line) != "And now, hello, " || err != ErrBufferFull {
   835  		t.Errorf("first ReadSlice(,) = %q, %v", line, err)
   836  	}
   837  	line, err = buf.ReadSlice('!')
   838  	if string(line) != "world!" || err != nil {
   839  		t.Errorf("second ReadSlice(,) = %q, %v", line, err)
   840  	}
   841  }
   842  
   843  func TestPeek(t *testing.T) {
   844  	p := make([]byte, 10)
   845  	// string is 16 (minReadBufferSize) long.
   846  	buf := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize)
   847  	if s, err := buf.Peek(1); string(s) != "a" || err != nil {
   848  		t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
   849  	}
   850  	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
   851  		t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err)
   852  	}
   853  	if _, err := buf.Peek(-1); err != ErrNegativeCount {
   854  		t.Fatalf("want ErrNegativeCount got %v", err)
   855  	}
   856  	if s, err := buf.Peek(32); string(s) != "abcdefghijklmnop" || err != ErrBufferFull {
   857  		t.Fatalf("want %q, ErrBufFull got %q, err=%v", "abcdefghijklmnop", string(s), err)
   858  	}
   859  	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil {
   860  		t.Fatalf("want %q got %q, err=%v", "abc", string(p[0:3]), err)
   861  	}
   862  	if s, err := buf.Peek(1); string(s) != "d" || err != nil {
   863  		t.Fatalf("want %q got %q, err=%v", "d", string(s), err)
   864  	}
   865  	if s, err := buf.Peek(2); string(s) != "de" || err != nil {
   866  		t.Fatalf("want %q got %q, err=%v", "de", string(s), err)
   867  	}
   868  	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "def" || err != nil {
   869  		t.Fatalf("want %q got %q, err=%v", "def", string(p[0:3]), err)
   870  	}
   871  	if s, err := buf.Peek(4); string(s) != "ghij" || err != nil {
   872  		t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err)
   873  	}
   874  	if _, err := buf.Read(p[0:]); string(p[0:]) != "ghijklmnop" || err != nil {
   875  		t.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p[0:minReadBufferSize]), err)
   876  	}
   877  	if s, err := buf.Peek(0); string(s) != "" || err != nil {
   878  		t.Fatalf("want %q got %q, err=%v", "", string(s), err)
   879  	}
   880  	if _, err := buf.Peek(1); err != io.EOF {
   881  		t.Fatalf("want EOF got %v", err)
   882  	}
   883  
   884  	// Test for issue 3022, not exposing a reader's error on a successful Peek.
   885  	buf = NewReaderSize(dataAndEOFReader("abcd"), 32)
   886  	if s, err := buf.Peek(2); string(s) != "ab" || err != nil {
   887  		t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err)
   888  	}
   889  	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
   890  		t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err)
   891  	}
   892  	if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil {
   893  		t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err)
   894  	}
   895  	if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF {
   896  		t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err)
   897  	}
   898  }
   899  
   900  type dataAndEOFReader string
   901  
   902  func (r dataAndEOFReader) Read(p []byte) (int, error) {
   903  	return copy(p, r), io.EOF
   904  }
   905  
   906  func TestPeekThenUnreadRune(t *testing.T) {
   907  	// This sequence used to cause a crash.
   908  	r := NewReader(strings.NewReader("x"))
   909  	r.ReadRune()
   910  	r.Peek(1)
   911  	r.UnreadRune()
   912  	r.ReadRune() // Used to panic here
   913  }
   914  
   915  var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy")
   916  var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")
   917  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")
   918  
   919  // TestReader wraps a []byte and returns reads of a specific length.
   920  type testReader struct {
   921  	data   []byte
   922  	stride int
   923  }
   924  
   925  func (t *testReader) Read(buf []byte) (n int, err error) {
   926  	n = t.stride
   927  	if n > len(t.data) {
   928  		n = len(t.data)
   929  	}
   930  	if n > len(buf) {
   931  		n = len(buf)
   932  	}
   933  	copy(buf, t.data)
   934  	t.data = t.data[n:]
   935  	if len(t.data) == 0 {
   936  		err = io.EOF
   937  	}
   938  	return
   939  }
   940  
   941  func testReadLine(t *testing.T, input []byte) {
   942  	for stride := 1; stride < 2; stride++ {
   943  		done := 0
   944  		reader := testReader{input, stride}
   945  		l := NewReaderSize(&reader, len(input)+1)
   946  		for {
   947  			line, isPrefix, err := l.ReadLine()
   948  			if len(line) > 0 && err != nil {
   949  				t.Errorf("ReadLine returned both data and error: %s", err)
   950  			}
   951  			if isPrefix {
   952  				t.Errorf("ReadLine returned prefix")
   953  			}
   954  			if err != nil {
   955  				if err != io.EOF {
   956  					t.Fatalf("Got unknown error: %s", err)
   957  				}
   958  				break
   959  			}
   960  			if want := testOutput[done : done+len(line)]; !bytes.Equal(want, line) {
   961  				t.Errorf("Bad line at stride %d: want: %x got: %x", stride, want, line)
   962  			}
   963  			done += len(line)
   964  		}
   965  		if done != len(testOutput) {
   966  			t.Errorf("ReadLine didn't return everything: got: %d, want: %d (stride: %d)", done, len(testOutput), stride)
   967  		}
   968  	}
   969  }
   970  
   971  func TestReadLine(t *testing.T) {
   972  	testReadLine(t, testInput)
   973  	testReadLine(t, testInputrn)
   974  }
   975  
   976  func TestLineTooLong(t *testing.T) {
   977  	data := make([]byte, 0)
   978  	for i := 0; i < minReadBufferSize*5/2; i++ {
   979  		data = append(data, '0'+byte(i%10))
   980  	}
   981  	buf := bytes.NewReader(data)
   982  	l := NewReaderSize(buf, minReadBufferSize)
   983  	line, isPrefix, err := l.ReadLine()
   984  	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
   985  		t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err)
   986  	}
   987  	data = data[len(line):]
   988  	line, isPrefix, err = l.ReadLine()
   989  	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
   990  		t.Errorf("bad result for second line: got %q want %q %v", line, data[:minReadBufferSize], err)
   991  	}
   992  	data = data[len(line):]
   993  	line, isPrefix, err = l.ReadLine()
   994  	if isPrefix || !bytes.Equal(line, data[:minReadBufferSize/2]) || err != nil {
   995  		t.Errorf("bad result for third line: got %q want %q %v", line, data[:minReadBufferSize/2], err)
   996  	}
   997  	line, isPrefix, err = l.ReadLine()
   998  	if isPrefix || err == nil {
   999  		t.Errorf("expected no more lines: %x %s", line, err)
  1000  	}
  1001  }
  1002  
  1003  func TestReadAfterLines(t *testing.T) {
  1004  	line1 := "this is line1"
  1005  	restData := "this is line2\nthis is line 3\n"
  1006  	inbuf := bytes.NewReader([]byte(line1 + "\n" + restData))
  1007  	outbuf := new(strings.Builder)
  1008  	maxLineLength := len(line1) + len(restData)/2
  1009  	l := NewReaderSize(inbuf, maxLineLength)
  1010  	line, isPrefix, err := l.ReadLine()
  1011  	if isPrefix || err != nil || string(line) != line1 {
  1012  		t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line))
  1013  	}
  1014  	n, err := io.Copy(outbuf, l)
  1015  	if int(n) != len(restData) || err != nil {
  1016  		t.Errorf("bad result for Read: n=%d err=%v", n, err)
  1017  	}
  1018  	if outbuf.String() != restData {
  1019  		t.Errorf("bad result for Read: got %q; expected %q", outbuf.String(), restData)
  1020  	}
  1021  }
  1022  
  1023  func TestReadEmptyBuffer(t *testing.T) {
  1024  	l := NewReaderSize(new(bytes.Buffer), minReadBufferSize)
  1025  	line, isPrefix, err := l.ReadLine()
  1026  	if err != io.EOF {
  1027  		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
  1028  	}
  1029  }
  1030  
  1031  func TestLinesAfterRead(t *testing.T) {
  1032  	l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize)
  1033  	_, err := io.ReadAll(l)
  1034  	if err != nil {
  1035  		t.Error(err)
  1036  		return
  1037  	}
  1038  
  1039  	line, isPrefix, err := l.ReadLine()
  1040  	if err != io.EOF {
  1041  		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
  1042  	}
  1043  }
  1044  
  1045  func TestReadLineNonNilLineOrError(t *testing.T) {
  1046  	r := NewReader(strings.NewReader("line 1\n"))
  1047  	for i := 0; i < 2; i++ {
  1048  		l, _, err := r.ReadLine()
  1049  		if l != nil && err != nil {
  1050  			t.Fatalf("on line %d/2; ReadLine=%#v, %v; want non-nil line or Error, but not both",
  1051  				i+1, l, err)
  1052  		}
  1053  	}
  1054  }
  1055  
  1056  type readLineResult struct {
  1057  	line     []byte
  1058  	isPrefix bool
  1059  	err      error
  1060  }
  1061  
  1062  var readLineNewlinesTests = []struct {
  1063  	input  string
  1064  	expect []readLineResult
  1065  }{
  1066  	{"012345678901234\r\n012345678901234\r\n", []readLineResult{
  1067  		{[]byte("012345678901234"), true, nil},
  1068  		{nil, false, nil},
  1069  		{[]byte("012345678901234"), true, nil},
  1070  		{nil, false, nil},
  1071  		{nil, false, io.EOF},
  1072  	}},
  1073  	{"0123456789012345\r012345678901234\r", []readLineResult{
  1074  		{[]byte("0123456789012345"), true, nil},
  1075  		{[]byte("\r012345678901234"), true, nil},
  1076  		{[]byte("\r"), false, nil},
  1077  		{nil, false, io.EOF},
  1078  	}},
  1079  }
  1080  
  1081  func TestReadLineNewlines(t *testing.T) {
  1082  	for _, e := range readLineNewlinesTests {
  1083  		testReadLineNewlines(t, e.input, e.expect)
  1084  	}
  1085  }
  1086  
  1087  func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) {
  1088  	b := NewReaderSize(strings.NewReader(input), minReadBufferSize)
  1089  	for i, e := range expect {
  1090  		line, isPrefix, err := b.ReadLine()
  1091  		if !bytes.Equal(line, e.line) {
  1092  			t.Errorf("%q call %d, line == %q, want %q", input, i, line, e.line)
  1093  			return
  1094  		}
  1095  		if isPrefix != e.isPrefix {
  1096  			t.Errorf("%q call %d, isPrefix == %v, want %v", input, i, isPrefix, e.isPrefix)
  1097  			return
  1098  		}
  1099  		if err != e.err {
  1100  			t.Errorf("%q call %d, err == %v, want %v", input, i, err, e.err)
  1101  			return
  1102  		}
  1103  	}
  1104  }
  1105  
  1106  func createTestInput(n int) []byte {
  1107  	input := make([]byte, n)
  1108  	for i := range input {
  1109  		// 101 and 251 are arbitrary prime numbers.
  1110  		// The idea is to create an input sequence
  1111  		// which doesn't repeat too frequently.
  1112  		input[i] = byte(i % 251)
  1113  		if i%101 == 0 {
  1114  			input[i] ^= byte(i / 101)
  1115  		}
  1116  	}
  1117  	return input
  1118  }
  1119  
  1120  func TestReaderWriteTo(t *testing.T) {
  1121  	input := createTestInput(8192)
  1122  	r := NewReader(onlyReader{bytes.NewReader(input)})
  1123  	w := new(bytes.Buffer)
  1124  	if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) {
  1125  		t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(input))
  1126  	}
  1127  
  1128  	for i, val := range w.Bytes() {
  1129  		if val != input[i] {
  1130  			t.Errorf("after write: out[%d] = %#x, want %#x", i, val, input[i])
  1131  		}
  1132  	}
  1133  }
  1134  
  1135  type errorWriterToTest struct {
  1136  	rn, wn     int
  1137  	rerr, werr error
  1138  	expected   error
  1139  }
  1140  
  1141  func (r errorWriterToTest) Read(p []byte) (int, error) {
  1142  	return len(p) * r.rn, r.rerr
  1143  }
  1144  
  1145  func (w errorWriterToTest) Write(p []byte) (int, error) {
  1146  	return len(p) * w.wn, w.werr
  1147  }
  1148  
  1149  var errorWriterToTests = []errorWriterToTest{
  1150  	{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
  1151  	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
  1152  	{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe},
  1153  	{0, 1, io.EOF, nil, nil},
  1154  }
  1155  
  1156  func TestReaderWriteToErrors(t *testing.T) {
  1157  	for i, rw := range errorWriterToTests {
  1158  		r := NewReader(rw)
  1159  		if _, err := r.WriteTo(rw); err != rw.expected {
  1160  			t.Errorf("r.WriteTo(errorWriterToTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
  1161  		}
  1162  	}
  1163  }
  1164  
  1165  func TestWriterReadFrom(t *testing.T) {
  1166  	ws := []func(io.Writer) io.Writer{
  1167  		func(w io.Writer) io.Writer { return onlyWriter{w} },
  1168  		func(w io.Writer) io.Writer { return w },
  1169  	}
  1170  
  1171  	rs := []func(io.Reader) io.Reader{
  1172  		iotest.DataErrReader,
  1173  		func(r io.Reader) io.Reader { return r },
  1174  	}
  1175  
  1176  	for ri, rfunc := range rs {
  1177  		for wi, wfunc := range ws {
  1178  			input := createTestInput(8192)
  1179  			b := new(strings.Builder)
  1180  			w := NewWriter(wfunc(b))
  1181  			r := rfunc(bytes.NewReader(input))
  1182  			if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) {
  1183  				t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
  1184  				continue
  1185  			}
  1186  			if err := w.Flush(); err != nil {
  1187  				t.Errorf("Flush returned %v", err)
  1188  				continue
  1189  			}
  1190  			if got, want := b.String(), string(input); got != want {
  1191  				t.Errorf("ws[%d], rs[%d]:\ngot  %q\nwant %q\n", wi, ri, got, want)
  1192  			}
  1193  		}
  1194  	}
  1195  }
  1196  
  1197  type errorReaderFromTest struct {
  1198  	rn, wn     int
  1199  	rerr, werr error
  1200  	expected   error
  1201  }
  1202  
  1203  func (r errorReaderFromTest) Read(p []byte) (int, error) {
  1204  	return len(p) * r.rn, r.rerr
  1205  }
  1206  
  1207  func (w errorReaderFromTest) Write(p []byte) (int, error) {
  1208  	return len(p) * w.wn, w.werr
  1209  }
  1210  
  1211  var errorReaderFromTests = []errorReaderFromTest{
  1212  	{0, 1, io.EOF, nil, nil},
  1213  	{1, 1, io.EOF, nil, nil},
  1214  	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
  1215  	{0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe},
  1216  	{1, 0, nil, io.ErrShortWrite, io.ErrShortWrite},
  1217  }
  1218  
  1219  func TestWriterReadFromErrors(t *testing.T) {
  1220  	for i, rw := range errorReaderFromTests {
  1221  		w := NewWriter(rw)
  1222  		if _, err := w.ReadFrom(rw); err != rw.expected {
  1223  			t.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
  1224  		}
  1225  	}
  1226  }
  1227  
  1228  // TestWriterReadFromCounts tests that using io.Copy to copy into a
  1229  // bufio.Writer does not prematurely flush the buffer. For example, when
  1230  // buffering writes to a network socket, excessive network writes should be
  1231  // avoided.
  1232  func TestWriterReadFromCounts(t *testing.T) {
  1233  	var w0 writeCountingDiscard
  1234  	b0 := NewWriterSize(&w0, 1234)
  1235  	b0.WriteString(strings.Repeat("x", 1000))
  1236  	if w0 != 0 {
  1237  		t.Fatalf("write 1000 'x's: got %d writes, want 0", w0)
  1238  	}
  1239  	b0.WriteString(strings.Repeat("x", 200))
  1240  	if w0 != 0 {
  1241  		t.Fatalf("write 1200 'x's: got %d writes, want 0", w0)
  1242  	}
  1243  	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 30))})
  1244  	if w0 != 0 {
  1245  		t.Fatalf("write 1230 'x's: got %d writes, want 0", w0)
  1246  	}
  1247  	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 9))})
  1248  	if w0 != 1 {
  1249  		t.Fatalf("write 1239 'x's: got %d writes, want 1", w0)
  1250  	}
  1251  
  1252  	var w1 writeCountingDiscard
  1253  	b1 := NewWriterSize(&w1, 1234)
  1254  	b1.WriteString(strings.Repeat("x", 1200))
  1255  	b1.Flush()
  1256  	if w1 != 1 {
  1257  		t.Fatalf("flush 1200 'x's: got %d writes, want 1", w1)
  1258  	}
  1259  	b1.WriteString(strings.Repeat("x", 89))
  1260  	if w1 != 1 {
  1261  		t.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1)
  1262  	}
  1263  	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 700))})
  1264  	if w1 != 1 {
  1265  		t.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1)
  1266  	}
  1267  	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 600))})
  1268  	if w1 != 2 {
  1269  		t.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1)
  1270  	}
  1271  	b1.Flush()
  1272  	if w1 != 3 {
  1273  		t.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1)
  1274  	}
  1275  }
  1276  
  1277  // A writeCountingDiscard is like io.Discard and counts the number of times
  1278  // Write is called on it.
  1279  type writeCountingDiscard int
  1280  
  1281  func (w *writeCountingDiscard) Write(p []byte) (int, error) {
  1282  	*w++
  1283  	return len(p), nil
  1284  }
  1285  
  1286  type negativeReader int
  1287  
  1288  func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
  1289  
  1290  func TestNegativeRead(t *testing.T) {
  1291  	// should panic with a description pointing at the reader, not at itself.
  1292  	// (should NOT panic with slice index error, for example.)
  1293  	b := NewReader(new(negativeReader))
  1294  	defer func() {
  1295  		switch err := recover().(type) {
  1296  		case nil:
  1297  			t.Fatal("read did not panic")
  1298  		case error:
  1299  			if !strings.Contains(err.Error(), "reader returned negative count from Read") {
  1300  				t.Fatalf("wrong panic: %v", err)
  1301  			}
  1302  		default:
  1303  			t.Fatalf("unexpected panic value: %T(%v)", err, err)
  1304  		}
  1305  	}()
  1306  	b.Read(make([]byte, 100))
  1307  }
  1308  
  1309  var errFake = errors.New("fake error")
  1310  
  1311  type errorThenGoodReader struct {
  1312  	didErr bool
  1313  	nread  int
  1314  }
  1315  
  1316  func (r *errorThenGoodReader) Read(p []byte) (int, error) {
  1317  	r.nread++
  1318  	if !r.didErr {
  1319  		r.didErr = true
  1320  		return 0, errFake
  1321  	}
  1322  	return len(p), nil
  1323  }
  1324  
  1325  func TestReaderClearError(t *testing.T) {
  1326  	r := &errorThenGoodReader{}
  1327  	b := NewReader(r)
  1328  	buf := make([]byte, 1)
  1329  	if _, err := b.Read(nil); err != nil {
  1330  		t.Fatalf("1st nil Read = %v; want nil", err)
  1331  	}
  1332  	if _, err := b.Read(buf); err != errFake {
  1333  		t.Fatalf("1st Read = %v; want errFake", err)
  1334  	}
  1335  	if _, err := b.Read(nil); err != nil {
  1336  		t.Fatalf("2nd nil Read = %v; want nil", err)
  1337  	}
  1338  	if _, err := b.Read(buf); err != nil {
  1339  		t.Fatalf("3rd Read with buffer = %v; want nil", err)
  1340  	}
  1341  	if r.nread != 2 {
  1342  		t.Errorf("num reads = %d; want 2", r.nread)
  1343  	}
  1344  }
  1345  
  1346  // Test for golang.org/issue/5947
  1347  func TestWriterReadFromWhileFull(t *testing.T) {
  1348  	buf := new(bytes.Buffer)
  1349  	w := NewWriterSize(buf, 10)
  1350  
  1351  	// Fill buffer exactly.
  1352  	n, err := w.Write([]byte("0123456789"))
  1353  	if n != 10 || err != nil {
  1354  		t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err)
  1355  	}
  1356  
  1357  	// Use ReadFrom to read in some data.
  1358  	n2, err := w.ReadFrom(strings.NewReader("abcdef"))
  1359  	if n2 != 6 || err != nil {
  1360  		t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n2, err)
  1361  	}
  1362  }
  1363  
  1364  type emptyThenNonEmptyReader struct {
  1365  	r io.Reader
  1366  	n int
  1367  }
  1368  
  1369  func (r *emptyThenNonEmptyReader) Read(p []byte) (int, error) {
  1370  	if r.n <= 0 {
  1371  		return r.r.Read(p)
  1372  	}
  1373  	r.n--
  1374  	return 0, nil
  1375  }
  1376  
  1377  // Test for golang.org/issue/7611
  1378  func TestWriterReadFromUntilEOF(t *testing.T) {
  1379  	buf := new(bytes.Buffer)
  1380  	w := NewWriterSize(buf, 5)
  1381  
  1382  	// Partially fill buffer
  1383  	n, err := w.Write([]byte("0123"))
  1384  	if n != 4 || err != nil {
  1385  		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
  1386  	}
  1387  
  1388  	// Use ReadFrom to read in some data.
  1389  	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 3}
  1390  	n2, err := w.ReadFrom(r)
  1391  	if n2 != 4 || err != nil {
  1392  		t.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2, err)
  1393  	}
  1394  	w.Flush()
  1395  	if got, want := buf.String(), "0123abcd"; got != want {
  1396  		t.Fatalf("buf.Bytes() returned %q, want %q", got, want)
  1397  	}
  1398  }
  1399  
  1400  func TestWriterReadFromErrNoProgress(t *testing.T) {
  1401  	buf := new(bytes.Buffer)
  1402  	w := NewWriterSize(buf, 5)
  1403  
  1404  	// Partially fill buffer
  1405  	n, err := w.Write([]byte("0123"))
  1406  	if n != 4 || err != nil {
  1407  		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
  1408  	}
  1409  
  1410  	// Use ReadFrom to read in some data.
  1411  	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 100}
  1412  	n2, err := w.ReadFrom(r)
  1413  	if n2 != 0 || err != io.ErrNoProgress {
  1414  		t.Fatalf("buf.Bytes() returned (%v, %v), want (0, io.ErrNoProgress)", n2, err)
  1415  	}
  1416  }
  1417  
  1418  type readFromWriter struct {
  1419  	buf           []byte
  1420  	writeBytes    int
  1421  	readFromBytes int
  1422  }
  1423  
  1424  func (w *readFromWriter) Write(p []byte) (int, error) {
  1425  	w.buf = append(w.buf, p...)
  1426  	w.writeBytes += len(p)
  1427  	return len(p), nil
  1428  }
  1429  
  1430  func (w *readFromWriter) ReadFrom(r io.Reader) (int64, error) {
  1431  	b, err := io.ReadAll(r)
  1432  	w.buf = append(w.buf, b...)
  1433  	w.readFromBytes += len(b)
  1434  	return int64(len(b)), err
  1435  }
  1436  
  1437  // Test that calling (*Writer).ReadFrom with a partially-filled buffer
  1438  // fills the buffer before switching over to ReadFrom.
  1439  func TestWriterReadFromWithBufferedData(t *testing.T) {
  1440  	const bufsize = 16
  1441  
  1442  	input := createTestInput(64)
  1443  	rfw := &readFromWriter{}
  1444  	w := NewWriterSize(rfw, bufsize)
  1445  
  1446  	const writeSize = 8
  1447  	if n, err := w.Write(input[:writeSize]); n != writeSize || err != nil {
  1448  		t.Errorf("w.Write(%v bytes) = %v, %v; want %v, nil", writeSize, n, err, writeSize)
  1449  	}
  1450  	n, err := w.ReadFrom(bytes.NewReader(input[writeSize:]))
  1451  	if wantn := len(input[writeSize:]); int(n) != wantn || err != nil {
  1452  		t.Errorf("io.Copy(w, %v bytes) = %v, %v; want %v, nil", wantn, n, err, wantn)
  1453  	}
  1454  	if err := w.Flush(); err != nil {
  1455  		t.Errorf("w.Flush() = %v, want nil", err)
  1456  	}
  1457  
  1458  	if got, want := rfw.writeBytes, bufsize; got != want {
  1459  		t.Errorf("wrote %v bytes with Write, want %v", got, want)
  1460  	}
  1461  	if got, want := rfw.readFromBytes, len(input)-bufsize; got != want {
  1462  		t.Errorf("wrote %v bytes with ReadFrom, want %v", got, want)
  1463  	}
  1464  }
  1465  
  1466  func TestReadZero(t *testing.T) {
  1467  	for _, size := range []int{100, 2} {
  1468  		t.Run(fmt.Sprintf("bufsize=%d", size), func(t *testing.T) {
  1469  			r := io.MultiReader(strings.NewReader("abc"), &emptyThenNonEmptyReader{r: strings.NewReader("def"), n: 1})
  1470  			br := NewReaderSize(r, size)
  1471  			want := func(s string, wantErr error) {
  1472  				p := make([]byte, 50)
  1473  				n, err := br.Read(p)
  1474  				if err != wantErr || n != len(s) || string(p[:n]) != s {
  1475  					t.Fatalf("read(%d) = %q, %v, want %q, %v", len(p), string(p[:n]), err, s, wantErr)
  1476  				}
  1477  				t.Logf("read(%d) = %q, %v", len(p), string(p[:n]), err)
  1478  			}
  1479  			want("abc", nil)
  1480  			want("", nil)
  1481  			want("def", nil)
  1482  			want("", io.EOF)
  1483  		})
  1484  	}
  1485  }
  1486  
  1487  func TestReaderReset(t *testing.T) {
  1488  	checkAll := func(r *Reader, want string) {
  1489  		t.Helper()
  1490  		all, err := io.ReadAll(r)
  1491  		if err != nil {
  1492  			t.Fatal(err)
  1493  		}
  1494  		if string(all) != want {
  1495  			t.Errorf("ReadAll returned %q, want %q", all, want)
  1496  		}
  1497  	}
  1498  
  1499  	r := NewReader(strings.NewReader("foo foo"))
  1500  	buf := make([]byte, 3)
  1501  	r.Read(buf)
  1502  	if string(buf) != "foo" {
  1503  		t.Errorf("buf = %q; want foo", buf)
  1504  	}
  1505  
  1506  	r.Reset(strings.NewReader("bar bar"))
  1507  	checkAll(r, "bar bar")
  1508  
  1509  	*r = Reader{} // zero out the Reader
  1510  	r.Reset(strings.NewReader("bar bar"))
  1511  	checkAll(r, "bar bar")
  1512  
  1513  	// Wrap a reader and then Reset to that reader.
  1514  	r.Reset(strings.NewReader("recur"))
  1515  	r2 := NewReader(r)
  1516  	checkAll(r2, "recur")
  1517  	r.Reset(strings.NewReader("recur2"))
  1518  	r2.Reset(r)
  1519  	checkAll(r2, "recur2")
  1520  }
  1521  
  1522  func TestWriterReset(t *testing.T) {
  1523  	var buf1, buf2, buf3, buf4, buf5 strings.Builder
  1524  	w := NewWriter(&buf1)
  1525  	w.WriteString("foo")
  1526  
  1527  	w.Reset(&buf2) // and not flushed
  1528  	w.WriteString("bar")
  1529  	w.Flush()
  1530  	if buf1.String() != "" {
  1531  		t.Errorf("buf1 = %q; want empty", buf1.String())
  1532  	}
  1533  	if buf2.String() != "bar" {
  1534  		t.Errorf("buf2 = %q; want bar", buf2.String())
  1535  	}
  1536  
  1537  	*w = Writer{}  // zero out the Writer
  1538  	w.Reset(&buf3) // and not flushed
  1539  	w.WriteString("bar")
  1540  	w.Flush()
  1541  	if buf1.String() != "" {
  1542  		t.Errorf("buf1 = %q; want empty", buf1.String())
  1543  	}
  1544  	if buf3.String() != "bar" {
  1545  		t.Errorf("buf3 = %q; want bar", buf3.String())
  1546  	}
  1547  
  1548  	// Wrap a writer and then Reset to that writer.
  1549  	w.Reset(&buf4)
  1550  	w2 := NewWriter(w)
  1551  	w2.WriteString("recur")
  1552  	w2.Flush()
  1553  	if buf4.String() != "recur" {
  1554  		t.Errorf("buf4 = %q, want %q", buf4.String(), "recur")
  1555  	}
  1556  	w.Reset(&buf5)
  1557  	w2.Reset(w)
  1558  	w2.WriteString("recur2")
  1559  	w2.Flush()
  1560  	if buf5.String() != "recur2" {
  1561  		t.Errorf("buf5 = %q, want %q", buf5.String(), "recur2")
  1562  	}
  1563  }
  1564  
  1565  func TestReaderDiscard(t *testing.T) {
  1566  	tests := []struct {
  1567  		name     string
  1568  		r        io.Reader
  1569  		bufSize  int // 0 means 16
  1570  		peekSize int
  1571  
  1572  		n int // input to Discard
  1573  
  1574  		want    int   // from Discard
  1575  		wantErr error // from Discard
  1576  
  1577  		wantBuffered int
  1578  	}{
  1579  		{
  1580  			name:         "normal case",
  1581  			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
  1582  			peekSize:     16,
  1583  			n:            6,
  1584  			want:         6,
  1585  			wantBuffered: 10,
  1586  		},
  1587  		{
  1588  			name:         "discard causing read",
  1589  			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
  1590  			n:            6,
  1591  			want:         6,
  1592  			wantBuffered: 10,
  1593  		},
  1594  		{
  1595  			name:         "discard all without peek",
  1596  			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
  1597  			n:            26,
  1598  			want:         26,
  1599  			wantBuffered: 0,
  1600  		},
  1601  		{
  1602  			name:         "discard more than end",
  1603  			r:            strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
  1604  			n:            27,
  1605  			want:         26,
  1606  			wantErr:      io.EOF,
  1607  			wantBuffered: 0,
  1608  		},
  1609  		// Any error from filling shouldn't show up until we
  1610  		// get past the valid bytes. Here we return 5 valid bytes at the same time
  1611  		// as an error, but test that we don't see the error from Discard.
  1612  		{
  1613  			name: "fill error, discard less",
  1614  			r: newScriptedReader(func(p []byte) (n int, err error) {
  1615  				if len(p) < 5 {
  1616  					panic("unexpected small read")
  1617  				}
  1618  				return 5, errors.New("5-then-error")
  1619  			}),
  1620  			n:            4,
  1621  			want:         4,
  1622  			wantErr:      nil,
  1623  			wantBuffered: 1,
  1624  		},
  1625  		{
  1626  			name: "fill error, discard equal",
  1627  			r: newScriptedReader(func(p []byte) (n int, err error) {
  1628  				if len(p) < 5 {
  1629  					panic("unexpected small read")
  1630  				}
  1631  				return 5, errors.New("5-then-error")
  1632  			}),
  1633  			n:            5,
  1634  			want:         5,
  1635  			wantErr:      nil,
  1636  			wantBuffered: 0,
  1637  		},
  1638  		{
  1639  			name: "fill error, discard more",
  1640  			r: newScriptedReader(func(p []byte) (n int, err error) {
  1641  				if len(p) < 5 {
  1642  					panic("unexpected small read")
  1643  				}
  1644  				return 5, errors.New("5-then-error")
  1645  			}),
  1646  			n:            6,
  1647  			want:         5,
  1648  			wantErr:      errors.New("5-then-error"),
  1649  			wantBuffered: 0,
  1650  		},
  1651  		// Discard of 0 shouldn't cause a read:
  1652  		{
  1653  			name:         "discard zero",
  1654  			r:            newScriptedReader(), // will panic on Read
  1655  			n:            0,
  1656  			want:         0,
  1657  			wantErr:      nil,
  1658  			wantBuffered: 0,
  1659  		},
  1660  		{
  1661  			name:         "discard negative",
  1662  			r:            newScriptedReader(), // will panic on Read
  1663  			n:            -1,
  1664  			want:         0,
  1665  			wantErr:      ErrNegativeCount,
  1666  			wantBuffered: 0,
  1667  		},
  1668  	}
  1669  	for _, tt := range tests {
  1670  		br := NewReaderSize(tt.r, tt.bufSize)
  1671  		if tt.peekSize > 0 {
  1672  			peekBuf, err := br.Peek(tt.peekSize)
  1673  			if err != nil {
  1674  				t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
  1675  				continue
  1676  			}
  1677  			if len(peekBuf) != tt.peekSize {
  1678  				t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
  1679  				continue
  1680  			}
  1681  		}
  1682  		discarded, err := br.Discard(tt.n)
  1683  		if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
  1684  			t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
  1685  			continue
  1686  		}
  1687  		if bn := br.Buffered(); bn != tt.wantBuffered {
  1688  			t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
  1689  		}
  1690  	}
  1691  
  1692  }
  1693  
  1694  func TestReaderSize(t *testing.T) {
  1695  	if got, want := NewReader(nil).Size(), DefaultBufSize; got != want {
  1696  		t.Errorf("NewReader's Reader.Size = %d; want %d", got, want)
  1697  	}
  1698  	if got, want := NewReaderSize(nil, 1234).Size(), 1234; got != want {
  1699  		t.Errorf("NewReaderSize's Reader.Size = %d; want %d", got, want)
  1700  	}
  1701  }
  1702  
  1703  func TestWriterSize(t *testing.T) {
  1704  	if got, want := NewWriter(nil).Size(), DefaultBufSize; got != want {
  1705  		t.Errorf("NewWriter's Writer.Size = %d; want %d", got, want)
  1706  	}
  1707  	if got, want := NewWriterSize(nil, 1234).Size(), 1234; got != want {
  1708  		t.Errorf("NewWriterSize's Writer.Size = %d; want %d", got, want)
  1709  	}
  1710  }
  1711  
  1712  // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
  1713  type onlyReader struct {
  1714  	io.Reader
  1715  }
  1716  
  1717  // An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
  1718  type onlyWriter struct {
  1719  	io.Writer
  1720  }
  1721  
  1722  // A scriptedReader is an io.Reader that executes its steps sequentially.
  1723  type scriptedReader []func(p []byte) (n int, err error)
  1724  
  1725  func (sr *scriptedReader) Read(p []byte) (n int, err error) {
  1726  	if len(*sr) == 0 {
  1727  		panic("too many Read calls on scripted Reader. No steps remain.")
  1728  	}
  1729  	step := (*sr)[0]
  1730  	*sr = (*sr)[1:]
  1731  	return step(p)
  1732  }
  1733  
  1734  func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
  1735  	sr := scriptedReader(steps)
  1736  	return &sr
  1737  }
  1738  
  1739  // eofReader returns the number of bytes read and io.EOF for the read that consumes the last of the content.
  1740  type eofReader struct {
  1741  	buf []byte
  1742  }
  1743  
  1744  func (r *eofReader) Read(p []byte) (int, error) {
  1745  	read := copy(p, r.buf)
  1746  	r.buf = r.buf[read:]
  1747  
  1748  	switch read {
  1749  	case 0, len(r.buf):
  1750  		// As allowed in the documentation, this will return io.EOF
  1751  		// in the same call that consumes the last of the data.
  1752  		// https://godoc.org/io#Reader
  1753  		return read, io.EOF
  1754  	}
  1755  
  1756  	return read, nil
  1757  }
  1758  
  1759  func TestPartialReadEOF(t *testing.T) {
  1760  	src := make([]byte, 10)
  1761  	eofR := &eofReader{buf: src}
  1762  	r := NewReader(eofR)
  1763  
  1764  	// Start by reading 5 of the 10 available bytes.
  1765  	dest := make([]byte, 5)
  1766  	read, err := r.Read(dest)
  1767  	if err != nil {
  1768  		t.Fatalf("unexpected error: %v", err)
  1769  	}
  1770  	if n := len(dest); read != n {
  1771  		t.Fatalf("read %d bytes; wanted %d bytes", read, n)
  1772  	}
  1773  
  1774  	// The Reader should have buffered all the content from the io.Reader.
  1775  	if n := len(eofR.buf); n != 0 {
  1776  		t.Fatalf("got %d bytes left in bufio.Reader source; want 0 bytes", n)
  1777  	}
  1778  	// To prove the point, check that there are still 5 bytes available to read.
  1779  	if n := r.Buffered(); n != 5 {
  1780  		t.Fatalf("got %d bytes buffered in bufio.Reader; want 5 bytes", n)
  1781  	}
  1782  
  1783  	// This is the second read of 0 bytes.
  1784  	read, err = r.Read([]byte{})
  1785  	if err != nil {
  1786  		t.Fatalf("unexpected error: %v", err)
  1787  	}
  1788  	if read != 0 {
  1789  		t.Fatalf("read %d bytes; want 0 bytes", read)
  1790  	}
  1791  }
  1792  
  1793  type writerWithReadFromError struct{}
  1794  
  1795  func (w writerWithReadFromError) ReadFrom(r io.Reader) (int64, error) {
  1796  	return 0, errors.New("writerWithReadFromError error")
  1797  }
  1798  
  1799  func (w writerWithReadFromError) Write(b []byte) (n int, err error) {
  1800  	return 10, nil
  1801  }
  1802  
  1803  func TestWriterReadFromMustSetUnderlyingError(t *testing.T) {
  1804  	var wr = NewWriter(writerWithReadFromError{})
  1805  	if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
  1806  		t.Fatal("expected ReadFrom returns error, got nil")
  1807  	}
  1808  	if _, err := wr.Write([]byte("123")); err == nil {
  1809  		t.Fatal("expected Write returns error, got nil")
  1810  	}
  1811  }
  1812  
  1813  type writeErrorOnlyWriter struct{}
  1814  
  1815  func (w writeErrorOnlyWriter) Write(p []byte) (n int, err error) {
  1816  	return 0, errors.New("writeErrorOnlyWriter error")
  1817  }
  1818  
  1819  // Ensure that previous Write errors are immediately returned
  1820  // on any ReadFrom. See golang.org/issue/35194.
  1821  func TestWriterReadFromMustReturnUnderlyingError(t *testing.T) {
  1822  	var wr = NewWriter(writeErrorOnlyWriter{})
  1823  	s := "test1"
  1824  	wantBuffered := len(s)
  1825  	if _, err := wr.WriteString(s); err != nil {
  1826  		t.Fatalf("unexpected error: %v", err)
  1827  	}
  1828  	if err := wr.Flush(); err == nil {
  1829  		t.Error("expected flush error, got nil")
  1830  	}
  1831  	if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
  1832  		t.Fatal("expected error, got nil")
  1833  	}
  1834  	if buffered := wr.Buffered(); buffered != wantBuffered {
  1835  		t.Fatalf("Buffered = %v; want %v", buffered, wantBuffered)
  1836  	}
  1837  }
  1838  
  1839  func BenchmarkReaderCopyOptimal(b *testing.B) {
  1840  	// Optimal case is where the underlying reader implements io.WriterTo
  1841  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1842  	src := NewReader(srcBuf)
  1843  	dstBuf := new(bytes.Buffer)
  1844  	dst := onlyWriter{dstBuf}
  1845  	for i := 0; i < b.N; i++ {
  1846  		srcBuf.Reset()
  1847  		src.Reset(srcBuf)
  1848  		dstBuf.Reset()
  1849  		io.Copy(dst, src)
  1850  	}
  1851  }
  1852  
  1853  func BenchmarkReaderCopyUnoptimal(b *testing.B) {
  1854  	// Unoptimal case is where the underlying reader doesn't implement io.WriterTo
  1855  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1856  	src := NewReader(onlyReader{srcBuf})
  1857  	dstBuf := new(bytes.Buffer)
  1858  	dst := onlyWriter{dstBuf}
  1859  	for i := 0; i < b.N; i++ {
  1860  		srcBuf.Reset()
  1861  		src.Reset(onlyReader{srcBuf})
  1862  		dstBuf.Reset()
  1863  		io.Copy(dst, src)
  1864  	}
  1865  }
  1866  
  1867  func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
  1868  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1869  	srcReader := NewReader(srcBuf)
  1870  	src := onlyReader{srcReader}
  1871  	dstBuf := new(bytes.Buffer)
  1872  	dst := onlyWriter{dstBuf}
  1873  	for i := 0; i < b.N; i++ {
  1874  		srcBuf.Reset()
  1875  		srcReader.Reset(srcBuf)
  1876  		dstBuf.Reset()
  1877  		io.Copy(dst, src)
  1878  	}
  1879  }
  1880  
  1881  func BenchmarkReaderWriteToOptimal(b *testing.B) {
  1882  	const bufSize = 16 << 10
  1883  	buf := make([]byte, bufSize)
  1884  	r := bytes.NewReader(buf)
  1885  	srcReader := NewReaderSize(onlyReader{r}, 1<<10)
  1886  	if _, ok := io.Discard.(io.ReaderFrom); !ok {
  1887  		b.Fatal("io.Discard doesn't support ReaderFrom")
  1888  	}
  1889  	for i := 0; i < b.N; i++ {
  1890  		r.Seek(0, io.SeekStart)
  1891  		srcReader.Reset(onlyReader{r})
  1892  		n, err := srcReader.WriteTo(io.Discard)
  1893  		if err != nil {
  1894  			b.Fatal(err)
  1895  		}
  1896  		if n != bufSize {
  1897  			b.Fatalf("n = %d; want %d", n, bufSize)
  1898  		}
  1899  	}
  1900  }
  1901  
  1902  func BenchmarkReaderReadString(b *testing.B) {
  1903  	r := strings.NewReader("       foo       foo        42        42        42        42        42        42        42        42       4.2       4.2       4.2       4.2\n")
  1904  	buf := NewReader(r)
  1905  	b.ReportAllocs()
  1906  	for i := 0; i < b.N; i++ {
  1907  		r.Seek(0, io.SeekStart)
  1908  		buf.Reset(r)
  1909  
  1910  		_, err := buf.ReadString('\n')
  1911  		if err != nil {
  1912  			b.Fatal(err)
  1913  		}
  1914  	}
  1915  }
  1916  
  1917  func BenchmarkWriterCopyOptimal(b *testing.B) {
  1918  	// Optimal case is where the underlying writer implements io.ReaderFrom
  1919  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1920  	src := onlyReader{srcBuf}
  1921  	dstBuf := new(bytes.Buffer)
  1922  	dst := NewWriter(dstBuf)
  1923  	for i := 0; i < b.N; i++ {
  1924  		srcBuf.Reset()
  1925  		dstBuf.Reset()
  1926  		dst.Reset(dstBuf)
  1927  		io.Copy(dst, src)
  1928  	}
  1929  }
  1930  
  1931  func BenchmarkWriterCopyUnoptimal(b *testing.B) {
  1932  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1933  	src := onlyReader{srcBuf}
  1934  	dstBuf := new(bytes.Buffer)
  1935  	dst := NewWriter(onlyWriter{dstBuf})
  1936  	for i := 0; i < b.N; i++ {
  1937  		srcBuf.Reset()
  1938  		dstBuf.Reset()
  1939  		dst.Reset(onlyWriter{dstBuf})
  1940  		io.Copy(dst, src)
  1941  	}
  1942  }
  1943  
  1944  func BenchmarkWriterCopyNoReadFrom(b *testing.B) {
  1945  	srcBuf := bytes.NewBuffer(make([]byte, 8192))
  1946  	src := onlyReader{srcBuf}
  1947  	dstBuf := new(bytes.Buffer)
  1948  	dstWriter := NewWriter(dstBuf)
  1949  	dst := onlyWriter{dstWriter}
  1950  	for i := 0; i < b.N; i++ {
  1951  		srcBuf.Reset()
  1952  		dstBuf.Reset()
  1953  		dstWriter.Reset(dstBuf)
  1954  		io.Copy(dst, src)
  1955  	}
  1956  }
  1957  
  1958  func BenchmarkReaderEmpty(b *testing.B) {
  1959  	b.ReportAllocs()
  1960  	str := strings.Repeat("x", 16<<10)
  1961  	for i := 0; i < b.N; i++ {
  1962  		br := NewReader(strings.NewReader(str))
  1963  		n, err := io.Copy(io.Discard, br)
  1964  		if err != nil {
  1965  			b.Fatal(err)
  1966  		}
  1967  		if n != int64(len(str)) {
  1968  			b.Fatal("wrong length")
  1969  		}
  1970  	}
  1971  }
  1972  
  1973  func BenchmarkWriterEmpty(b *testing.B) {
  1974  	b.ReportAllocs()
  1975  	str := strings.Repeat("x", 1<<10)
  1976  	bs := []byte(str)
  1977  	for i := 0; i < b.N; i++ {
  1978  		bw := NewWriter(io.Discard)
  1979  		bw.Flush()
  1980  		bw.WriteByte('a')
  1981  		bw.Flush()
  1982  		bw.WriteRune('B')
  1983  		bw.Flush()
  1984  		bw.Write(bs)
  1985  		bw.Flush()
  1986  		bw.WriteString(str)
  1987  		bw.Flush()
  1988  	}
  1989  }
  1990  
  1991  func BenchmarkWriterFlush(b *testing.B) {
  1992  	b.ReportAllocs()
  1993  	bw := NewWriter(io.Discard)
  1994  	str := strings.Repeat("x", 50)
  1995  	for i := 0; i < b.N; i++ {
  1996  		bw.WriteString(str)
  1997  		bw.Flush()
  1998  	}
  1999  }
  2000  

View as plain text