<commit_before>package buffer

import (
	"bytes"
	"crypto/rand"
	"encoding/gob"
	"io"
	"io/ioutil"
	"os"
	"testing"
)

func BenchmarkMemory(b *testing.B) {
	buf := New(32 * 1024)
	for i := 0; i < b.N; i++ {
		io.Copy(buf, io.LimitReader(rand.Reader, 32*1024))
		io.Copy(ioutil.Discard, buf)
	}
}

func TestOverflow(t *testing.T) {
	buf := NewMulti(New(5), NewDiscard())
	buf.Write([]byte("Hello World"))

	data, err := ioutil.ReadAll(buf)
	if err != nil {
		t.Error(err.Error())
	}

	if !bytes.Equal(data, []byte("Hello")) {
		t.Errorf("Expected Hello got %s", string(data))
	}

}

func TestWriteAt(t *testing.T) {
	var b BufferAt

	b = New(5)
	BufferAtTester(t, b)

	file, err := ioutil.TempFile("", "buffer")
	if err != nil {
		t.Error(err.Error())
	}
	defer os.Remove(file.Name())
	defer file.Close()

	b = NewFile(5, file)
	BufferAtTester(t, b)

}

func BufferAtTester(t *testing.T, b BufferAt) {
	b.WriteAt([]byte("abc"), 0)
	Compare(t, b, "abc")

	b.WriteAt([]byte("abc"), 1)
	Compare(t, b, "aabc")

	b.WriteAt([]byte("abc"), 2)
	Compare(t, b, "aaabc")

	b.WriteAt([]byte("abc"), 3)
	Compare(t, b, "aaaab")

	b.Read(make([]byte, 2))

	Compare(t, b, "aab")
	b.Reset()
}

func Compare(t *testing.T, b BufferAt, s string) {
	data := make([]byte, b.Len())
	n, _ := b.ReadAt(data, 0)
	if string(data[:n]) != s {
		t.Error("Mismatch:", string(data[:n]), s)
	}
}

func TestRing(t *testing.T) {
	ring := NewRing(New(3))
	if ring.Len() != 0 {
		t.Errorf("Ring non-empty start!")
	}

	if ring.Cap() != MAXINT64 {
		t.Errorf("Ring has < max capacity")
	}

	ring.Write([]byte("abc"))
	if ring.Len() != 3 {
		t.Errorf("expected ring len == 3")
	}

	ring.Write([]byte("de"))
	if ring.Len() != 3 {
		t.Errorf("expected riing len == 3")
	}

	data := make([]byte, 12)
	if n, err := ring.Read(data); err != nil {
		t.Error(err.Error())
	} else {
		if !bytes.Equal(data[:n], []byte("cde")) {
			t.Errorf("expected cde, got %s", data[:n])
		}
	}

	if ring.Len() != 0 {
		t.Errorf("ring should now be empty")
	}

	ring.Write([]byte("hello"))
	ring.Reset()

	if ring.Len() != 0 {
		t.Errorf("ring should still be empty")
	}
}

func TestGob(t *testing.T) {
	str := "HelloWorld"

	buf := NewUnboundedBuffer(2, 2)
	buf.Write([]byte(str))
	b := bytes.NewBuffer(nil)
	var test Buffer = buf
	if err := gob.NewEncoder(b).Encode(&test); err != nil {
		t.Error(err.Error())
		return
	}
	var buffer Buffer
	if err := gob.NewDecoder(b).Decode(&buffer); err != nil {
		t.Error(err.Error())
		return
	}
	data := make([]byte, len(str))
	if _, err := buffer.Read(data); err != nil && err != io.EOF {
		t.Error(err.Error())
	}
	if !bytes.Equal(data, []byte(str)) {
		t.Error("Gob Recover Failed... " + string(data))
	}
	buffer.Reset()
}

func TestDiscard(t *testing.T) {
	buf := NewDiscard()
	if buf.Cap() != MAXINT64 {
		t.Errorf("cap isn't infinite")
	}
	buf.Write([]byte("hello"))
	if buf.Len() != 0 {
		t.Errorf("buf should always be empty")
	}
}

