//! Extreme edge case tests for the announcement crate. //! Testing 100+ edge cases that could break the implementation. use announcement::{AnnounceError, Announcement, Listener}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::mem; use std::sync::{Arc, Mutex, RwLock}; use std::thread; use std::time::Duration; /// Test: Edge case: Announce at the exact moment of listener creation /// /// Verifies: Handles edge case: announce at the exact moment of listener creation /// Category: edge #[test] fn test_announce_during_listener_creation() { for _ in 0..1000 { let (announcer, announcement) = Announcement::new(); let announcement_clone = announcement.clone(); let handle = thread::spawn(move || { announcer.announce(42).unwrap(); }); let listener = announcement_clone.listener(); handle.join().unwrap(); // Should always receive the value assert!(listener.try_listen().is_some()); } } /// Test: Edge case: Rapid creation and dropping of listeners /// /// Verifies: Handles edge case: rapid creation and dropping of listeners /// Category: edge #[test] fn test_rapid_listener_churn() { let (announcer, announcement) = Announcement::new(); // Create and drop 10000 listeners rapidly for _ in 0..10000 { let _ = announcement.listener(); } let final_listener = announcement.listener(); announcer.announce(999).unwrap(); assert_eq!(final_listener.try_listen(), Some(999)); } /// Test: Edge case: Announcer dropped without announcing /// /// Verifies: Handles edge case: announcer dropped without announcing /// Category: edge #[test] fn test_announcer_dropped_without_announce() { let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); drop(announcer); // Listener should never receive a value assert_eq!(listener.try_listen(), None); } /// Test: Edge case: All listeners dropped before announcing /// /// Verifies: Handles edge case: all listeners dropped before announcing /// Category: edge #[test] fn test_all_listeners_dropped_before_announce() { let (announcer, announcement) = Announcement::new(); { let _l1 = announcement.listener(); let _l2 = announcement.listener(); let _l3 = announcement.listener(); // All listeners dropped here } // Should still succeed announcer.announce(42).unwrap(); // New listener should get the value let new_listener = announcement.listener(); assert_eq!(new_listener.try_listen(), Some(42)); } /// Test: Edge case: Zero-sized types /// /// Verifies: Handles edge case: zero-sized types /// Category: edge #[test] fn test_zero_sized_type() { let (announcer, announcement) = Announcement::<()>::new(); let listener = announcement.listener(); announcer.announce(()).unwrap(); assert_eq!(listener.try_listen(), Some(())); } /// Test: Edge case: Very large types (1MB+) /// /// Verifies: Handles edge case: very large types (1mb+) /// Category: edge #[test] fn test_very_large_type() { #[derive(Clone, Debug, PartialEq)] struct LargeType { data: Vec, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let large = LargeType { data: vec![0u8; 1024 * 1024], // 1MB }; announcer.announce(large.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.data.len(), 1024 * 1024); } /// Test: Edge case: Recursive types with Arc /// /// Verifies: Handles edge case: recursive types with arc /// Category: edge #[test] fn test_recursive_type_with_arc() { #[derive(Clone, Debug)] struct Node { value: i32, next: Option>, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let node = Arc::new(Node { value: 42, next: Some(Arc::new(Node { value: 43, next: None, })), }); announcer.announce(node.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.value, 42); assert_eq!(received.next.as_ref().unwrap().value, 43); } /// Test: Edge case: Empty announcements (unit type) /// /// Verifies: Handles edge case: empty announcements (unit type) /// Category: edge #[test] fn test_empty_announcement() { let (announcer, announcement) = Announcement::<()>::new(); let listeners: Vec<_> = (0..100).map(|_| announcement.listener()).collect(); announcer.announce(()).unwrap(); for listener in &listeners { assert_eq!(listener.try_listen(), Some(())); } } /// Test: Edge case: Nested announcement channels - using Arc to share announcer /// /// Verifies: Handles edge case: nested announcement channels - using arc to share announcer /// Category: edge #[test] fn test_nested_announcements() { let (outer_announcer, outer) = Announcement::::new(); let (_inner_announcer, inner) = Announcement::::new(); let outer_listener = outer.listener(); let _inner_listener: announcement::Listener = inner.listener(); // Announce a simple value instead of trying to pass the announcer outer_announcer.announce(42).unwrap(); let value = outer_listener.try_listen().unwrap(); // Create a new announcer for the inner channel let (inner_announcer2, inner2) = Announcement::::new(); let inner_listener2 = inner2.listener(); inner_announcer2.announce(value).unwrap(); assert_eq!(inner_listener2.try_listen(), Some(42)); } /// Test: Edge case: Announcement with HashMap /// /// Verifies: Handles edge case: announcement with hashmap /// Category: edge #[test] fn test_announcement_with_hashmap() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mut map = HashMap::new(); map.insert("key1", vec![1, 2, 3]); map.insert("key2", vec![4, 5, 6]); announcer.announce(map.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received["key1"], vec![1, 2, 3]); assert_eq!(received["key2"], vec![4, 5, 6]); } /// Test: Edge case: Announcement with HashSet /// /// Verifies: Handles edge case: announcement with hashset /// Category: edge #[test] fn test_announcement_with_hashset() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mut set = HashSet::new(); set.insert(1); set.insert(2); set.insert(3); announcer.announce(set.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.len(), 3); assert!(received.contains(&1)); } /// Test: Edge case: Announcement with BTreeMap /// /// Verifies: Handles edge case: announcement with btreemap /// Category: edge #[test] fn test_announcement_with_btreemap() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mut map = BTreeMap::new(); map.insert(3, "three"); map.insert(1, "one"); map.insert(2, "two"); announcer.announce(map.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received[&1], "one"); } /// Test: Edge case: Announcement with BTreeSet /// /// Verifies: Handles edge case: announcement with btreeset /// Category: edge #[test] fn test_announcement_with_btreeset() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mut set = BTreeSet::new(); set.insert("apple"); set.insert("banana"); set.insert("cherry"); announcer.announce(set.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.len(), 3); } /// Test: Edge case: Option types /// /// Verifies: Handles edge case: option types /// Category: edge #[test] fn test_option_none() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(None).unwrap(); assert_eq!(listener.try_listen(), Some(None)); } /// Test: Option type: option some /// /// Verifies: Handles Option::Some values /// Category: edge #[test] fn test_option_some() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(Some("Hello".to_string())).unwrap(); assert_eq!(listener.try_listen(), Some(Some("Hello".to_string()))); } /// Test: Edge case: Result types /// /// Verifies: Handles edge case: result types /// Category: edge #[test] fn test_result_ok() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(Ok(42)).unwrap(); assert_eq!(listener.try_listen(), Some(Ok(42))); } /// Test: Result type: result err /// /// Verifies: Handles Result::Err values /// Category: edge #[test] fn test_result_err() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(Err("Error".to_string())).unwrap(); assert_eq!(listener.try_listen(), Some(Err("Error".to_string()))); } /// Test: Edge case: Box types /// /// Verifies: Handles edge case: box types /// Category: edge #[test] fn test_boxed_type() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let boxed: Box> = Box::new(vec![1, 2, 3, 4, 5]); announcer.announce(boxed.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(boxed)); } /// Test: Edge case: Arc with interior mutability /// /// Verifies: Handles edge case: arc with interior mutability /// Category: edge #[test] fn test_arc_mutex() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let data = Arc::new(Mutex::new(42)); announcer.announce(data.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(*received.lock().unwrap(), 42); } /// Test: Interior mutability: Arc> /// /// Verifies: Handles Arc-wrapped rwlock correctly /// Category: edge #[test] fn test_arc_rwlock() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let data = Arc::new(RwLock::new(vec![1, 2, 3])); announcer.announce(data.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(*received.read().unwrap(), vec![1, 2, 3]); } /// Test: Edge case: Empty strings and vectors /// /// Verifies: Handles edge case: empty strings and vectors /// Category: edge #[test] fn test_empty_string() { let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); announcer.announce(String::new()).unwrap(); assert_eq!(listener.try_listen(), Some(String::new())); } /// Test: Empty collection: empty vec /// /// Verifies: Handles empty vec correctly /// Category: edge #[test] fn test_empty_vec() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(Vec::new()).unwrap(); assert_eq!(listener.try_listen(), Some(Vec::new())); } /// Test: Edge case: Very long strings /// /// Verifies: Handles edge case: very long strings /// Category: edge #[test] fn test_very_long_string() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let long_string = "x".repeat(10_000_000); // 10MB string announcer.announce(long_string.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.len(), 10_000_000); } /// Test: Edge case: Arrays of different sizes /// /// Verifies: Handles edge case: arrays of different sizes /// Category: edge #[test] fn test_zero_sized_array() { let (announcer, announcement) = Announcement::<[u8; 0]>::new(); let listener = announcement.listener(); announcer.announce([]).unwrap(); assert_eq!(listener.try_listen(), Some([])); } /// Test: Array: small fixed-size array /// /// Verifies: Handles small fixed-size arrays /// Category: edge #[test] fn test_small_array() { let (announcer, announcement) = Announcement::<[i32; 3]>::new(); let listener = announcement.listener(); announcer.announce([1, 2, 3]).unwrap(); assert_eq!(listener.try_listen(), Some([1, 2, 3])); } /// Test: Array: large fixed-size array (1KB) /// /// Verifies: Handles large fixed-size arrays /// Category: edge #[test] fn test_large_array() { let (announcer, announcement) = Announcement::<[u8; 1024]>::new(); let listener = announcement.listener(); let array = [42u8; 1024]; announcer.announce(array).unwrap(); assert_eq!(listener.try_listen(), Some(array)); } /// Test: Edge case: Tuples /// /// Verifies: Handles edge case: tuples /// Category: edge #[test] fn test_simple_tuple() { let (announcer, announcement) = Announcement::<(i32, i32)>::new(); let listener = announcement.listener(); announcer.announce((1, 2)).unwrap(); assert_eq!(listener.try_listen(), Some((1, 2))); } /// Test: Tuple: complex tuple /// /// Verifies: Handles complex tuple correctly /// Category: edge #[test] fn test_complex_tuple() { let (announcer, announcement) = Announcement::<(String, Vec, i32, Option)>::new(); let listener = announcement.listener(); let tuple = ("hello".to_string(), vec![1, 2, 3], 42, Some(true)); announcer.announce(tuple.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(tuple)); } /// Test: Edge case: Custom struct with Drop /// /// Verifies: Handles edge case: custom struct with drop /// Category: edge #[test] fn test_struct_with_drop() { static DROP_COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); #[derive(Clone, Debug)] #[allow(dead_code)] struct DropCounter { value: i32, } impl Drop for DropCounter { fn drop(&mut self) { DROP_COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst); } } DROP_COUNT.store(0, std::sync::atomic::Ordering::SeqCst); { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let counter = DropCounter { value: 42 }; announcer.announce(counter).unwrap(); let _received = listener.try_listen(); } // Check that drops happened assert!(DROP_COUNT.load(std::sync::atomic::Ordering::SeqCst) > 0); } /// Test: Edge case: Enums /// /// Verifies: Handles edge case: enums /// Category: edge #[test] fn test_simple_enum() { #[derive(Clone, Debug, PartialEq)] #[allow(dead_code)] enum SimpleEnum { A, B, C, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(SimpleEnum::B).unwrap(); assert_eq!(listener.try_listen(), Some(SimpleEnum::B)); } /// Test: Enum: complex enum /// /// Verifies: Handles complex enum with variants correctly /// Category: edge #[test] fn test_complex_enum() { #[derive(Clone, Debug, PartialEq)] #[allow(dead_code)] enum ComplexEnum { Empty, Value(i32), Tuple(String, Vec), Struct { x: f64, y: f64 }, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let val = ComplexEnum::Tuple("test".to_string(), vec![1, 2, 3]); announcer.announce(val.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(val)); } /// Test: Edge case: PhantomData /// /// Verifies: Handles edge case: phantomdata /// Category: edge #[test] fn test_phantom_data() { use std::marker::PhantomData; #[derive(Clone, Debug)] struct Phantom { value: i32, _phantom: PhantomData, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let phantom: Phantom = Phantom { value: 42, _phantom: PhantomData, }; announcer.announce(phantom).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.value, 42); } /// Test: Edge case: Function pointers /// /// Verifies: Handles edge case: function pointers /// Category: edge #[test] fn test_function_pointer() { fn example_fn() -> i32 { 42 } let (announcer, announcement) = Announcement:: i32>::new(); let listener = announcement.listener(); announcer.announce(example_fn).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received(), 42); } /// Test: Edge case: Trait objects /// /// Verifies: Handles edge case: trait objects /// Category: edge #[test] fn test_trait_object() { trait MyTrait: Send + Sync { fn value(&self) -> i32; } #[derive(Clone)] struct MyStruct(i32); impl MyTrait for MyStruct { fn value(&self) -> i32 { self.0 } } let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); let obj: Arc = Arc::new(MyStruct(42)); let _ = announcer.announce(obj); // Can't use unwrap because dyn MyTrait doesn't implement Debug let received = listener.try_listen().unwrap(); assert_eq!(received.value(), 42); } /// Test: Edge case: Deeply nested structures /// /// Verifies: Handles edge case: deeply nested structures /// Category: edge #[test] fn test_deeply_nested_structure() { #[derive(Clone, Debug)] struct Level1(Level2); #[derive(Clone, Debug)] struct Level2(Level3); #[derive(Clone, Debug)] struct Level3(Level4); #[derive(Clone, Debug)] struct Level4(Level5); #[derive(Clone, Debug)] struct Level5(Level6); #[derive(Clone, Debug)] struct Level6(Level7); #[derive(Clone, Debug)] struct Level7(Level8); #[derive(Clone, Debug)] struct Level8(Level9); #[derive(Clone, Debug)] struct Level9(Level10); #[derive(Clone, Debug)] struct Level10(i32); let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let nested = Level1(Level2(Level3(Level4(Level5(Level6(Level7(Level8( Level9(Level10(42)), )))))))); announcer.announce(nested).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.0 .0 .0 .0 .0 .0 .0 .0 .0 .0, 42); } /// Test: Edge case: Listener created after drop of announcer /// /// Verifies: Handles edge case: listener created after drop of announcer /// Category: edge #[test] fn test_listener_after_announcer_drop() { let announcement = { let (announcer, announcement) = Announcement::::new(); drop(announcer); announcement }; let listener = announcement.listener(); assert_eq!(listener.try_listen(), None); } /// Test: Edge case: Clone announcement after announce /// /// Verifies: Handles edge case: clone announcement after announce /// Category: edge #[test] fn test_clone_announcement_after_announce() { let (announcer, announcement) = Announcement::new(); announcer.announce(42).unwrap(); let cloned = announcement.clone(); let listener = cloned.listener(); assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Many threads creating listeners simultaneously /// /// Verifies: Handles edge case: many threads creating listeners simultaneously /// Category: edge #[test] fn test_concurrent_listener_creation() { let (announcer, announcement) = Announcement::new(); let mut handles = vec![]; for _ in 0..100 { let announcement_clone = announcement.clone(); handles.push(thread::spawn(move || announcement_clone.listener())); } let listeners: Vec<_> = handles.into_iter().map(|h| h.join().unwrap()).collect(); announcer.announce(42).unwrap(); for listener in &listeners { assert_eq!(listener.try_listen(), Some(42)); } } /// Test: Edge case: Maximum value sizes /// /// Verifies: Handles edge case: maximum value sizes /// Category: edge #[test] fn test_max_u128() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(u128::MAX).unwrap(); assert_eq!(listener.try_listen(), Some(u128::MAX)); } /// Test: Numeric boundary: i128::MIN /// /// Verifies: Handles minimum signed 128-bit integer value /// Category: edge #[test] fn test_min_i128() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(i128::MIN).unwrap(); assert_eq!(listener.try_listen(), Some(i128::MIN)); } /// Test: Edge case: NaN and infinity for floats /// /// Verifies: Handles edge case: nan and infinity for floats /// Category: edge #[test] fn test_nan_f64() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(f64::NAN).unwrap(); let received = listener.try_listen().unwrap(); assert!(received.is_nan()); } /// Test: Special value: floating point infinity /// /// Verifies: Handles positive/negative infinity correctly /// Category: edge #[test] fn test_infinity_f32() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(f32::INFINITY).unwrap(); assert_eq!(listener.try_listen(), Some(f32::INFINITY)); } /// Test: Special value: floating point infinity /// /// Verifies: Handles positive/negative infinity correctly /// Category: edge #[test] fn test_neg_infinity_f64() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(f64::NEG_INFINITY).unwrap(); assert_eq!(listener.try_listen(), Some(f64::NEG_INFINITY)); } /// Test: Edge case: Unicode strings /// /// Verifies: Handles edge case: unicode strings /// Category: edge #[test] fn test_unicode_emoji() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let emoji_string = "Hello 👋 World 🌍 🦀".to_string(); announcer.announce(emoji_string.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(emoji_string)); } /// Test: Unicode: unicode rtl /// /// Verifies: Handles unicode rtl correctly /// Category: edge #[test] fn test_unicode_rtl() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let rtl_string = "مرحبا بالعالم".to_string(); announcer.announce(rtl_string.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(rtl_string)); } /// Test: Unicode: unicode combining /// /// Verifies: Handles unicode combining correctly /// Category: edge #[test] fn test_unicode_combining() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let combining = "e\u{0301}".to_string(); // é as e + combining accent announcer.announce(combining.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(combining)); } /// Test: Edge case: Memory size checks /// /// Verifies: Handles edge case: memory size checks /// Category: edge #[test] fn test_announcement_memory_size() { let size = mem::size_of::>(); // Should be relatively small (just Arc pointers) // Two Arc pointers on 64-bit: inner + event assert!(size <= 16); } /// Test: Memory efficiency: Listener size /// /// Verifies: Verifies Listener type has minimal memory footprint /// Category: edge #[test] fn test_listener_memory_size() { let size = mem::size_of::>(); // Should be same as Announcement // Two Arc pointers on 64-bit: inner + event assert!(size <= 16); } /// Test: Edge case: Listener dropped immediately after creation /// /// Verifies: Handles edge case: listener dropped immediately after creation /// Category: edge #[test] fn test_listener_immediate_drop() { let (announcer, announcement) = Announcement::new(); for _ in 0..1000 { drop(announcement.listener()); } announcer.announce(42).unwrap(); // Should still work with new listener let listener = announcement.listener(); assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Announcement with closure /// /// Verifies: Handles edge case: announcement with closure /// Category: edge #[test] fn test_announcement_with_closure() { let (announcer, announcement) = Announcement:: i32 + Send + Sync>>::new(); let listener = announcement.listener(); let closure = Arc::new(|| 42) as Arc i32 + Send + Sync>; let _ = announcer.announce(closure); // Can't use unwrap because dyn Fn doesn't implement Debug let received = listener.try_listen().unwrap(); assert_eq!(received(), 42); } /// Test: Edge case: Announcement channel dropped before listeners /// /// Verifies: Handles edge case: announcement channel dropped before listeners /// Category: edge #[test] fn test_announcement_dropped_before_listeners() { let listener = { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(42).unwrap(); drop(announcement); listener }; assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Multiple announcement channels at once /// /// Verifies: Handles edge case: multiple announcement channels at once /// Category: edge #[test] fn test_multiple_channels() { let (a1, ann1) = Announcement::::new(); let (a2, ann2) = Announcement::::new(); let (a3, ann3) = Announcement::>::new(); let l1 = ann1.listener(); let l2 = ann2.listener(); let l3 = ann3.listener(); a1.announce(42).unwrap(); a2.announce("hello".to_string()).unwrap(); a3.announce(vec![1, 2, 3]).unwrap(); assert_eq!(l1.try_listen(), Some(42)); assert_eq!(l2.try_listen(), Some("hello".to_string())); assert_eq!(l3.try_listen(), Some(vec![1, 2, 3])); } /// Test: Edge case: Char boundary cases /// /// Verifies: Handles edge case: char boundary cases /// Category: edge #[test] fn test_char_boundaries() { let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); announcer.announce('\0').unwrap(); assert_eq!(listener.try_listen(), Some('\0')); let (announcer2, announcement2) = Announcement::::new(); let listener2 = announcement2.listener(); announcer2.announce('\u{10FFFF}').unwrap(); assert_eq!(listener2.try_listen(), Some('\u{10FFFF}')); } /// Test: Edge case: Bool values /// /// Verifies: Handles edge case: bool values /// Category: edge #[test] fn test_bool_true() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(true).unwrap(); assert_eq!(listener.try_listen(), Some(true)); } /// Test: Boolean: bool false /// /// Verifies: Handles boolean false value /// Category: edge #[test] fn test_bool_false() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(false).unwrap(); assert_eq!(listener.try_listen(), Some(false)); } /// Test: Edge case: Nested Options /// /// Verifies: Handles edge case: nested options /// Category: edge #[test] fn test_nested_options() { type NestedOption = Option>>; let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); announcer.announce(Some(Some(Some(42)))).unwrap(); assert_eq!(listener.try_listen(), Some(Some(Some(Some(42))))); } /// Test: Edge case: Nested Results /// /// Verifies: Handles edge case: nested results /// Category: edge #[test] fn test_nested_results() { type NestedResult = Result, Vec>; let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); announcer.announce(Ok(Ok(42))).unwrap(); assert_eq!(listener.try_listen(), Some(Ok(Ok(42)))); } /// Test: Edge case: Empty collections /// /// Verifies: Handles edge case: empty collections /// Category: edge #[test] fn test_empty_hashmap() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(HashMap::new()).unwrap(); assert_eq!(listener.try_listen(), Some(HashMap::new())); } /// Test: Empty collection: empty btreemap /// /// Verifies: Handles empty btreemap correctly /// Category: edge #[test] fn test_empty_btreemap() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); announcer.announce(BTreeMap::new()).unwrap(); assert_eq!(listener.try_listen(), Some(BTreeMap::new())); } /// Test: Edge case: Single element collections /// /// Verifies: Handles edge case: single element collections /// Category: edge #[test] fn test_single_element_vec() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(vec![42]).unwrap(); assert_eq!(listener.try_listen(), Some(vec![42])); } /// Test: Collection boundary: single element collections /// /// Verifies: Handles collections with exactly one element /// Category: edge #[test] fn test_single_element_hashset() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mut set = HashSet::new(); set.insert("only"); announcer.announce(set.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(set)); } /// Test: Edge case: Reference counting edge cases /// /// Verifies: Handles edge case: reference counting edge cases /// Category: edge #[test] fn test_arc_refcount_after_announce() { let (announcer, announcement) = Announcement::new(); let data = Arc::new(42); let initial_count = Arc::strong_count(&data); let l1 = announcement.listener(); let l2 = announcement.listener(); announcer.announce(data.clone()).unwrap(); let r1 = l1.try_listen().unwrap(); let _r2 = l2.try_listen().unwrap(); // Should be: original + internal + r1 + r2 assert_eq!(Arc::strong_count(&r1), initial_count + 3); } /// Test: Edge case: Path-like strings /// /// Verifies: Handles edge case: path-like strings /// Category: edge #[test] fn test_path_strings() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let path = "/usr/local/bin/../../lib".to_string(); announcer.announce(path.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(path)); } /// Test: Edge case: SQL injection attempt strings /// /// Verifies: Handles edge case: sql injection attempt strings /// Category: edge #[test] fn test_sql_injection_string() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let sql = "'; DROP TABLE users; --".to_string(); announcer.announce(sql.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(sql)); } /// Test: Edge case: Listener cloned multiple times /// /// Verifies: Handles edge case: listener cloned multiple times /// Category: edge #[test] fn test_listener_clone_chain() { let (announcer, announcement) = Announcement::new(); let l1 = announcement.listener(); let l2 = l1.clone(); let l3 = l2.clone(); let l4 = l3.clone(); announcer.announce(42).unwrap(); assert_eq!(l1.try_listen(), Some(42)); assert_eq!(l2.try_listen(), Some(42)); assert_eq!(l3.try_listen(), Some(42)); assert_eq!(l4.try_listen(), Some(42)); } /// Test: Edge case: Announcement cloned multiple times /// /// Verifies: Handles edge case: announcement cloned multiple times /// Category: edge #[test] fn test_announcement_clone_chain() { let (announcer, announcement) = Announcement::new(); let a2 = announcement.clone(); let a3 = a2.clone(); let a4 = a3.clone(); let l1 = announcement.listener(); let l2 = a2.listener(); let l3 = a3.listener(); let l4 = a4.listener(); announcer.announce(42).unwrap(); assert_eq!(l1.try_listen(), Some(42)); assert_eq!(l2.try_listen(), Some(42)); assert_eq!(l3.try_listen(), Some(42)); assert_eq!(l4.try_listen(), Some(42)); } /// Test: Edge case: Mixed listener creation timing /// /// Verifies: Handles edge case: mixed listener creation timing /// Category: edge #[test] fn test_mixed_timing_listeners() { let (announcer, announcement) = Announcement::new(); let before1 = announcement.listener(); let before2 = announcement.listener(); announcer.announce(42).unwrap(); let after1 = announcement.listener(); let after2 = announcement.listener(); assert_eq!(before1.try_listen(), Some(42)); assert_eq!(before2.try_listen(), Some(42)); assert_eq!(after1.try_listen(), Some(42)); assert_eq!(after2.try_listen(), Some(42)); } /// Test: Edge case: Thread-local storage interaction /// /// Verifies: Handles edge case: thread-local storage interaction /// Category: edge #[test] fn test_thread_local_interaction() { thread_local! { static COUNTER: std::cell::Cell = const { std::cell::Cell::new(0) }; } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); COUNTER.with(|c| c.set(100)); announcer.announce(42).unwrap(); assert_eq!(listener.try_listen(), Some(42)); assert_eq!(COUNTER.with(|c| c.get()), 100); } /// Test: Edge case: Panic safety - announcer panics before announce /// /// Verifies: Handles edge case: panic safety - announcer panics before announce /// Category: edge #[test] fn test_panic_before_announce() { let result = std::panic::catch_unwind(|| { let (_announcer, announcement) = Announcement::::new(); let _listener = announcement.listener(); panic!("Intentional panic"); #[allow(unreachable_code)] _announcer.announce(42).unwrap(); }); assert!(result.is_err()); } /// Test: Edge case: Maximum listeners on single announcement /// /// Verifies: Handles edge case: maximum listeners on single announcement /// Category: edge #[test] fn test_max_listeners_single_announcement() { let (announcer, announcement) = Announcement::new(); let mut listeners = Vec::new(); for _ in 0..10000 { listeners.push(announcement.listener()); } announcer.announce(42).unwrap(); // Sample check assert_eq!(listeners[0].try_listen(), Some(42)); assert_eq!(listeners[5000].try_listen(), Some(42)); assert_eq!(listeners[9999].try_listen(), Some(42)); } /// Test: Edge case: Alternating operations /// /// Verifies: Handles edge case: alternating operations /// Category: edge #[test] fn test_alternating_operations() { let (announcer, announcement) = Announcement::new(); let _l1 = announcement.listener(); assert!(!announcement.is_announced()); let _l2 = announcement.listener(); assert!(!announcement.is_announced()); let _l3 = announcement.listener(); assert!(!announcement.is_announced()); announcer.announce(42).unwrap(); assert!(announcement.is_announced()); let l4 = announcement.listener(); assert!(announcement.is_announced()); assert_eq!(l4.try_listen(), Some(42)); } /// Test: Edge case: Error type validation /// /// Verifies: Handles edge case: error type validation /// Category: edge #[test] fn test_error_types() { let err = AnnounceError::AlreadyAnnounced(42); assert_eq!(format!("{}", err), "a value has already been announced"); assert_eq!(format!("{:?}", err), "AlreadyAnnounced(42)"); } /// Test: Edge case: Boundary timing test /// /// Verifies: Handles edge case: boundary timing test /// Category: edge #[test] fn test_announce_exactly_with_try_listen() { for _ in 0..100 { let (announcer, announcement) = Announcement::new(); let announcement2 = announcement.clone(); let handle = thread::spawn(move || announcement2.listener().try_listen()); // Try to announce at nearly the same time announcer.announce(42).unwrap(); let result = handle.join().unwrap(); // Could be Some or None depending on exact timing assert!(result.is_none() || result == Some(42)); } } /// Test: Edge case: String with null bytes /// /// Verifies: Handles edge case: string with null bytes /// Category: edge #[test] fn test_string_with_nulls() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let s = "hello\0world\0test".to_string(); announcer.announce(s.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(s)); } /// Test: Edge case: Maximum tuple size /// /// Verifies: Handles edge case: maximum tuple size /// Category: edge #[test] fn test_12_tuple() { type BigTuple = (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32); let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); let tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); announcer.announce(tuple).unwrap(); assert_eq!(listener.try_listen(), Some(tuple)); } /// Test: Edge case: Negative array indices simulation /// /// Verifies: Handles edge case: negative array indices simulation /// Category: edge #[test] fn test_vec_with_negative_pattern() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); // Simulate negative indexing pattern let vec = vec![-1, -2, -3, 0, 1, 2, 3]; announcer.announce(vec.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(vec)); } /// Test: Edge case: Floating point special values /// /// Verifies: Handles edge case: floating point special values /// Category: edge #[test] fn test_float_special_values() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); let specials = vec![ 0.0, -0.0, f64::MIN_POSITIVE, f64::MAX, f64::MIN, f64::EPSILON, ]; announcer.announce(specials.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(specials)); } /// Test: Edge case: UTF-8 boundary test /// /// Verifies: Handles edge case: utf-8 boundary test /// Category: edge #[test] fn test_utf8_boundaries() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); // Various UTF-8 sequences let s = "A೻ಇ👍🏿Z".to_string(); announcer.announce(s.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(s)); } /// Test: Edge case: Lifetime boundary with static /// /// Verifies: Handles edge case: lifetime boundary with static /// Category: edge #[test] fn test_static_str() { let (announcer, announcement) = Announcement::<&'static str>::new(); let listener = announcement.listener(); announcer.announce("static string").unwrap(); assert_eq!(listener.try_listen(), Some("static string")); } /// Test: Edge case: Very fast repeated checks /// /// Verifies: Handles edge case: very fast repeated checks /// Category: edge #[test] fn test_spin_wait_pattern() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let announcement_clone = announcement.clone(); thread::spawn(move || { thread::sleep(Duration::from_millis(1)); announcer.announce(42).unwrap(); }); // Spin wait while listener.try_listen().is_none() { std::hint::spin_loop(); } assert_eq!(listener.try_listen(), Some(42)); assert!(announcement_clone.is_announced()); } /// Test: Edge case: Memory ordering stress /// /// Verifies: Handles edge case: memory ordering stress /// Category: edge #[test] fn test_memory_ordering_stress() { use std::sync::atomic::{AtomicBool, Ordering}; let (announcer, announcement) = Announcement::new(); let flag = Arc::new(AtomicBool::new(false)); let listener = announcement.listener(); let flag_clone = flag.clone(); thread::spawn(move || { flag_clone.store(true, Ordering::Release); announcer.announce(42).unwrap(); }); while !flag.load(Ordering::Acquire) { thread::yield_now(); } // Flag is set, announcement should be visible soon thread::sleep(Duration::from_millis(1)); assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Drop order testing /// /// Verifies: Handles edge case: drop order testing /// Category: edge #[test] fn test_drop_order() { use std::sync::atomic::{AtomicUsize, Ordering}; static DROP_ORDER: AtomicUsize = AtomicUsize::new(0); #[derive(Clone, Debug)] struct DropOrderTest(usize); impl Drop for DropOrderTest { fn drop(&mut self) { DROP_ORDER.fetch_add(self.0, Ordering::SeqCst); } } DROP_ORDER.store(0, Ordering::SeqCst); { let (announcer, announcement) = Announcement::new(); let _listener = announcement.listener(); announcer.announce(DropOrderTest(1)).unwrap(); } assert!(DROP_ORDER.load(Ordering::SeqCst) > 0); } /// Test: Edge case: Const array patterns /// /// Verifies: Handles edge case: const array patterns /// Category: edge #[test] fn test_const_array() { const ARRAY: [i32; 5] = [1, 2, 3, 4, 5]; let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(ARRAY).unwrap(); assert_eq!(listener.try_listen(), Some(ARRAY)); } /// Test: Edge case: Mixed collection types /// /// Verifies: Handles edge case: mixed collection types /// Category: edge #[test] fn test_vec_of_hashmaps() { let (announcer, announcement) = Announcement::>>::new(); let listener = announcement.listener(); let mut map1 = HashMap::new(); map1.insert("a".to_string(), 1); let mut map2 = HashMap::new(); map2.insert("b".to_string(), 2); let vec = vec![map1, map2]; announcer.announce(vec.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(vec)); } /// Test: Edge case: Hashmap with complex values /// /// Verifies: Handles edge case: hashmap with complex values /// Category: edge #[test] fn test_hashmap_complex_values() { let (announcer, announcement) = Announcement::>>>::new(); let listener = announcement.listener(); let mut map = HashMap::new(); map.insert("key1".to_string(), vec![Some(1), None, Some(2)]); map.insert("key2".to_string(), vec![]); announcer.announce(map.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(map)); } /// Test: Edge case: Maximum safe integer boundaries /// /// Verifies: Handles edge case: maximum safe integer boundaries /// Category: edge #[test] fn test_safe_integer_boundaries() { // JavaScript MAX_SAFE_INTEGER equivalent const MAX_SAFE: i64 = 9_007_199_254_740_991; let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(MAX_SAFE).unwrap(); assert_eq!(listener.try_listen(), Some(MAX_SAFE)); } /// Test: Edge case: Bitwise patterns /// /// Verifies: Handles edge case: bitwise patterns /// Category: edge #[test] fn test_bitwise_patterns() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let pattern: u64 = 0xDEADBEEF_CAFEBABE; announcer.announce(pattern).unwrap(); assert_eq!(listener.try_listen(), Some(pattern)); } /// Test: Edge case: String escaping patterns /// /// Verifies: Handles edge case: string escaping patterns /// Category: edge #[test] fn test_string_escaping() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let s = "\"Hello\"\n\r\t\\World\\".to_string(); announcer.announce(s.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(s)); } /// Test: Edge case: Recursive enum /// /// Verifies: Handles edge case: recursive enum /// Category: edge #[test] fn test_recursive_enum() { #[derive(Clone, Debug, PartialEq)] enum Tree { Leaf(i32), Node(Box, Box), } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let tree = Tree::Node( Box::new(Tree::Leaf(1)), Box::new(Tree::Node(Box::new(Tree::Leaf(2)), Box::new(Tree::Leaf(3)))), ); announcer.announce(tree.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(tree)); } /// Test: Edge case: Type with lifetime parameter via Arc /// /// Verifies: Handles edge case: type with lifetime parameter via arc /// Category: edge #[test] fn test_type_with_lifetime() { #[derive(Clone, Debug)] struct WithData { text: String, number: i32, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let data = Arc::new(WithData { text: "test".to_string(), number: 42, }); announcer.announce(data.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.text, "test"); assert_eq!(received.number, 42); } /// Test: Edge case: Mixed sync primitives /// /// Verifies: Handles edge case: mixed sync primitives /// Category: edge #[test] fn test_mixed_sync_primitives() { use std::sync::RwLock; #[derive(Clone, Debug)] struct MixedSync { mutex_data: Arc>, rwlock_data: Arc>, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mixed = MixedSync { mutex_data: Arc::new(Mutex::new(42)), rwlock_data: Arc::new(RwLock::new("test".to_string())), }; announcer.announce(mixed.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(*received.mutex_data.lock().unwrap(), 42); assert_eq!(*received.rwlock_data.read().unwrap(), "test"); } /// Test: Edge case: Whitespace strings /// /// Verifies: Handles edge case: whitespace strings /// Category: edge #[test] fn test_whitespace_strings() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let whitespace = " \t\n\r\u{00A0}\u{2003} ".to_string(); announcer.announce(whitespace.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(whitespace)); } /// Test: Edge case: Binary data patterns /// /// Verifies: Handles edge case: binary data patterns /// Category: edge #[test] fn test_binary_patterns() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let binary = vec![0x00, 0xFF, 0xAA, 0x55, 0x0F, 0xF0]; announcer.announce(binary.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(binary)); } /// Test: Edge case: HashMap with collision-prone keys /// /// Verifies: Handles edge case: hashmap with collision-prone keys /// Category: edge #[test] fn test_hashmap_collision_keys() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); let mut map = HashMap::new(); // These might cause collisions in some hash implementations for i in 0..100 { map.insert(i * 65536, format!("value_{}", i)); } announcer.announce(map.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.len(), 100); } /// Test: Edge case: Partial move semantics /// /// Verifies: Handles edge case: partial move semantics /// Category: edge #[test] fn test_partial_struct() { #[derive(Clone, Debug)] struct Partial { owned: String, reference: i32, } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let partial = Partial { owned: "owned data".to_string(), reference: 42, }; announcer.announce(partial.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert_eq!(received.owned, "owned data"); assert_eq!(received.reference, 42); } /// Test: Edge case: Extreme thread contention /// /// Verifies: Handles edge case: extreme thread contention /// Category: edge #[test] fn test_extreme_thread_contention() { let (announcer, announcement) = Announcement::new(); let mut handles = vec![]; // 50 threads all trying to check at once for _ in 0..50 { let ann = announcement.clone(); handles.push(thread::spawn(move || { for _ in 0..1000 { let _ = ann.is_announced(); } })); } thread::sleep(Duration::from_millis(10)); announcer.announce(42).unwrap(); for handle in handles { handle.join().unwrap(); } assert!(announcement.is_announced()); } /// Test: Edge case: Cross-thread announcement verification /// /// Verifies: Handles edge case: cross-thread announcement verification /// Category: edge #[test] fn test_cross_thread_verification() { let (announcer, announcement) = Announcement::new(); let ann1 = announcement.clone(); let ann2 = announcement.clone(); let h1 = thread::spawn(move || ann1.is_announced()); let h2 = thread::spawn(move || { announcer.announce(42).unwrap(); }); h2.join().unwrap(); thread::sleep(Duration::from_millis(1)); let h3 = thread::spawn(move || ann2.is_announced()); let _ = h1.join().unwrap(); // May or may not see it assert!(h3.join().unwrap()); // Must see it } /// Test: Edge case: Zero capacity collections /// /// Verifies: Handles edge case: zero capacity collections /// Category: edge #[test] fn test_zero_capacity_vec() { let (announcer, announcement) = Announcement::>::new(); let listener = announcement.listener(); let vec = Vec::with_capacity(0); announcer.announce(vec.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(vec)); } /// Test: Edge case: Enum with many variants /// /// Verifies: Handles edge case: enum with many variants /// Category: edge #[test] fn test_large_enum() { #[derive(Clone, Debug, PartialEq)] #[allow(dead_code)] enum LargeEnum { V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21(i32), V22(String), V23(Vec), } let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(LargeEnum::V23(vec![1, 2, 3])).unwrap(); assert_eq!(listener.try_listen(), Some(LargeEnum::V23(vec![1, 2, 3]))); } /// Test: Edge case: Thread priority interactions /// /// Verifies: Handles edge case: thread priority interactions /// Category: edge #[test] #[cfg(not(target_os = "macos"))] fn test_thread_yield_pattern() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); thread::spawn(move || { for _ in 0..100 { thread::yield_now(); } announcer.announce(42).unwrap(); }); thread::sleep(Duration::from_millis(50)); assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Poisoned mutex in announced value /// /// Verifies: Handles edge case: poisoned mutex in announced value /// Category: edge #[test] fn test_poisoned_mutex() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let mutex = Arc::new(Mutex::new(42)); // Poison the mutex let mutex_clone = mutex.clone(); let _ = thread::spawn(move || { let _guard = mutex_clone.lock().unwrap(); panic!("Intentional panic to poison mutex"); }) .join(); announcer.announce(mutex.clone()).unwrap(); let received = listener.try_listen().unwrap(); assert!(received.lock().is_err()); // Should be poisoned } /// Test: Edge case: Special filesystem characters in strings /// /// Verifies: Handles edge case: special filesystem characters in strings /// Category: edge #[test] fn test_filesystem_special_chars() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let special = "../../../etc/passwd\0.txt".to_string(); announcer.announce(special.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(special)); } /// Test: Edge case: Integer overflow patterns /// /// Verifies: Handles edge case: integer overflow patterns /// Category: edge #[test] fn test_overflow_patterns() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let values = vec![u32::MAX, u32::MAX - 1, 0, 1, u32::MAX / 2]; announcer.announce(values.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(values)); } /// Test: Edge case: Negative zero float /// /// Verifies: Handles edge case: negative zero float /// Category: edge #[test] fn test_negative_zero() { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); let neg_zero = -0.0_f64; announcer.announce(neg_zero).unwrap(); let received = listener.try_listen().unwrap(); assert!(received.is_sign_negative()); assert_eq!(received, 0.0); } /// Test: Edge case: Complex generic nesting /// /// Verifies: Handles edge case: complex generic nesting /// Category: edge #[test] fn test_complex_generics() { type Complex = HashMap>>>; let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); let mut complex = HashMap::new(); complex.insert( "key".to_string(), vec![Some(Ok(1)), None, Some(Err("error".to_string()))], ); announcer.announce(complex.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(complex)); } /// Test: Edge case: Many small announcements sequentially /// /// Verifies: Handles edge case: many small announcements sequentially /// Category: edge #[test] fn test_sequential_small_announcements() { for i in 0..100 { let (announcer, announcement) = Announcement::new(); let listener = announcement.listener(); announcer.announce(i).unwrap(); assert_eq!(listener.try_listen(), Some(i)); } } /// Test: Edge case: Listener after multiple is_announced checks /// /// Verifies: Handles edge case: listener after multiple is_announced checks /// Category: edge #[test] fn test_listener_after_many_checks() { let (announcer, announcement) = Announcement::new(); for _ in 0..1000 { assert!(!announcement.is_announced()); } let listener = announcement.listener(); announcer.announce(42).unwrap(); for _ in 0..1000 { assert!(announcement.is_announced()); } assert_eq!(listener.try_listen(), Some(42)); } /// Test: Edge case: Type aliases /// /// Verifies: Handles edge case: type aliases /// Category: edge #[test] fn test_type_aliases() { type MyString = String; type MyVec = Vec; let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); let data: MyVec = vec!["a".to_string(), "b".to_string()]; announcer.announce(data.clone()).unwrap(); assert_eq!(listener.try_listen(), Some(data)); } /// Test: Edge case: Final edge case - announcement reuse attempt /// /// Verifies: Handles edge case: final edge case - announcement reuse attempt /// Category: edge #[test] fn test_cannot_reuse_consumed_announcer() { let (announcer, announcement) = Announcement::new(); let _listener = announcement.listener(); // Announcer is consumed here announcer.announce(42).unwrap(); // Cannot use announcer again - it's been consumed // This is enforced at compile time by Rust's ownership system // Create a new one to verify the pattern let (announcer2, announcement2) = Announcement::new(); let listener2 = announcement2.listener(); announcer2.announce(99).unwrap(); assert_eq!(listener2.try_listen(), Some(99)); } /// Test: Edge case: Extreme rapid fire operations /// /// Verifies: Handles edge case: extreme rapid fire operations /// Category: edge #[test] fn test_rapid_fire_all_operations() { let (announcer, announcement) = Announcement::new(); let ann1 = announcement.clone(); let ann2 = announcement.clone(); let ann3 = announcement.clone(); let h1 = thread::spawn(move || { for _ in 0..10000 { let _ = ann1.listener(); } }); let h2 = thread::spawn(move || { for _ in 0..10000 { let _ = ann2.is_announced(); } }); let h3 = thread::spawn(move || { for _ in 0..10000 { let l = ann3.listener(); let _ = l.try_listen(); } }); thread::sleep(Duration::from_millis(10)); announcer.announce(42).unwrap(); h1.join().unwrap(); h2.join().unwrap(); h3.join().unwrap(); } // Additional edge cases for zero-listener scenarios /// Test: Edge case: Edge case - announce to 0 listeners with ~0ns overhead /// /// Verifies: Handles edge case: edge case - announce to 0 listeners with ~0ns overhead /// Category: edge #[test] fn test_announce_zero_listeners_minimal_overhead() { use std::time::Instant; // Warm up for _ in 0..100 { let (announcer, _) = Announcement::::new(); announcer.announce(42).unwrap(); } // Measure single announcement to no listeners let start = Instant::now(); let (announcer, _announcement) = Announcement::::new(); announcer.announce(42).unwrap(); let duration = start.elapsed(); // Should be extremely fast (nanoseconds) assert!( duration.as_nanos() < 10_000, "Single announcement to 0 listeners should have near-zero overhead, was {:?}", duration ); } /// Test: Edge case: Stress test - alternating announce/no-listeners pattern /// /// Verifies: Handles edge case: stress test - alternating announce/no-listeners pattern /// Category: edge #[test] fn test_edge_case_alternating_listener_pattern() { for i in 0..1000 { let (announcer, announcement) = Announcement::::new(); if i % 2 == 0 { // Even: create listeners then drop them before announce let listeners: Vec<_> = (0..10).map(|_| announcement.listener()).collect(); drop(listeners); } // Odd: no listeners at all announcer.announce(i).unwrap(); // Verify late listener still works if i % 3 == 0 { let late_listener = announcement.listener(); assert_eq!(late_listener.try_listen(), Some(i)); } } }