1
0
buffer/io_test.go

159 lines
3.0 KiB
Go
Raw Permalink Normal View History

2026-02-17 16:58:00 +01:00
package buffer_test
import (
2026-02-22 16:30:37 +01:00
"code.squareroundforest.org/arpio/buffer"
2026-02-17 16:58:00 +01:00
"errors"
"io"
)
2026-02-22 16:30:37 +01:00
type createReader func(r io.Reader, o buffer.Options) buffer.Reader
2026-02-17 16:58:00 +01:00
type gen struct {
rng []byte
max int
fastErr bool
nullReadAfter []int
errAfter []int
customContentAfter []int
customContent map[int][]byte
counter int
}
type writer struct {
2026-02-22 16:30:37 +01:00
written []byte
errAfter []int
2026-02-17 16:58:00 +01:00
shortAfter []int
}
var (
genRange = []byte("abcdefghi")
utf8Range = []byte("aábéícóöődúüeű")
utf8W2Range = []byte("áéíóöőúüű")
errTest = errors.New("test error")
2026-02-22 18:45:57 +01:00
errTest2 = errors.New("test error 2")
2026-02-17 16:58:00 +01:00
)
func (g *gen) Read(p []byte) (int, error) {
if g.max == 0 {
return 0, io.EOF
}
if len(g.nullReadAfter) > 0 && g.counter >= g.nullReadAfter[0] {
g.nullReadAfter = g.nullReadAfter[1:]
return 0, nil
}
if len(g.errAfter) > 0 && g.counter >= g.errAfter[0] {
g.errAfter = g.errAfter[1:]
return 0, errTest
}
l := len(p)
hasMax := g.max > 0
if hasMax && l > g.max {
l = g.max
}
if len(g.rng) == 0 {
g.rng = genRange
}
var n int
for l > 0 {
rng := make([]byte, len(g.rng))
copy(rng, g.rng)
c := g.counter % len(rng)
rng = append(rng[c:], rng[:c]...)
li := l
if li > len(rng) {
li = len(rng)
}
cc := len(g.customContentAfter) > 0 &&
g.counter <= g.customContentAfter[0] &&
g.counter+li > g.customContentAfter[0]
if cc && g.counter != g.customContentAfter[0] {
li = g.customContentAfter[0] - g.counter
cc = false
}
var ni int
if cc {
content := g.customContent[g.customContentAfter[0]]
ni = copy(p[:li], content)
if ni == len(content) {
g.customContentAfter = g.customContentAfter[1:]
} else {
g.customContentAfter[0] += ni
g.customContent[g.customContentAfter[0]] = content[ni:]
}
} else {
ni = copy(p[:li], rng)
}
n += ni
p = p[ni:]
l -= ni
g.counter += ni
if cc {
c := g.counter % len(g.rng)
rng = append(rng[c:], rng[:c]...)
}
}
if hasMax {
g.max -= n
}
if len(g.errAfter) > 0 && g.counter >= g.errAfter[0] && g.fastErr {
g.errAfter = g.errAfter[1:]
return n, errTest
}
if hasMax && g.max == 0 && g.fastErr {
return n, io.EOF
}
return n, nil
}
func generateFrom(rng []byte, n int) []byte {
g := &gen{
rng: rng,
max: n,
}
b, _ := io.ReadAll(g)
return b
}
func generate(n int) []byte {
return generateFrom(genRange, n)
}
func (w *writer) Write(p []byte) (int, error) {
if len(w.errAfter) > 0 && len(w.written) >= w.errAfter[0] {
w.errAfter = w.errAfter[1:]
return 0, errTest
}
if len(p) > 0 && len(w.shortAfter) > 0 && len(w.written) >= w.shortAfter[0] {
w.shortAfter = w.shortAfter[1:]
2026-02-22 16:30:37 +01:00
p = p[:len(p)/2]
2026-02-17 16:58:00 +01:00
}
wp := make([]byte, len(p))
copy(wp, p)
w.written = append(w.written, wp...)
return len(p), nil
}
2026-02-22 16:30:37 +01:00
func testContent(r io.Reader, o buffer.Options) buffer.Reader {
return buffer.BufferedContent(
buffer.ContentFunc(func(w io.Writer) (int64, error) {
return io.Copy(w, r)
}),
o,
)
}