package detect import ( "testing" "github.com/stretchr/testify/assert" ) func TestRingBuffer_FIFO(t *testing.T) { // 1. Initialize with capacity 10 rb := newRingBuffer(10) assert.Equal(t, 10, rb.cap) assert.Equal(t, 0, rb.size) // 2. Fill it up for i := 1; i <= 10; i++ { rb.push(float64(i)) } assert.Equal(t, 10, rb.size) // head should be at 0 after 10 pushes assert.Equal(t, 0, rb.head) // 3. Verify quantile (sorted view) // sorted: [1 2 3 4 5 6 7 8 9 10] // quantile 0.5 (median) of 10 items: index int(0.5 * 9) = 4 -> value 5 assert.Equal(t, 5.0, rb.quantileVal(0.5)) // 4. Push one more to trigger FIFO eviction // Should evict "1" (the oldest) rb.push(11.0) assert.Equal(t, 10, rb.size) assert.Equal(t, 1, rb.head) // 5. Verify the oldest (1.0) is gone and 11.0 is present // sorted: [2 3 4 5 6 7 8 9 10 11] // idx = int(0.4 * 9) = 3 -> value at index 3 is 5.0 assert.Equal(t, 5.0, rb.quantileVal(0.4)) // let's be precise: idx = int(p * 9) // p=0 -> idx 0 (2.0) // p=1 -> idx 9 (11.0) assert.Equal(t, 2.0, rb.quantileVal(0.0)) assert.Equal(t, 11.0, rb.quantileVal(1.0)) } func TestRingBuffer_Rank(t *testing.T) { rb := newRingBuffer(5) // Rank is float64(rank) / float64(n-1) assert.Equal(t, 0.5, rb.push(10.0)) // n=1 -> 0.5 assert.Equal(t, 1.0, rb.push(20.0)) // n=2, sorted=[10, 20], search(20)->1. 1/(2-1)=1.0 assert.Equal(t, 0.0, rb.push(5.0)) // n=3, sorted=[5, 10, 20], search(5)->0. 0/2=0.0 // n=4, sorted=[5 10 10 20], search(10) -> idx 1. 1/(4-1) = 0.333... assert.InDelta(t, 0.3333333333333333, rb.push(10.0), 1e-9) rb = newRingBuffer(4) rb.push(1.0) rb.push(3.0) rank := rb.push(2.0) // n=3, sorted=[1, 2, 3], search(2)->idx 1. 1/(3-1)=0.5 assert.Equal(t, 0.5, rank) }