blob: f4e75f40d9a29b9cbe2cd187c04a93933eb9afe0 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package slicewriter
import (
"io"
"testing"
)
func TestSliceWriter(t *testing.T) {
sleq := func(t *testing.T, got []byte, want []byte) {
t.Helper()
if len(got) != len(want) {
t.Fatalf("bad length got %d want %d", len(got), len(want))
}
for i := range got {
if got[i] != want[i] {
t.Fatalf("bad read at %d got %d want %d", i, got[i], want[i])
}
}
}
wf := func(t *testing.T, ws *WriteSeeker, p []byte) {
t.Helper()
nw, werr := ws.Write(p)
if werr != nil {
t.Fatalf("unexpected write error: %v", werr)
}
if nw != len(p) {
t.Fatalf("wrong amount written want %d got %d", len(p), nw)
}
}
rf := func(t *testing.T, ws *WriteSeeker, p []byte) {
t.Helper()
b := make([]byte, len(p))
nr, rerr := ws.Read(b)
if rerr != nil {
t.Fatalf("unexpected read error: %v", rerr)
}
if nr != len(p) {
t.Fatalf("wrong amount read want %d got %d", len(p), nr)
}
sleq(t, b, p)
}
sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) {
t.Helper()
_, err := ws.Seek(offset, whence)
if err != nil {
t.Fatalf("unexpected seek error: %v", err)
}
}
wp1 := []byte{1, 2}
ws := &WriteSeeker{}
// write some stuff
wf(t, ws, wp1)
// check that BytesWritten returns what we wrote.
sleq(t, ws.BytesWritten(), wp1)
// offset is at end of slice, so reading should return zero bytes.
rf(t, ws, []byte{})
// write some more stuff
wp2 := []byte{7, 8, 9}
wf(t, ws, wp2)
// check that BytesWritten returns what we expect.
wpex := []byte{1, 2, 7, 8, 9}
sleq(t, ws.BytesWritten(), wpex)
rf(t, ws, []byte{})
// seeks and reads.
sk(t, ws, 1, io.SeekStart)
rf(t, ws, []byte{2, 7})
sk(t, ws, -2, io.SeekCurrent)
rf(t, ws, []byte{2, 7})
sk(t, ws, -4, io.SeekEnd)
rf(t, ws, []byte{2, 7})
// seek back and overwrite
sk(t, ws, 1, io.SeekStart)
wf(t, ws, []byte{9, 11})
wpex = []byte{1, 9, 11, 8, 9}
sleq(t, ws.BytesWritten(), wpex)
// seeks on empty writer.
ws2 := &WriteSeeker{}
sk(t, ws2, 0, io.SeekStart)
sk(t, ws2, 0, io.SeekCurrent)
sk(t, ws2, 0, io.SeekEnd)
// check for seek errors.
_, err := ws.Seek(-1, io.SeekStart)
if err == nil {
t.Fatalf("expected error on invalid -1 seek")
}
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekStart)
if err == nil {
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
}
ws.Seek(0, io.SeekStart)
_, err = ws.Seek(-1, io.SeekCurrent)
if err == nil {
t.Fatalf("expected error on invalid -1 seek")
}
_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekCurrent)
if err == nil {
t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
}
_, err = ws.Seek(1, io.SeekEnd)
if err == nil {
t.Fatalf("expected error on invalid 1 seek")
}
bsamt := int64(-1*len(ws.BytesWritten()) - 1)
_, err = ws.Seek(bsamt, io.SeekEnd)
if err == nil {
t.Fatalf("expected error on invalid %d seek", bsamt)
}
// bad seek mode
_, err = ws.Seek(-1, io.SeekStart+9)
if err == nil {
t.Fatalf("expected error on invalid seek mode")
}
}