149 lines
3.0 KiB
Go
149 lines
3.0 KiB
Go
package io
|
|
|
|
import (
|
|
"errors"
|
|
std "io"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type mockReadCloser struct {
|
|
reader std.Reader
|
|
closed bool
|
|
}
|
|
|
|
func (m *mockReadCloser) Read(p []byte) (n int, err error) {
|
|
return m.reader.Read(p)
|
|
}
|
|
|
|
func (m *mockReadCloser) Close() error {
|
|
m.closed = true
|
|
return nil
|
|
}
|
|
|
|
type errorReadCloser struct {
|
|
closeErr error
|
|
}
|
|
|
|
func (e *errorReadCloser) Read(p []byte) (n int, err error) {
|
|
return 0, errors.New("read error")
|
|
}
|
|
|
|
func (e *errorReadCloser) Close() error {
|
|
return e.closeErr
|
|
}
|
|
|
|
func TestReadAllAndClose(t *testing.T) {
|
|
t.Run("successful read and close", func(t *testing.T) {
|
|
content := "hello world"
|
|
mock := &mockReadCloser{reader: strings.NewReader(content)}
|
|
|
|
data, err := ReadAllAndClose(mock)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if string(data) != content {
|
|
t.Errorf("expected %q, got %q", content, string(data))
|
|
}
|
|
|
|
if !mock.closed {
|
|
t.Error("expected ReadCloser to be closed")
|
|
}
|
|
})
|
|
|
|
t.Run("read error", func(t *testing.T) {
|
|
errRC := &errorReadCloser{}
|
|
|
|
data, err := ReadAllAndClose(errRC)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
if len(data) != 0 {
|
|
t.Errorf("expected empty data on error, got %v", data)
|
|
}
|
|
})
|
|
|
|
t.Run("empty content", func(t *testing.T) {
|
|
mock := &mockReadCloser{reader: strings.NewReader("")}
|
|
|
|
data, err := ReadAllAndClose(mock)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if len(data) != 0 {
|
|
t.Errorf("expected empty data, got %v", data)
|
|
}
|
|
|
|
if !mock.closed {
|
|
t.Error("expected ReadCloser to be closed")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReadAllAndCloseAsString(t *testing.T) {
|
|
t.Run("successful read and close", func(t *testing.T) {
|
|
content := "hello world"
|
|
mock := &mockReadCloser{reader: strings.NewReader(content)}
|
|
|
|
str, err := ReadAllAndCloseAsString(mock)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if str != content {
|
|
t.Errorf("expected %q, got %q", content, str)
|
|
}
|
|
|
|
if !mock.closed {
|
|
t.Error("expected ReadCloser to be closed")
|
|
}
|
|
})
|
|
|
|
t.Run("read error propagates", func(t *testing.T) {
|
|
errRC := &errorReadCloser{}
|
|
|
|
str, err := ReadAllAndCloseAsString(errRC)
|
|
if err == nil {
|
|
t.Fatal("expected error, got nil")
|
|
}
|
|
|
|
if str != "" {
|
|
t.Errorf("expected empty string on error, got %q", str)
|
|
}
|
|
})
|
|
|
|
t.Run("empty content", func(t *testing.T) {
|
|
mock := &mockReadCloser{reader: strings.NewReader("")}
|
|
|
|
str, err := ReadAllAndCloseAsString(mock)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if str != "" {
|
|
t.Errorf("expected empty string, got %q", str)
|
|
}
|
|
|
|
if !mock.closed {
|
|
t.Error("expected ReadCloser to be closed")
|
|
}
|
|
})
|
|
|
|
t.Run("unicode content", func(t *testing.T) {
|
|
content := "Hello 世界 🌍"
|
|
mock := &mockReadCloser{reader: strings.NewReader(content)}
|
|
|
|
str, err := ReadAllAndCloseAsString(mock)
|
|
if err != nil {
|
|
t.Fatalf("expected no error, got %v", err)
|
|
}
|
|
|
|
if str != content {
|
|
t.Errorf("expected %q, got %q", content, str)
|
|
}
|
|
})
|
|
}
|