github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/quicvarint/io_test.go (about)

     1  package quicvarint
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  
     7  	. "github.com/onsi/ginkgo/v2"
     8  	. "github.com/onsi/gomega"
     9  )
    10  
    11  type nopReader struct{}
    12  
    13  func (r *nopReader) Read(_ []byte) (int, error) {
    14  	return 0, io.ErrUnexpectedEOF
    15  }
    16  
    17  var _ io.Reader = &nopReader{}
    18  
    19  type nopWriter struct{}
    20  
    21  func (r *nopWriter) Write(_ []byte) (int, error) {
    22  	return 0, io.ErrShortBuffer
    23  }
    24  
    25  // eofReader is a reader that returns data and the io.EOF at the same time in the last Read call
    26  type eofReader struct {
    27  	Data []byte
    28  	pos  int
    29  }
    30  
    31  func (r *eofReader) Read(b []byte) (int, error) {
    32  	n := copy(b, r.Data[r.pos:])
    33  	r.pos += n
    34  	if r.pos >= len(r.Data) {
    35  		return n, io.EOF
    36  	}
    37  	return n, nil
    38  }
    39  
    40  var _ io.Writer = &nopWriter{}
    41  
    42  var _ = Describe("Varint I/O", func() {
    43  	Context("Reader", func() {
    44  		Context("NewReader", func() {
    45  			It("passes through a Reader unchanged", func() {
    46  				b := bytes.NewReader([]byte{0})
    47  				r := NewReader(b)
    48  				Expect(r).To(Equal(b))
    49  			})
    50  
    51  			It("wraps an io.Reader", func() {
    52  				n := &nopReader{}
    53  				r := NewReader(n)
    54  				Expect(r).ToNot(Equal(n))
    55  			})
    56  		})
    57  
    58  		It("returns an error when reading from an underlying io.Reader fails", func() {
    59  			r := NewReader(&nopReader{})
    60  			val, err := r.ReadByte()
    61  			Expect(err).To(Equal(io.ErrUnexpectedEOF))
    62  			Expect(val).To(Equal(byte(0)))
    63  		})
    64  
    65  		Context("EOF handling", func() {
    66  			It("eofReader works correctly", func() {
    67  				r := &eofReader{Data: []byte("foobar")}
    68  				b := make([]byte, 3)
    69  				n, err := r.Read(b)
    70  				Expect(n).To(Equal(3))
    71  				Expect(err).ToNot(HaveOccurred())
    72  				Expect(string(b)).To(Equal("foo"))
    73  				n, err = r.Read(b)
    74  				Expect(n).To(Equal(3))
    75  				Expect(err).To(MatchError(io.EOF))
    76  				Expect(string(b)).To(Equal("bar"))
    77  				n, err = r.Read(b)
    78  				Expect(err).To(MatchError(io.EOF))
    79  				Expect(n).To(BeZero())
    80  			})
    81  
    82  			It("correctly handles io.EOF", func() {
    83  				r := NewReader(&eofReader{Data: Append(nil, 1337)})
    84  				n, err := Read(r)
    85  				Expect(err).ToNot(HaveOccurred())
    86  				Expect(n).To(BeEquivalentTo(1337))
    87  			})
    88  		})
    89  	})
    90  
    91  	Context("Writer", func() {
    92  		Context("NewWriter", func() {
    93  			It("passes through a Writer unchanged", func() {
    94  				b := &bytes.Buffer{}
    95  				w := NewWriter(b)
    96  				Expect(w).To(Equal(b))
    97  			})
    98  
    99  			It("wraps an io.Writer", func() {
   100  				n := &nopWriter{}
   101  				w := NewWriter(n)
   102  				Expect(w).ToNot(Equal(n))
   103  			})
   104  		})
   105  
   106  		It("returns an error when writing to an underlying io.Writer fails", func() {
   107  			w := NewWriter(&nopWriter{})
   108  			err := w.WriteByte(0)
   109  			Expect(err).To(Equal(io.ErrShortBuffer))
   110  		})
   111  	})
   112  })