package dataext import ( "bytes" "io" "testing" ) type fakeReadCloser struct { r *bytes.Reader closed bool } func newFakeReadCloser(data []byte) *fakeReadCloser { return &fakeReadCloser{r: bytes.NewReader(data)} } func (f *fakeReadCloser) Read(p []byte) (int, error) { return f.r.Read(p) } func (f *fakeReadCloser) Close() error { f.closed = true return nil } func TestBufferedReadCloser_ReadAll(t *testing.T) { data := []byte("hello world") brc := NewBufferedReadCloser(newFakeReadCloser(data)) buf := make([]byte, 64) total := 0 for { n, err := brc.Read(buf[total:]) total += n if err == io.EOF { break } if err != nil { t.Fatalf("unexpected err: %v", err) } } if !bytes.Equal(buf[:total], data) { t.Fatalf("got %q want %q", buf[:total], data) } } func TestBufferedReadCloser_BufferedAllThenRead(t *testing.T) { data := []byte("foobar baz") brc := NewBufferedReadCloser(newFakeReadCloser(data)) all, err := brc.BufferedAll() if err != nil { t.Fatalf("BufferedAll err: %v", err) } if !bytes.Equal(all, data) { t.Fatalf("BufferedAll got %q want %q", all, data) } // after BufferedAll, Reset put us in BufferReading mode - we can read again out, err := io.ReadAll(brc) if err != nil { t.Fatalf("ReadAll err: %v", err) } if !bytes.Equal(out, data) { t.Fatalf("ReadAll got %q want %q", out, data) } } func TestBufferedReadCloser_FullyReadResetReread(t *testing.T) { data := []byte("abcdefghij") brc := NewBufferedReadCloser(newFakeReadCloser(data)) out, err := io.ReadAll(brc) if err != nil { t.Fatalf("first ReadAll err: %v", err) } if !bytes.Equal(out, data) { t.Fatalf("first read got %q want %q", out, data) } if err := brc.Reset(); err != nil { t.Fatalf("reset err: %v", err) } out2, err := io.ReadAll(brc) if err != nil { t.Fatalf("second ReadAll err: %v", err) } if !bytes.Equal(out2, data) { t.Fatalf("after reset got %q want %q", out2, data) } } func TestBufferedReadCloser_Close(t *testing.T) { data := []byte("xyz") inner := newFakeReadCloser(data) brc := NewBufferedReadCloser(inner) if err := brc.Close(); err != nil { t.Fatalf("close err: %v", err) } if !inner.closed { t.Fatal("inner not closed") } // double close should be no-op if err := brc.Close(); err != nil { t.Fatalf("second close err: %v", err) } } func TestBufferedReadCloser_ResetWithoutRead(t *testing.T) { data := []byte("abc") brc := NewBufferedReadCloser(newFakeReadCloser(data)) if err := brc.Reset(); err != nil { t.Fatalf("reset err: %v", err) } out, err := io.ReadAll(brc) if err != nil { t.Fatalf("ReadAll err: %v", err) } if !bytes.Equal(out, data) { t.Fatalf("got %q want %q", out, data) } }