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") } }) }