package process import ( "sync" "testing" "github.com/stretchr/testify/assert" ) func TestBuffer_Write_Good(t *testing.T) { t.Run("write and read", func(t *testing.T) { rb := NewRingBuffer(10) itemCount, err := rb.Write([]byte("hello")) assert.NoError(t, err) assert.Equal(t, 5, itemCount) assert.Equal(t, "hello", rb.String()) assert.Equal(t, 5, rb.Len()) }) t.Run("overflow wraps around", func(t *testing.T) { rb := NewRingBuffer(5) _, _ = rb.Write([]byte("hello")) assert.Equal(t, "hello", rb.String()) _, _ = rb.Write([]byte("world")) // Should contain "world" (overwrote "hello") assert.Equal(t, 5, rb.Len()) assert.Equal(t, "world", rb.String()) }) t.Run("partial overflow", func(t *testing.T) { rb := NewRingBuffer(10) _, _ = rb.Write([]byte("hello")) _, _ = rb.Write([]byte("worldx")) // Should contain "lloworldx" (11 chars, buffer is 10) assert.Equal(t, 10, rb.Len()) }) t.Run("bytes returns copy", func(t *testing.T) { rb := NewRingBuffer(10) _, _ = rb.Write([]byte("hello")) contents := rb.Bytes() assert.Equal(t, []byte("hello"), contents) // Modifying returned bytes shouldn't affect buffer contents[0] = 'x' assert.Equal(t, "hello", rb.String()) }) } func TestBuffer_Write_Bad(t *testing.T) { t.Run("empty write is a no-op", func(t *testing.T) { rb := NewRingBuffer(10) itemCount, err := rb.Write([]byte{}) assert.NoError(t, err) assert.Equal(t, 0, itemCount) assert.Equal(t, "", rb.String()) }) } func TestBuffer_Write_Ugly(t *testing.T) { t.Run("concurrent writes do not race", func(t *testing.T) { rb := NewRingBuffer(64) var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() _, _ = rb.Write([]byte("data")) }() } wg.Wait() // Buffer should not panic and length should be bounded by capacity assert.LessOrEqual(t, rb.Len(), rb.Cap()) }) } func TestBuffer_String_Good(t *testing.T) { t.Run("empty buffer returns empty string", func(t *testing.T) { rb := NewRingBuffer(10) assert.Equal(t, "", rb.String()) }) t.Run("full buffer wraps correctly", func(t *testing.T) { rb := NewRingBuffer(5) _, _ = rb.Write([]byte("abcde")) assert.Equal(t, "abcde", rb.String()) }) } func TestBuffer_String_Bad(t *testing.T) { t.Run("overflowed buffer reflects newest data", func(t *testing.T) { rb := NewRingBuffer(5) _, _ = rb.Write([]byte("hello")) _, _ = rb.Write([]byte("world")) // Oldest bytes ("hello") have been overwritten assert.Equal(t, "world", rb.String()) }) } func TestBuffer_String_Ugly(t *testing.T) { t.Run("size-1 buffer holds only last byte", func(t *testing.T) { rb := NewRingBuffer(1) _, _ = rb.Write([]byte("abc")) assert.Equal(t, "c", rb.String()) }) } func TestBuffer_Reset_Good(t *testing.T) { t.Run("clears all data", func(t *testing.T) { rb := NewRingBuffer(10) _, _ = rb.Write([]byte("hello")) rb.Reset() assert.Equal(t, "", rb.String()) assert.Equal(t, 0, rb.Len()) }) t.Run("cap returns buffer capacity", func(t *testing.T) { rb := NewRingBuffer(42) assert.Equal(t, 42, rb.Cap()) }) } func TestBuffer_Reset_Bad(t *testing.T) { t.Run("reset on empty buffer is a no-op", func(t *testing.T) { rb := NewRingBuffer(10) rb.Reset() assert.Equal(t, "", rb.String()) assert.Equal(t, 0, rb.Len()) }) } func TestBuffer_Reset_Ugly(t *testing.T) { t.Run("reset after overflow allows fresh writes", func(t *testing.T) { rb := NewRingBuffer(5) _, _ = rb.Write([]byte("hello")) _, _ = rb.Write([]byte("world")) rb.Reset() _, _ = rb.Write([]byte("new")) assert.Equal(t, "new", rb.String()) }) }