Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
bufio_test.go2000 linesDownload Raw Back to bufio
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package bufio_test6 7import (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.24type rot13Reader struct {25	r io.Reader26}27 28func newRot13Reader(r io.Reader) *rot13Reader {29	r13 := new(rot13Reader)30	r13.r = r31	return r1332}33 34func (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 byte38		if 'a' <= c && c <= 'm' {39			p[i] += 1340		} else if 'n' <= c && c <= 'z' {41			p[i] -= 1342		}43	}44	return n, err45}46 47// Call ReadByte to accumulate the text of a file48func readBytes(buf *Reader) string {49	var b [1000]byte50	nb := 051	for {52		c, err := buf.ReadByte()53		if err == io.EOF {54			break55		}56		if err == nil {57			b[nb] = c58			nb++59		} else if err != iotest.ErrTimeout {60			panic("Data: " + err.Error())61		}62	}63	return string(b[0:nb])64}65 66func 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 79type readMaker struct {80	name string81	fn   func(io.Reader) io.Reader82}83 84var 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.94func readLines(b *Reader) string {95	s := ""96	for {97		s1, err := b.ReadString('\n')98		if err == io.EOF {99			break100		}101		if err != nil && err != iotest.ErrTimeout {102			panic("GetLines: " + err.Error())103		}104		s += s1105	}106	return s107}108 109// Call Read to accumulate the text of a file110func reads(buf *Reader, m int) string {111	var b [1000]byte112	nb := 0113	for {114		n, err := buf.Read(b[nb : nb+m])115		nb += n116		if err == io.EOF {117			break118		}119	}120	return string(b[0:nb])121}122 123type bufReader struct {124	name string125	fn   func(*Reader) string126}127 128var 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 139const minReadBufferSize = 16140 141var bufsizes = []int{142	0, minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096,143}144 145func TestReader(t *testing.T) {146	var texts [31]string147	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] = all155 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 177type zeroReader struct{}178 179func (zeroReader) Read(p []byte) (int, error) {180	return 0, nil181}182 183func TestZeroReader(t *testing.T) {184	var z zeroReader185	r := NewReader(z)186 187	c := make(chan error)188	go func() {189		_, err := r.ReadByte()190		c <- err191	}()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.206type StringReader struct {207	data []string208	step int209}210 211func (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.EOF218	}219	return220}221 222func 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				return231			}232			break233		}234		got += string(r)235	}236	if got != want {237		t.Errorf("segments=%v got=%s want=%s", segments, got, want)238	}239}240 241var 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 252func TestReadRune(t *testing.T) {253	for _, s := range segmentList {254		readRuneSegments(t, s)255	}256}257 258func 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			break271		}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 290func 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 299func 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 308func 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 317func 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 326func 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 334func 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 342func 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			break355		}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 374func 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 402func 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), err410		},411		// ReadLine doesn't fit the data/pattern easily412		// so we leave it out. It should be covered via413		// the ReadSlice test since ReadLine simply calls414		// ReadSlice, and it's that function that handles415		// 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 = 10422		var buf bytes.Buffer423		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.459func TestUnreadRuneError(t *testing.T) {460	buf := make([]byte, 3) // All runes in this test are 3 bytes long461	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 state477	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 state489	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 state503	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 state519	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 531func 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 545func TestReadWriteRune(t *testing.T) {546	const NRune = 1000547	byteBuf := new(bytes.Buffer)548	w := NewWriter(byteBuf)549	// Write the runes out using WriteRune550	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 ReadRune565	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 574func TestWriteInvalidRune(t *testing.T) {575	// Invalid runes, including negative ones, should be written as the576	// replacement character.577	for _, r := range []rune{-1, utf8.MaxRune + 1} {578		var buf strings.Builder579		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 588func 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 608func TestWriter(t *testing.T) {609	var data [8192]byte610 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 out622			// 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				continue631			}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 651func TestWriterAppend(t *testing.T) {652	got := new(bytes.Buffer)653	var want []byte654	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 684type errorWriterTest struct {685	n, m   int686	err    error687	expect error688}689 690func (w errorWriterTest) Write(p []byte) (int, error) {691	return len(p) * w.n / w.m, w.err692}693 694var 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 703func 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			continue710		}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 721func TestNewReaderSizeIdempotent(t *testing.T) {722	const BufSize = 1000723	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 736func TestNewWriterSizeIdempotent(t *testing.T) {737	const BufSize = 1000738	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 751func TestWriteString(t *testing.T) {752	const BufSize = 8753	buf := new(strings.Builder)754	b := NewWriterSize(buf, BufSize)755	b.WriteString("0")                         // easy756	b.WriteString("123456")                    // still easy757	b.WriteString("7890")                      // easy after flush758	b.WriteString("abcdefghijklmnopqrstuvwxy") // hard759	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 769func TestWriteStringStringWriter(t *testing.T) {770	const BufSize = 8771	{772		tw := &teststringwriter{}773		b := NewWriterSize(tw, BufSize)774		b.WriteString("1234")775		tw.check(t, "", "")776		b.WriteString("56789012")   // longer than BufSize777		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 WriteString786	}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 buffer793		tw.check(t, "abc12345", "6789012345") // use Write and then WriteString since the remaining part is still longer than BufSize794	}795	{796		tw := &teststringwriter{}797		b := NewWriterSize(tw, BufSize)798		b.Write([]byte("abc")) // same as above, but use Write instead of WriteString799		tw.check(t, "", "")800		b.WriteString("123456789012345")801		tw.check(t, "abc12345", "6789012345") // same as above802	}803}804 805type teststringwriter struct {806	write       string807	writeString string808}809 810func (w *teststringwriter) Write(b []byte) (int, error) {811	w.write += string(b)812	return len(b), nil813}814 815func (w *teststringwriter) WriteString(s string) (int, error) {816	w.writeString += s817	return len(s), nil818}819 820func (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 830func 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 843func 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 900type dataAndEOFReader string901 902func (r dataAndEOFReader) Read(p []byte) (int, error) {903	return copy(p, r), io.EOF904}905 906func 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 here913}914 915var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy")916var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")917var 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.920type testReader struct {921	data   []byte922	stride int923}924 925func (t *testReader) Read(buf []byte) (n int, err error) {926	n = t.stride927	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.EOF937	}938	return939}940 941func testReadLine(t *testing.T, input []byte) {942	for stride := 1; stride < 2; stride++ {943		done := 0944		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				break959			}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 971func TestReadLine(t *testing.T) {972	testReadLine(t, testInput)973	testReadLine(t, testInputrn)974}975 976func 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 1003func 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)/21009	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 1023func 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 1031func 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		return1037	}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 1045func 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 1056type readLineResult struct {1057	line     []byte1058	isPrefix bool1059	err      error1060}1061 1062var readLineNewlinesTests = []struct {1063	input  string1064	expect []readLineResult1065}{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 1081func TestReadLineNewlines(t *testing.T) {1082	for _, e := range readLineNewlinesTests {1083		testReadLineNewlines(t, e.input, e.expect)1084	}1085}1086 1087func 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			return1094		}1095		if isPrefix != e.isPrefix {1096			t.Errorf("%q call %d, isPrefix == %v, want %v", input, i, isPrefix, e.isPrefix)1097			return1098		}1099		if err != e.err {1100			t.Errorf("%q call %d, err == %v, want %v", input, i, err, e.err)1101			return1102		}1103	}1104}1105 1106func 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 sequence1111		// 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 input1118}1119 1120func 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 1135type errorWriterToTest struct {1136	rn, wn     int1137	rerr, werr error1138	expected   error1139}1140 1141func (r errorWriterToTest) Read(p []byte) (int, error) {1142	return len(p) * r.rn, r.rerr1143}1144 1145func (w errorWriterToTest) Write(p []byte) (int, error) {1146	return len(p) * w.wn, w.werr1147}1148 1149var 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.ErrUnexpectedEOF},1153	{0, 1, io.EOF, nil, nil},1154}1155 1156func 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 1165func 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				continue1185			}1186			if err := w.Flush(); err != nil {1187				t.Errorf("Flush returned %v", err)1188				continue1189			}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 1197type errorReaderFromTest struct {1198	rn, wn     int1199	rerr, werr error1200	expected   error

Showing the first 1,200 of 2000 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai