use swactor::worker::Mailbox; // ── Basic operations ── #[test] fn push_and_pop() { let mut mb = Mailbox::new(10); mb.push(42i32); assert_eq!(mb.pop(), Some(42)); } #[test] fn fifo_ordering() { let mut mb = Mailbox::new(10); mb.push(1); mb.push(2); mb.push(3); assert_eq!(mb.pop(), Some(1)); assert_eq!(mb.pop(), Some(2)); assert_eq!(mb.pop(), Some(3)); } #[test] fn pop_empty() { let mut mb: Mailbox = Mailbox::new(10); assert_eq!(mb.pop(), None); } #[test] fn multiple_messages() { let mut mb = Mailbox::new(10); for i in 0..100 { mb.push(i); } for i in 0..100 { assert_eq!(mb.pop(), Some(i)); } assert_eq!(mb.pop(), None); } #[test] fn interleaved_push_pop() { let mut mb = Mailbox::new(10); mb.push(1); mb.push(2); assert_eq!(mb.pop(), Some(1)); mb.push(3); assert_eq!(mb.pop(), Some(2)); assert_eq!(mb.pop(), Some(3)); assert_eq!(mb.pop(), None); } // ── Drain count / watermark logic ── #[test] fn drain_count_empty() { let mb: Mailbox = Mailbox::new(10); assert_eq!(mb.drain_count(), 0); } #[test] fn drain_count_below_waterlevel() { let mut mb = Mailbox::new(10); for i in 0..5 { mb.push(i); } // 5 < 10 (default waterlevel) → process all assert_eq!(mb.drain_count(), 5); } #[test] fn drain_count_at_waterlevel() { let mut mb = Mailbox::new(10); for i in 0..10 { mb.push(i); } // 10 >= 10 → process half → 5 assert_eq!(mb.drain_count(), 5); } #[test] fn drain_count_above_waterlevel() { let mut mb = Mailbox::new(10); for i in 0..20 { mb.push(i); } // 20 >= 10 → 20 >> 1 = 10 assert_eq!(mb.drain_count(), 10); } #[test] fn drain_count_one_message() { let mut mb = Mailbox::new(10); mb.push(1i32); // 1 < 10 → process all → 1 assert_eq!(mb.drain_count(), 1); } #[test] fn drain_count_just_below_waterlevel() { let mut mb = Mailbox::new(10); for i in 0..9 { mb.push(i); } // 9 < 10 → process all → 9 assert_eq!(mb.drain_count(), 9); } #[test] fn drain_count_large() { let mut mb = Mailbox::new(10); for i in 0..1000 { mb.push(i); } // 1000 >= 10 → 1000 >> 1 = 500 assert_eq!(mb.drain_count(), 500); } #[test] fn drain_count_custom_waterlevel() { let mut mb = Mailbox::new(4); for i in 0..3 { mb.push(i); } // 3 < 4 → process all → 3 assert_eq!(mb.drain_count(), 3); mb.push(99); // 4 >= 4 → 4 >> 1 = 2 assert_eq!(mb.drain_count(), 2); } #[test] fn drain_count_updates_after_pop() { let mut mb = Mailbox::new(10); for i in 0..20 { mb.push(i); } // 20 >= 10 → 10 assert_eq!(mb.drain_count(), 10); // pop 15, leaving 5 for _ in 0..15 { mb.pop(); } // 5 < 10 → process all → 5 assert_eq!(mb.drain_count(), 5); } // ── Properties ── #[test] fn len_tracks_pushes() { let mut mb = Mailbox::new(10); assert_eq!(mb.len(), 0); mb.push(1); assert_eq!(mb.len(), 1); mb.push(2); assert_eq!(mb.len(), 2); mb.push(3); assert_eq!(mb.len(), 3); } #[test] fn len_tracks_pops() { let mut mb = Mailbox::new(10); mb.push(1); mb.push(2); mb.push(3); assert_eq!(mb.len(), 3); mb.pop(); assert_eq!(mb.len(), 2); mb.pop(); assert_eq!(mb.len(), 1); mb.pop(); assert_eq!(mb.len(), 0); } #[test] fn is_empty_on_new() { let mb: Mailbox = Mailbox::new(10); assert!(mb.is_empty()); } #[test] fn is_empty_after_drain() { let mut mb = Mailbox::new(10); mb.push(1); mb.push(2); mb.push(3); assert!(!mb.is_empty()); mb.pop(); mb.pop(); mb.pop(); assert!(mb.is_empty()); } // ── Type tests ── #[test] fn works_with_primitive_types() { let mut mb_i32 = Mailbox::new(10); mb_i32.push(42i32); assert_eq!(mb_i32.pop(), Some(42)); let mut mb_string = Mailbox::new(10); mb_string.push(String::from("hello")); assert_eq!(mb_string.pop(), Some(String::from("hello"))); } #[test] fn works_with_custom_structs() { #[derive(Debug, Clone, PartialEq)] struct MyMsg { id: u64, payload: String, } let mut mb = Mailbox::new(10); let msg = MyMsg { id: 1, payload: "test".into(), }; mb.push(msg.clone()); assert_eq!(mb.pop(), Some(msg)); }