1
0
buffer/writeto_test.go
2026-02-17 16:58:00 +01:00

286 lines
5.2 KiB
Go

package buffer_test
import (
"testing"
"code.squareroundforest.org/arpio/buffer"
"bytes"
"errors"
"io"
)
func TestWriteTo(t *testing.T) {
t.Run("write out from zero", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if err != nil {
t.Fatal(err)
}
if n != 1 << 15 {
t.Fatal("write count")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)) {
t.Fatal("content")
}
})
t.Run("write out from started", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
p := make([]byte, 256)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("invalid read count")
}
if !bytes.Equal(p, generate(256)) {
t.Fatal("invalid content")
}
var b bytes.Buffer
n64, err := r.WriteTo(&b)
if err != nil {
t.Fatal(err)
}
if n64 != 1 << 15 - 256 {
t.Fatal("write count")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[256:]) {
t.Fatal("content")
}
})
t.Run("after EOF", func(t *testing.T) {
g := &gen{max: 256}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
b, err := r.Peek(512)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b, generate(256)) {
t.Fatal("invalid content")
}
var buf bytes.Buffer
n, err := r.WriteTo(&buf)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("write count")
}
if !bytes.Equal(buf.Bytes(), generate(256)) {
t.Fatal("invalid content")
}
})
t.Run("after err", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
fastErr: true,
}
o := buffer.Options{
Pool: buffer.NoPool(64),
ReadSize: 16,
}
r := buffer.ReaderFrom(g, o)
b, err := r.Peek(512)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(b, generate(256)) {
t.Fatal("invalid content", 1)
}
var buf bytes.Buffer
n, err := r.WriteTo(&buf)
if !errors.Is(err, errTest) {
t.Fatal("failed to test with the right error", err)
}
if n != 256 {
t.Fatal("write count")
}
if !bytes.Equal(buf.Bytes(), generate(256)) {
t.Fatal("invalid content", 2)
}
})
t.Run("after eof empty", func(t *testing.T) {
g := &gen{max: 256}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
p := make([]byte, 512)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n != 256 {
t.Fatal("invalid length")
}
if !bytes.Equal(p[:n], generate(256)) {
t.Fatal("invalid content 1")
}
var buf bytes.Buffer
n64, err := r.WriteTo(&buf)
if err != nil {
t.Fatal(err)
}
if n64 != 0 {
t.Fatal("write count")
}
if buf.Len() != 0 {
t.Fatal("invalid content 2")
}
})
t.Run("after error empty", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
p := make([]byte, 1 << 15)
n, err := r.Read(p)
if err != nil {
t.Fatal(err)
}
if n < 256 {
t.Fatal("invalid length")
}
if !bytes.Equal(p[:n], generate(1 << 15)[:n]) {
t.Fatal("invalid content 1")
}
var buf bytes.Buffer
n64, err := r.WriteTo(&buf)
if !errors.Is(err, errTest) {
t.Fatal(err)
}
if n64 != 0 {
t.Fatal("write count")
}
if buf.Len() != 0 {
t.Fatal("invalid content 2")
}
})
t.Run("null read on fill", func(t *testing.T) {
g := &gen{
max: 1 << 15,
nullReadAfter: []int{256, 256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if !errors.Is(err, io.ErrNoProgress) {
t.Fatal("failed to fail with the right error")
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
t.Run("err during fill", func(t *testing.T) {
g := &gen{
max: 1 << 15,
errAfter: []int{256},
}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
var b bytes.Buffer
n, err := r.WriteTo(&b)
if !errors.Is(err, errTest) {
t.Fatal("failed to fail with the right error")
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(b.Bytes(), generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
t.Run("write error", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
w := &writer{errAfter: []int{256}}
n, err := r.WriteTo(w)
if !errors.Is(err, errTest) {
t.Fatal("failed to fail with the right error", err)
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(w.written, generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
t.Run("short write", func(t *testing.T) {
g := &gen{max: 1 << 15}
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
r := buffer.ReaderFrom(g, o)
w := &writer{shortAfter: []int{256}}
n, err := r.WriteTo(w)
if !errors.Is(err, io.ErrShortWrite) {
t.Fatal("failed to fail with the right error", err)
}
if n < 256 {
t.Fatal("not enough written")
}
if !bytes.Equal(w.written, generate(1 << 15)[:n]) {
t.Fatal("invalid content")
}
})
}