use fin_stream::error::StreamError;
use fin_stream::ring::SpscRing;
#[test]
fn test_ring_full_overwrites_oldest() {
let ring: SpscRing<u32, 4> = SpscRing::new();
ring.push(10).unwrap();
ring.push(20).unwrap();
ring.push(30).unwrap();
assert!(
ring.is_full(),
"ring should be full after 3 pushes (capacity = 3)"
);
let err = ring.push(99).unwrap_err();
assert!(
matches!(err, StreamError::RingBufferFull { capacity: 3 }),
"expected RingBufferFull {{ capacity: 3 }}, got {:?}",
err
);
assert_eq!(ring.pop().unwrap(), 10, "oldest item must still be 10");
assert_eq!(ring.pop().unwrap(), 20);
assert_eq!(ring.pop().unwrap(), 30);
assert!(ring.is_empty());
}
#[test]
fn test_ring_empty_pop_returns_none() {
let ring: SpscRing<u64, 8> = SpscRing::new();
let err = ring.pop().unwrap_err();
assert!(
matches!(err, StreamError::RingBufferEmpty),
"expected RingBufferEmpty on initial pop, got {:?}",
err
);
ring.push(42).unwrap();
assert_eq!(ring.pop().unwrap(), 42);
let err2 = ring.pop().unwrap_err();
assert!(
matches!(err2, StreamError::RingBufferEmpty),
"expected RingBufferEmpty after draining, got {:?}",
err2
);
}
#[test]
fn test_ring_capacity_one() {
let ring: SpscRing<i32, 2> = SpscRing::new();
assert_eq!(ring.capacity(), 1);
assert!(ring.is_empty());
ring.push(7).unwrap();
assert!(
ring.is_full(),
"ring of capacity 1 must be full after one push"
);
assert_eq!(ring.len(), 1);
let err = ring.push(99).unwrap_err();
assert!(
matches!(err, StreamError::RingBufferFull { capacity: 1 }),
"expected RingBufferFull {{ capacity: 1 }}, got {:?}",
err
);
let v = ring.pop().unwrap();
assert_eq!(v, 7);
assert!(ring.is_empty());
ring.push(42).unwrap();
assert_eq!(ring.pop().unwrap(), 42);
}
#[test]
fn test_ring_capacity_n_minus_one() {
let ring: SpscRing<u8, 8> = SpscRing::new();
assert_eq!(ring.capacity(), 7);
let ring16: SpscRing<u8, 16> = SpscRing::new();
assert_eq!(ring16.capacity(), 15);
}
#[test]
fn test_ring_interleaved_push_pop_at_boundary() {
let ring: SpscRing<u32, 4> = SpscRing::new(); ring.push(1).unwrap();
ring.push(2).unwrap();
ring.push(3).unwrap();
assert!(ring.is_full());
assert_eq!(ring.pop().unwrap(), 1);
assert!(!ring.is_full());
ring.push(4).unwrap();
assert!(ring.is_full());
assert_eq!(ring.pop().unwrap(), 2);
assert_eq!(ring.pop().unwrap(), 3);
assert_eq!(ring.pop().unwrap(), 4);
assert!(ring.is_empty());
}
#[test]
fn test_ring_buffer_full_error_capacity_matches() {
let ring: SpscRing<u8, 8> = SpscRing::new(); for i in 0..7u8 {
ring.push(i).unwrap();
}
let err = ring.push(99).unwrap_err();
match err {
StreamError::RingBufferFull { capacity } => {
assert_eq!(capacity, 7, "capacity in error must match ring capacity");
}
other => panic!("unexpected error: {:?}", other),
}
}
#[test]
fn test_ring_error_display() {
let full = StreamError::RingBufferFull { capacity: 1024 };
let empty = StreamError::RingBufferEmpty;
assert!(
full.to_string().contains("1024"),
"full display must include capacity"
);
assert!(
full.to_string().contains("full"),
"full display must say 'full'"
);
assert!(
empty.to_string().contains("empty"),
"empty display must say 'empty'"
);
}