199 lines
3.5 KiB
Go
199 lines
3.5 KiB
Go
package circular
|
|
|
|
import (
|
|
"io"
|
|
"testing"
|
|
)
|
|
|
|
// Here is one way you can have a test case verify that the expected
|
|
// interfaces are implemented.
|
|
|
|
var _ io.ByteReader = new(Buffer)
|
|
var _ io.ByteWriter = new(Buffer)
|
|
|
|
// testBuffer and methods support the tests, providing log and fail messages.
|
|
|
|
type testBuffer struct {
|
|
*testing.T
|
|
b *Buffer
|
|
}
|
|
|
|
func nb(size int, t *testing.T) testBuffer {
|
|
t.Logf("NewBuffer(%d)", size)
|
|
return testBuffer{t, NewBuffer(size)}
|
|
}
|
|
|
|
func (tb testBuffer) read(want byte) {
|
|
switch c, err := tb.b.ReadByte(); {
|
|
case err != nil:
|
|
var _ error = err
|
|
tb.Fatalf("ReadByte() failed unexpectedly: %v", err)
|
|
case c != want:
|
|
tb.Fatalf("ReadByte() = %c, want %c.", c, want)
|
|
}
|
|
tb.Logf("ReadByte %c", want)
|
|
}
|
|
|
|
func (tb testBuffer) readFail() {
|
|
c, err := tb.b.ReadByte()
|
|
if err == nil {
|
|
tb.Fatalf("ReadByte() = %c, expected a failure", c)
|
|
}
|
|
var _ error = err
|
|
tb.Log("ReadByte() fails as expected")
|
|
}
|
|
|
|
func (tb testBuffer) write(c byte) {
|
|
if err := tb.b.WriteByte(c); err != nil {
|
|
var _ error = err
|
|
tb.Fatalf("WriteByte(%c) failed unexpectedly: %v", c, err)
|
|
}
|
|
tb.Logf("WriteByte(%c)", c)
|
|
}
|
|
|
|
func (tb testBuffer) writeFail(c byte) {
|
|
err := tb.b.WriteByte(c)
|
|
if err == nil {
|
|
tb.Fatalf("WriteByte(%c) succeeded, expected a failure", c)
|
|
}
|
|
var _ error = err
|
|
tb.Logf("WriteByte(%c) fails as expected", c)
|
|
}
|
|
|
|
func (tb testBuffer) reset() {
|
|
tb.b.Reset()
|
|
tb.Log("Reset()")
|
|
}
|
|
|
|
func (tb testBuffer) overwrite(c byte) {
|
|
tb.b.Overwrite(c)
|
|
tb.Logf("Overwrite(%c)", c)
|
|
}
|
|
|
|
// tests. separate functions so log will have descriptive test name.
|
|
|
|
func TestReadEmptyBuffer(t *testing.T) {
|
|
tb := nb(1, t)
|
|
tb.readFail()
|
|
}
|
|
|
|
func TestWriteAndReadOneItem(t *testing.T) {
|
|
tb := nb(1, t)
|
|
tb.write('1')
|
|
tb.read('1')
|
|
tb.readFail()
|
|
}
|
|
|
|
func TestWriteAndReadMultipleItems(t *testing.T) {
|
|
tb := nb(2, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.read('1')
|
|
tb.read('2')
|
|
tb.readFail()
|
|
}
|
|
|
|
func TestReset(t *testing.T) {
|
|
tb := nb(3, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.write('3')
|
|
tb.reset()
|
|
tb.write('1')
|
|
tb.write('3')
|
|
tb.read('1')
|
|
tb.write('4')
|
|
tb.read('3')
|
|
}
|
|
|
|
func TestAlternateWriteAndRead(t *testing.T) {
|
|
tb := nb(2, t)
|
|
tb.write('1')
|
|
tb.read('1')
|
|
tb.write('2')
|
|
tb.read('2')
|
|
}
|
|
|
|
func TestReadOldestItem(t *testing.T) {
|
|
tb := nb(3, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.read('1')
|
|
tb.write('3')
|
|
tb.read('2')
|
|
tb.read('3')
|
|
}
|
|
|
|
func TestWriteFullBuffer(t *testing.T) {
|
|
tb := nb(2, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.writeFail('A')
|
|
}
|
|
|
|
func TestOverwriteFull(t *testing.T) {
|
|
tb := nb(2, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.overwrite('A')
|
|
tb.read('2')
|
|
tb.read('A')
|
|
tb.readFail()
|
|
}
|
|
|
|
func TestOverwriteNonFull(t *testing.T) {
|
|
tb := nb(2, t)
|
|
tb.write('1')
|
|
tb.overwrite('2')
|
|
tb.read('1')
|
|
tb.read('2')
|
|
tb.readFail()
|
|
}
|
|
|
|
func TestAlternateReadAndOverwrite(t *testing.T) {
|
|
tb := nb(5, t)
|
|
tb.write('1')
|
|
tb.write('2')
|
|
tb.write('3')
|
|
tb.read('1')
|
|
tb.read('2')
|
|
tb.write('4')
|
|
tb.read('3')
|
|
tb.write('5')
|
|
tb.write('6')
|
|
tb.write('7')
|
|
tb.write('8')
|
|
tb.overwrite('A')
|
|
tb.overwrite('B')
|
|
tb.read('6')
|
|
tb.read('7')
|
|
tb.read('8')
|
|
tb.read('A')
|
|
tb.read('B')
|
|
tb.readFail()
|
|
}
|
|
|
|
func BenchmarkOverwrite(b *testing.B) {
|
|
if testing.Short() {
|
|
b.Skip("skipping benchmark in short mode.")
|
|
}
|
|
c := NewBuffer(100)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
c.Overwrite(0)
|
|
}
|
|
b.SetBytes(int64(b.N))
|
|
}
|
|
|
|
func BenchmarkWriteRead(b *testing.B) {
|
|
if testing.Short() {
|
|
b.Skip("skipping benchmark in short mode.")
|
|
}
|
|
c := NewBuffer(100)
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
c.WriteByte(0)
|
|
c.ReadByte()
|
|
}
|
|
b.SetBytes(int64(b.N))
|
|
}
|