func TestSpill(t *testing.T) {
	buf := NewMulti(New(5), NewDiscard())
	buf.Write([]byte("Hello World"))
	data := make([]byte, 12)<commit_msg>fixed TestSpill to use NewSpill<commit_after>package buffer

import (
	"bytes"
	"crypto/rand"
	"encoding/gob"
	"io"
	"io/ioutil"
	"os"
	"testing"
)

func BenchmarkMemory(b *testing.B) {
	buf := New(32 * 1024)
	for i := 0; i < b.N; i++ {
		io.Copy(buf, io.LimitReader(rand.Reader, 32*1024))
		io.Copy(ioutil.Discard, buf)
	}
}

func TestOverflow(t *testing.T) {
	buf := NewMulti(New(5), NewDiscard())
	buf.Write([]byte("Hello World"))

	data, err := ioutil.ReadAll(buf)
	if err != nil {
		t.Error(err.Error())
	}

	if !bytes.Equal(data, []byte("Hello")) {
		t.Errorf("Expected Hello got %s", string(data))
	}

}

func TestWriteAt(t *testing.T) {
	var b BufferAt

	b = New(5)
	BufferAtTester(t, b)

	file, err := ioutil.TempFile("", "buffer")
	if err != nil {
		t.Error(err.Error())
	}
	defer os.Remove(file.Name())
	defer file.Close()

	b = NewFile(5, file)
	BufferAtTester(t, b)

}

func BufferAtTester(t *testing.T, b BufferAt) {
	b.WriteAt([]byte("abc"), 0)
	Compare(t, b, "abc")

	b.WriteAt([]byte("abc"), 1)
	Compare(t, b, "aabc")

	b.WriteAt([]byte("abc"), 2)
	Compare(t, b, "aaabc")

	b.WriteAt([]byte("abc"), 3)
	Compare(t, b, "aaaab")

	b.Read(make([]byte, 2))

	Compare(t, b, "aab")
	b.Reset()
}

func Compare(t *testing.T, b BufferAt, s string) {
	data := make([]byte, b.Len())
	n, _ := b.ReadAt(data, 0)
	if string(data[:n]) != s {
		t.Error("Mismatch:", string(data[:n]), s)
	}
}

func TestRing(t *testing.T) {
	ring := NewRing(New(3))
	if ring.Len() != 0 {
		t.Errorf("Ring non-empty start!")
	}

	if ring.Cap() != MAXINT64 {
		t.Errorf("Ring has < max capacity")
	}

	ring.Write([]byte("abc"))
	if ring.Len() != 3 {
		t.Errorf("expected ring len == 3")
	}

	ring.Write([]byte("de"))
	if ring.Len() != 3 {
		t.Errorf("expected riing len == 3")
	}

	data := make([]byte, 12)
	if n, err := ring.Read(data); err != nil {
		t.Error(err.Error())
	} else {
		if !bytes.Equal(data[:n], []byte("cde")) {
			t.Errorf("expected cde, got %s", data[:n])
		}
	}

	if ring.Len() != 0 {
		t.Errorf("ring should now be empty")
	}

	ring.Write([]byte("hello"))
	ring.Reset()

	if ring.Len() != 0 {
		t.Errorf("ring should still be empty")
	}
}

func TestGob(t *testing.T) {
	str := "HelloWorld"

	buf := NewUnboundedBuffer(2, 2)
	buf.Write([]byte(str))
	b := bytes.NewBuffer(nil)
	var test Buffer = buf
	if err := gob.NewEncoder(b).Encode(&test); err != nil {
		t.Error(err.Error())
		return
	}
	var buffer Buffer
	if err := gob.NewDecoder(b).Decode(&buffer); err != nil {
		t.Error(err.Error())
		return
	}
	data := make([]byte, len(str))
	if _, err := buffer.Read(data); err != nil && err != io.EOF {
		t.Error(err.Error())
	}
	if !bytes.Equal(data, []byte(str)) {
		t.Error("Gob Recover Failed... " + string(data))
	}
	buffer.Reset()
}

func TestDiscard(t *testing.T) {
	buf := NewDiscard()
	if buf.Cap() != MAXINT64 {
		t.Errorf("cap isn't infinite")
	}
	buf.Write([]byte("hello"))
	if buf.Len() != 0 {
		t.Errorf("buf should always be empty")
	}
}

func TestSpill(t *testing.T) {
	buf := NewSpill(New(5), NewDiscard())
	buf.Write([]byte("Hello World"))
	data := make([]byte, 12)
{'fraction_non_alphanumeric': 0.2201954397394137, 'fraction_numerical': 0.013680781758957655, 'mean_word_length': 3.7715617715617715, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2303134', 'n_tokens_mistral': 2722, 'n_tokens_neox': 2550, 'n_words': 563}