2123 lines
59 KiB
Rust
2123 lines
59 KiB
Rust
//! Comprehensive type testing for the announcement crate.
|
|
//! Tests with 100+ different types to ensure universal compatibility.
|
|
|
|
use announcement::Announcement;
|
|
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
|
|
use std::ffi::OsString;
|
|
use std::marker::PhantomData;
|
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
|
use std::num::{NonZeroI32, NonZeroU64, NonZeroU8};
|
|
use std::path::PathBuf;
|
|
use std::sync::{Arc, Mutex, RwLock};
|
|
use std::time::Duration;
|
|
|
|
// === PRIMITIVE TYPES (15 tests) ===
|
|
|
|
/// Test: u8 type compatibility
|
|
///
|
|
/// Verifies: Unsigned 8-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_u8() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(255u8).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(255u8));
|
|
}
|
|
|
|
/// Test: i8 type compatibility
|
|
///
|
|
/// Verifies: Signed 8-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_i8() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(-128i8).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(-128i8));
|
|
}
|
|
|
|
/// Test: u16 type compatibility
|
|
///
|
|
/// Verifies: Unsigned 16-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_u16() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(65535u16).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(65535u16));
|
|
}
|
|
|
|
/// Test: i16 type compatibility
|
|
///
|
|
/// Verifies: Signed 16-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_i16() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(-32768i16).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(-32768i16));
|
|
}
|
|
|
|
/// Test: u32 type compatibility
|
|
///
|
|
/// Verifies: Unsigned 32-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_u32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(4294967295u32).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(4294967295u32));
|
|
}
|
|
|
|
/// Test: i32 type compatibility
|
|
///
|
|
/// Verifies: Signed 32-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_i32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(-2147483648i32).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(-2147483648i32));
|
|
}
|
|
|
|
/// Test: u64 type compatibility
|
|
///
|
|
/// Verifies: Unsigned 64-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_u64() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(18446744073709551615u64).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(18446744073709551615u64));
|
|
}
|
|
|
|
/// Test: i64 type compatibility
|
|
///
|
|
/// Verifies: Signed 64-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_i64() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(-9223372036854775808i64).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(-9223372036854775808i64));
|
|
}
|
|
|
|
/// Test: u128 type compatibility
|
|
///
|
|
/// Verifies: Unsigned 128-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_u128() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(u128::MAX).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(u128::MAX));
|
|
}
|
|
|
|
/// Test: i128 type compatibility
|
|
///
|
|
/// Verifies: Signed 128-bit integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_i128() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(i128::MIN).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(i128::MIN));
|
|
}
|
|
|
|
/// Test: usize type compatibility
|
|
///
|
|
/// Verifies: Pointer-sized unsigned integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_usize() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(usize::MAX).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(usize::MAX));
|
|
}
|
|
|
|
/// Test: isize type compatibility
|
|
///
|
|
/// Verifies: Pointer-sized signed integers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_isize() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(isize::MIN).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(isize::MIN));
|
|
}
|
|
|
|
/// Test: f32 type compatibility
|
|
///
|
|
/// Verifies: 32-bit floating point numbers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_f32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(std::f32::consts::PI).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(std::f32::consts::PI));
|
|
}
|
|
|
|
/// Test: f64 type compatibility
|
|
///
|
|
/// Verifies: 64-bit floating point numbers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_f64() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(std::f64::consts::E).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(std::f64::consts::E));
|
|
}
|
|
|
|
/// Test: bool type compatibility
|
|
///
|
|
/// Verifies: Boolean values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_bool() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(true).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(true));
|
|
}
|
|
|
|
/// Test: char type compatibility
|
|
///
|
|
/// Verifies: Unicode characters work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_char() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce('🦀').unwrap();
|
|
assert_eq!(listener.try_listen(), Some('🦀'));
|
|
}
|
|
|
|
// === UNIT AND NEVER TYPES (2 tests) ===
|
|
|
|
/// Test: Unit type () compatibility
|
|
///
|
|
/// Verifies: Zero-sized unit type works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_unit_type() {
|
|
let (announcer, announcement) = Announcement::<()>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(()));
|
|
}
|
|
|
|
// === TUPLES (10 tests) ===
|
|
|
|
/// Test: 2-element tuple compatibility
|
|
///
|
|
/// Verifies: Pairs of values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_2() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce((42, "hello")).unwrap();
|
|
assert_eq!(listener.try_listen(), Some((42, "hello")));
|
|
}
|
|
|
|
/// Test: 3-element tuple compatibility
|
|
///
|
|
/// Verifies: Triple values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_3() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce((1, 2.5, true)).unwrap();
|
|
assert_eq!(listener.try_listen(), Some((1, 2.5, true)));
|
|
}
|
|
|
|
/// Test: 4-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 4 different integer types work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_4() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (1u8, 2u16, 3u32, 4u64);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 5-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 5 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_5() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (1, 2, 3, 4, 5);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 6-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 6 char elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_6() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = ('a', 'b', 'c', 'd', 'e', 'f');
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 7-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 7 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_7() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (1, 2, 3, 4, 5, 6, 7);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 8-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 8 f64 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_8() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 9-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 9 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_9() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 10-element tuple compatibility
|
|
///
|
|
/// Verifies: Tuples with 10 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_10() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
/// Test: 12-element tuple compatibility
|
|
///
|
|
/// Verifies: Large tuples with 12 elements work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_12() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
|
|
announcer.announce(tuple).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tuple));
|
|
}
|
|
|
|
// === ARRAYS (15 tests) ===
|
|
|
|
/// Test: Empty array [T; 0] compatibility
|
|
///
|
|
/// Verifies: Zero-length arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_0() {
|
|
let (announcer, announcement) = Announcement::<[i32; 0]>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce([]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some([]));
|
|
}
|
|
|
|
/// Test: Single-element array compatibility
|
|
///
|
|
/// Verifies: Arrays with 1 element work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_1() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce([42]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some([42]));
|
|
}
|
|
|
|
/// Test: 2-element array compatibility
|
|
///
|
|
/// Verifies: Small arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_2() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce([1, 2]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some([1, 2]));
|
|
}
|
|
|
|
/// Test: 4-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 4 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_4() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce([1, 2, 3, 4]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some([1, 2, 3, 4]));
|
|
}
|
|
|
|
/// Test: 8-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 8 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_8() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0u8; 8];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 16-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 16 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_16() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [42i32; 16];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 32-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 32 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0u64; 32];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 64-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 64 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_64() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [1u8; 64];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 128-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 128 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_128() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0u8; 128];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 256-element array compatibility
|
|
///
|
|
/// Verifies: Medium arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_256() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [255u8; 256];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 512-element array compatibility
|
|
///
|
|
/// Verifies: Arrays of size 512 work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_512() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0i16; 512];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 1024-element array compatibility
|
|
///
|
|
/// Verifies: 1KB arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_1024() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [42u8; 1024];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 4096-element array compatibility
|
|
///
|
|
/// Verifies: 4KB arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_4096() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0u8; 4096];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 8192-element array compatibility
|
|
///
|
|
/// Verifies: 8KB arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_8192() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [1u8; 8192];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
/// Test: 65536-element array compatibility
|
|
///
|
|
/// Verifies: Large 64KB arrays work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_array_65536() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let array = [0u8; 65536];
|
|
announcer.announce(array).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(array));
|
|
}
|
|
|
|
// === STRING TYPES (5 tests) ===
|
|
|
|
/// Test: Empty string compatibility
|
|
///
|
|
/// Verifies: Empty String values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_string_empty() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(String::new()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(String::new()));
|
|
}
|
|
|
|
/// Test: Short string compatibility
|
|
///
|
|
/// Verifies: Small String values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_string_short() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce("Hi".to_string()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some("Hi".to_string()));
|
|
}
|
|
|
|
/// Test: Medium-length string compatibility
|
|
///
|
|
/// Verifies: Regular-sized strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_string_medium() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let s = "The quick brown fox jumps over the lazy dog".to_string();
|
|
announcer.announce(s.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(s));
|
|
}
|
|
|
|
/// Test: Long string (100K chars) compatibility
|
|
///
|
|
/// Verifies: Large strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_string_long() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let s = "x".repeat(100_000);
|
|
announcer.announce(s.clone()).unwrap();
|
|
assert_eq!(listener.try_listen().unwrap().len(), 100_000);
|
|
}
|
|
|
|
/// Test: Unicode string compatibility
|
|
///
|
|
/// Verifies: Multi-language Unicode strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_string_unicode() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let s = "Hello 世界 🌍 مرحبا мир".to_string();
|
|
announcer.announce(s.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(s));
|
|
}
|
|
|
|
// === VECTOR TYPES (5 tests) ===
|
|
|
|
/// Test: Empty vector compatibility
|
|
///
|
|
/// Verifies: Empty Vec values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_empty() {
|
|
let (announcer, announcement) = Announcement::<Vec<i32>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(vec![]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(vec![]));
|
|
}
|
|
|
|
/// Test: Small vector compatibility
|
|
///
|
|
/// Verifies: Small Vec with few elements works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_small() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(vec![1, 2, 3]).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(vec![1, 2, 3]));
|
|
}
|
|
|
|
/// Test: Medium vector compatibility
|
|
///
|
|
/// Verifies: Vec with 1000 elements works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_medium() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let v: Vec<i32> = (0..1000).collect();
|
|
announcer.announce(v.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(v));
|
|
}
|
|
|
|
/// Test: Large vector (1M elements) compatibility
|
|
///
|
|
/// Verifies: Large Vec handles correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_large() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let v = vec![42u8; 1_000_000];
|
|
announcer.announce(v.clone()).unwrap();
|
|
assert_eq!(listener.try_listen().unwrap().len(), 1_000_000);
|
|
}
|
|
|
|
/// Test: Nested vector compatibility
|
|
///
|
|
/// Verifies: Vec<Vec<T>> works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_nested() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let v = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
|
|
announcer.announce(v.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(v));
|
|
}
|
|
|
|
// === HASHMAP TYPES (5 tests) ===
|
|
|
|
/// Test: Empty HashMap compatibility
|
|
///
|
|
/// Verifies: Empty HashMap works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_empty() {
|
|
let (announcer, announcement) = Announcement::<HashMap<String, i32>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(HashMap::new()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(HashMap::new()));
|
|
}
|
|
|
|
/// Test: HashMap<String, i32> compatibility
|
|
///
|
|
/// Verifies: String-to-int maps work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_string_int() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = HashMap::new();
|
|
map.insert("one".to_string(), 1);
|
|
map.insert("two".to_string(), 2);
|
|
announcer.announce(map.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(map));
|
|
}
|
|
|
|
/// Test: HashMap<i32, Vec> compatibility
|
|
///
|
|
/// Verifies: Maps with Vec values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_int_vec() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = HashMap::new();
|
|
map.insert(1, vec![1, 2, 3]);
|
|
map.insert(2, vec![4, 5, 6]);
|
|
announcer.announce(map.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(map));
|
|
}
|
|
|
|
/// Test: Large HashMap (10K entries) compatibility
|
|
///
|
|
/// Verifies: Large HashMaps work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_large() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = HashMap::new();
|
|
for i in 0..10000 {
|
|
map.insert(i, i * 2);
|
|
}
|
|
announcer.announce(map.clone()).unwrap();
|
|
assert_eq!(listener.try_listen().unwrap().len(), 10000);
|
|
}
|
|
|
|
/// Test: Nested HashMap compatibility
|
|
///
|
|
/// Verifies: HashMap<K, HashMap<K2, V>> works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_nested() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut outer = HashMap::new();
|
|
let mut inner = HashMap::new();
|
|
inner.insert("nested".to_string(), 42);
|
|
outer.insert("key".to_string(), inner);
|
|
announcer.announce(outer.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(outer));
|
|
}
|
|
|
|
// === BTREEMAP TYPES (3 tests) ===
|
|
|
|
/// Test: Empty BTreeMap compatibility
|
|
///
|
|
/// Verifies: Empty BTreeMap works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_btreemap_empty() {
|
|
let (announcer, announcement) = Announcement::<BTreeMap<i32, String>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(BTreeMap::new()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(BTreeMap::new()));
|
|
}
|
|
|
|
/// Test: BTreeMap ordering compatibility
|
|
///
|
|
/// Verifies: Ordered maps maintain sort order
|
|
/// Category: type
|
|
#[test]
|
|
fn test_btreemap_ordered() {
|
|
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();
|
|
assert_eq!(listener.try_listen(), Some(map));
|
|
}
|
|
|
|
/// Test: Complex BTreeMap compatibility
|
|
///
|
|
/// Verifies: BTreeMap with 100 entries works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_btreemap_complex() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = BTreeMap::new();
|
|
for i in (0..100).rev() {
|
|
map.insert(i, format!("value_{}", i));
|
|
}
|
|
announcer.announce(map.clone()).unwrap();
|
|
let received = listener.try_listen().unwrap();
|
|
assert_eq!(received.len(), 100);
|
|
}
|
|
|
|
// === HASHSET TYPES (3 tests) ===
|
|
|
|
/// Test: Empty HashSet compatibility
|
|
///
|
|
/// Verifies: Empty HashSet works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashset_empty() {
|
|
let (announcer, announcement) = Announcement::<HashSet<i32>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(HashSet::new()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(HashSet::new()));
|
|
}
|
|
|
|
/// Test: HashSet<i32> compatibility
|
|
///
|
|
/// Verifies: Integer sets work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashset_integers() {
|
|
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();
|
|
assert_eq!(listener.try_listen(), Some(set));
|
|
}
|
|
|
|
/// Test: HashSet<String> compatibility
|
|
///
|
|
/// Verifies: String sets work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashset_strings() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut set = HashSet::new();
|
|
set.insert("apple".to_string());
|
|
set.insert("banana".to_string());
|
|
announcer.announce(set.clone()).unwrap();
|
|
let received = listener.try_listen().unwrap();
|
|
assert_eq!(received.len(), 2);
|
|
}
|
|
|
|
// === BTREESET TYPES (2 tests) ===
|
|
|
|
/// Test: Empty BTreeSet compatibility
|
|
///
|
|
/// Verifies: Empty BTreeSet works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_btreeset_empty() {
|
|
let (announcer, announcement) = Announcement::<BTreeSet<i32>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(BTreeSet::new()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(BTreeSet::new()));
|
|
}
|
|
|
|
/// Test: BTreeSet ordering compatibility
|
|
///
|
|
/// Verifies: Ordered sets maintain sort order
|
|
/// Category: type
|
|
#[test]
|
|
fn test_btreeset_ordered() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut set = BTreeSet::new();
|
|
for i in [5, 2, 8, 1, 9, 3] {
|
|
set.insert(i);
|
|
}
|
|
announcer.announce(set.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(set));
|
|
}
|
|
|
|
// === OPTION TYPES (3 tests) ===
|
|
|
|
/// Test: Option::None compatibility
|
|
///
|
|
/// Verifies: None values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_option_none() {
|
|
let (announcer, announcement) = Announcement::<Option<String>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(None).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(None));
|
|
}
|
|
|
|
/// Test: Option::Some with primitive compatibility
|
|
///
|
|
/// Verifies: Some(T) with primitives works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_option_some_primitive() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Some(42)).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Some(42)));
|
|
}
|
|
|
|
/// Test: Option::Some with complex type compatibility
|
|
///
|
|
/// Verifies: Some(Vec) works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_option_some_complex() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Some(vec![1, 2, 3])).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Some(vec![1, 2, 3])));
|
|
}
|
|
|
|
// === RESULT TYPES (3 tests) ===
|
|
|
|
/// Test: Result::Ok compatibility
|
|
///
|
|
/// Verifies: Ok values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_result_ok() {
|
|
let (announcer, announcement) = Announcement::<Result<i32, String>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Ok(42)).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Ok(42)));
|
|
}
|
|
|
|
/// Test: Result::Err compatibility
|
|
///
|
|
/// Verifies: Err values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_result_err() {
|
|
let (announcer, announcement) = Announcement::<Result<i32, String>>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Err("error".to_string())).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Err("error".to_string())));
|
|
}
|
|
|
|
/// Test: Nested Result compatibility
|
|
///
|
|
/// Verifies: Result<Result<T,E>,E2> works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_result_nested() {
|
|
type NestedResult = Result<Result<i32, String>, bool>;
|
|
let (announcer, announcement) = Announcement::<NestedResult>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Ok(Ok(42))).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Ok(Ok(42))));
|
|
}
|
|
|
|
// === BOX TYPES (3 tests) ===
|
|
|
|
/// Test: Box<primitive> compatibility
|
|
///
|
|
/// Verifies: Boxed primitives work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_box_primitive() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Box::new(42)).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Box::new(42)));
|
|
}
|
|
|
|
/// Test: Box<String> compatibility
|
|
///
|
|
/// Verifies: Boxed strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_box_string() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Box::new("hello".to_string())).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Box::new("hello".to_string())));
|
|
}
|
|
|
|
/// Test: Box<Vec> compatibility
|
|
///
|
|
/// Verifies: Boxed vectors work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_box_vec() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Box::new(vec![1, 2, 3])).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Box::new(vec![1, 2, 3])));
|
|
}
|
|
|
|
// === ARC TYPES (5 tests) ===
|
|
|
|
/// Test: Arc<primitive> compatibility
|
|
///
|
|
/// Verifies: Arc-wrapped primitives work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_primitive() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Arc::new(42)).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap(), 42);
|
|
}
|
|
|
|
/// Test: Arc<String> compatibility
|
|
///
|
|
/// Verifies: Arc-wrapped strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_string() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Arc::new("hello".to_string())).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap(), "hello");
|
|
}
|
|
|
|
/// Test: Arc<Mutex<T>> compatibility
|
|
///
|
|
/// Verifies: Arc-wrapped Mutex works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_mutex() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Arc::new(Mutex::new(42))).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap().lock().unwrap(), 42);
|
|
}
|
|
|
|
/// Test: Arc<RwLock<T>> compatibility
|
|
///
|
|
/// Verifies: Arc-wrapped RwLock works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_rwlock() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer
|
|
.announce(Arc::new(RwLock::new(vec![1, 2, 3])))
|
|
.unwrap();
|
|
assert_eq!(
|
|
*listener.try_listen().unwrap().read().unwrap(),
|
|
vec![1, 2, 3]
|
|
);
|
|
}
|
|
|
|
/// Test: Nested Arc compatibility
|
|
///
|
|
/// Verifies: Arc<Arc<T>> works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_nested() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Arc::new(Arc::new(42))).unwrap();
|
|
assert_eq!(**listener.try_listen().unwrap(), 42);
|
|
}
|
|
|
|
// === CUSTOM STRUCTS (10 tests) ===
|
|
|
|
/// Test: Simple struct compatibility
|
|
///
|
|
/// Verifies: Basic structs with fields work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_simple() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Simple {
|
|
x: i32,
|
|
y: String,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let s = Simple {
|
|
x: 42,
|
|
y: "hello".to_string(),
|
|
};
|
|
announcer.announce(s.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(s));
|
|
}
|
|
|
|
/// Test: Unit struct compatibility
|
|
///
|
|
/// Verifies: Unit structs work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_unit() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Unit;
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Unit).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Unit));
|
|
}
|
|
|
|
/// Test: Tuple struct compatibility
|
|
///
|
|
/// Verifies: Tuple structs work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_tuple() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct TupleStruct(i32, String);
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ts = TupleStruct(42, "hello".to_string());
|
|
announcer.announce(ts.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ts));
|
|
}
|
|
|
|
/// Test: Generic struct compatibility
|
|
///
|
|
/// Verifies: Generic structs work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_generic() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Generic<T> {
|
|
value: T,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let g = Generic {
|
|
value: vec![1, 2, 3],
|
|
};
|
|
announcer.announce(g.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(g));
|
|
}
|
|
|
|
/// Test: Struct with String compatibility
|
|
///
|
|
/// Verifies: Structs with owned strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_lifetime_bounds() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct WithString {
|
|
text: String,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ws = WithString {
|
|
text: "test".to_string(),
|
|
};
|
|
announcer.announce(ws.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ws));
|
|
}
|
|
|
|
/// Test: Nested struct compatibility
|
|
///
|
|
/// Verifies: Structs containing structs work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_nested() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Inner {
|
|
value: i32,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Outer {
|
|
inner: Inner,
|
|
name: String,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let o = Outer {
|
|
inner: Inner { value: 42 },
|
|
name: "test".to_string(),
|
|
};
|
|
announcer.announce(o.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(o));
|
|
}
|
|
|
|
/// Test: Struct with Vec field compatibility
|
|
///
|
|
/// Verifies: Structs containing Vec work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_with_vec() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct WithVec {
|
|
items: Vec<String>,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let wv = WithVec {
|
|
items: vec!["a".to_string(), "b".to_string()],
|
|
};
|
|
announcer.announce(wv.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(wv));
|
|
}
|
|
|
|
/// Test: Struct with HashMap field compatibility
|
|
///
|
|
/// Verifies: Structs containing HashMap work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_with_hashmap() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct WithHashMap {
|
|
data: HashMap<String, i32>,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut data = HashMap::new();
|
|
data.insert("key".to_string(), 42);
|
|
let whm = WithHashMap { data };
|
|
announcer.announce(whm.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(whm));
|
|
}
|
|
|
|
/// Test: Recursive struct via Box compatibility
|
|
///
|
|
/// Verifies: Self-referential structs work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_recursive_via_box() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct Node {
|
|
value: i32,
|
|
next: Option<Box<Node>>,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let n = Node {
|
|
value: 1,
|
|
next: Some(Box::new(Node {
|
|
value: 2,
|
|
next: None,
|
|
})),
|
|
};
|
|
announcer.announce(n.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(n));
|
|
}
|
|
|
|
/// Test: Struct with all primitive types compatibility
|
|
///
|
|
/// Verifies: Structs with all primitives work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_struct_with_all_primitives() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
struct AllPrimitives {
|
|
u8_val: u8,
|
|
i8_val: i8,
|
|
u16_val: u16,
|
|
i16_val: i16,
|
|
u32_val: u32,
|
|
i32_val: i32,
|
|
u64_val: u64,
|
|
i64_val: i64,
|
|
f32_val: f32,
|
|
f64_val: f64,
|
|
bool_val: bool,
|
|
char_val: char,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ap = AllPrimitives {
|
|
u8_val: 255,
|
|
i8_val: -128,
|
|
u16_val: 65535,
|
|
i16_val: -32768,
|
|
u32_val: u32::MAX,
|
|
i32_val: i32::MIN,
|
|
u64_val: u64::MAX,
|
|
i64_val: i64::MIN,
|
|
f32_val: std::f32::consts::PI,
|
|
f64_val: std::f64::consts::E,
|
|
bool_val: true,
|
|
char_val: '💯',
|
|
};
|
|
announcer.announce(ap.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ap));
|
|
}
|
|
|
|
// === ENUMS (10 tests) ===
|
|
|
|
/// Test: Simple enum compatibility
|
|
///
|
|
/// Verifies: Basic enums work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_simple() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum Simple {
|
|
A,
|
|
B,
|
|
C,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Simple::B).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Simple::B));
|
|
}
|
|
|
|
/// Test: Enum with associated data compatibility
|
|
///
|
|
/// Verifies: Enums with tuple/struct data work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_with_data() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum WithData {
|
|
Empty,
|
|
Number(i32),
|
|
Text(String),
|
|
Both(i32, String),
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer
|
|
.announce(WithData::Both(42, "hello".to_string()))
|
|
.unwrap();
|
|
assert_eq!(
|
|
listener.try_listen(),
|
|
Some(WithData::Both(42, "hello".to_string()))
|
|
);
|
|
}
|
|
|
|
/// Test: Enum with struct variants compatibility
|
|
///
|
|
/// Verifies: Enums with named fields work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_struct_variants() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum StructVariants {
|
|
Point { x: f64, y: f64 },
|
|
Color { r: u8, g: u8, b: u8 },
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer
|
|
.announce(StructVariants::Point { x: 1.5, y: 2.5 })
|
|
.unwrap();
|
|
assert_eq!(
|
|
listener.try_listen(),
|
|
Some(StructVariants::Point { x: 1.5, y: 2.5 })
|
|
);
|
|
}
|
|
|
|
/// Test: Generic enum compatibility
|
|
///
|
|
/// Verifies: Generic enums work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_generic() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum Generic<T> {
|
|
Some(T),
|
|
None,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Generic::Some(vec![1, 2, 3])).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Generic::Some(vec![1, 2, 3])));
|
|
}
|
|
|
|
/// Test: Recursive enum compatibility
|
|
///
|
|
/// Verifies: Self-referential enums work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_recursive() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
enum Tree {
|
|
Leaf(i32),
|
|
Branch(Box<Tree>, Box<Tree>),
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let tree = Tree::Branch(Box::new(Tree::Leaf(1)), Box::new(Tree::Leaf(2)));
|
|
announcer.announce(tree.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(tree));
|
|
}
|
|
|
|
/// Test: C-like enum compatibility
|
|
///
|
|
/// Verifies: Enums with explicit discriminants work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_c_like() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[repr(u8)]
|
|
#[allow(dead_code)]
|
|
enum CLike {
|
|
Zero = 0,
|
|
One = 1,
|
|
Two = 2,
|
|
Hundred = 100,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(CLike::Hundred).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(CLike::Hundred));
|
|
}
|
|
|
|
/// Test: Enum with mixed variants compatibility
|
|
///
|
|
/// Verifies: Enums mixing unit/tuple/struct variants work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_mixed_variants() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum Mixed {
|
|
Unit,
|
|
Tuple(i32, i32),
|
|
Struct { name: String, value: i32 },
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer
|
|
.announce(Mixed::Struct {
|
|
name: "test".to_string(),
|
|
value: 42,
|
|
})
|
|
.unwrap();
|
|
assert_eq!(
|
|
listener.try_listen(),
|
|
Some(Mixed::Struct {
|
|
name: "test".to_string(),
|
|
value: 42
|
|
})
|
|
);
|
|
}
|
|
|
|
/// Test: Enum with Vec compatibility
|
|
///
|
|
/// Verifies: Enums containing Vec work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_with_vec() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
enum WithVec {
|
|
List(Vec<i32>),
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(WithVec::List(vec![1, 2, 3])).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(WithVec::List(vec![1, 2, 3])));
|
|
}
|
|
|
|
/// Test: Enum with Option compatibility
|
|
///
|
|
/// Verifies: Enums containing Option work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_with_option() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
enum WithOption {
|
|
Maybe(Option<String>),
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer
|
|
.announce(WithOption::Maybe(Some("yes".to_string())))
|
|
.unwrap();
|
|
assert_eq!(
|
|
listener.try_listen(),
|
|
Some(WithOption::Maybe(Some("yes".to_string())))
|
|
);
|
|
}
|
|
|
|
/// Test: Large enum (20+ variants) compatibility
|
|
///
|
|
/// Verifies: Enums with many variants work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_enum_large() {
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
#[allow(dead_code)]
|
|
enum Large {
|
|
V1,
|
|
V2,
|
|
V3,
|
|
V4,
|
|
V5,
|
|
V6,
|
|
V7,
|
|
V8,
|
|
V9,
|
|
V10,
|
|
V11,
|
|
V12,
|
|
V13,
|
|
V14,
|
|
V15,
|
|
V16,
|
|
V17,
|
|
V18,
|
|
V19,
|
|
V20,
|
|
Data(String),
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(Large::Data("test".to_string())).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(Large::Data("test".to_string())));
|
|
}
|
|
|
|
// === PHANTOMDATA (2 tests) ===
|
|
|
|
/// Test: PhantomData<String> compatibility
|
|
///
|
|
/// Verifies: PhantomData type markers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_phantom_data_string() {
|
|
#[derive(Clone, Debug)]
|
|
struct WithPhantom<T> {
|
|
value: i32,
|
|
_phantom: PhantomData<T>,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let wp: WithPhantom<String> = WithPhantom {
|
|
value: 42,
|
|
_phantom: PhantomData,
|
|
};
|
|
announcer.announce(wp.clone()).unwrap();
|
|
assert_eq!(listener.try_listen().unwrap().value, 42);
|
|
}
|
|
|
|
/// Test: PhantomData with lifetime compatibility
|
|
///
|
|
/// Verifies: PhantomData with lifetimes works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_phantom_data_lifetime() {
|
|
#[derive(Clone, Debug)]
|
|
struct WithLifetime<'a> {
|
|
value: String,
|
|
_phantom: PhantomData<&'a str>,
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let wl = WithLifetime {
|
|
value: "test".to_string(),
|
|
_phantom: PhantomData,
|
|
};
|
|
announcer.announce(wl.clone()).unwrap();
|
|
assert_eq!(listener.try_listen().unwrap().value, "test");
|
|
}
|
|
|
|
// === INTERIOR MUTABILITY (5 tests) ===
|
|
|
|
/// Test: Arc<Mutex<i32>> compatibility
|
|
///
|
|
/// Verifies: Thread-safe mutable i32 works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_mutex_i32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let data = Arc::new(Mutex::new(42));
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap().lock().unwrap(), 42);
|
|
}
|
|
|
|
/// Test: Arc<RwLock<String>> compatibility
|
|
///
|
|
/// Verifies: Thread-safe mutable String works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_rwlock_string() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let data = Arc::new(RwLock::new("hello".to_string()));
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap().read().unwrap(), "hello");
|
|
}
|
|
|
|
/// Test: Arc<Mutex<Vec>> compatibility
|
|
///
|
|
/// Verifies: Thread-safe mutable Vec works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_mutex_vec() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(
|
|
*listener.try_listen().unwrap().lock().unwrap(),
|
|
vec![1, 2, 3]
|
|
);
|
|
}
|
|
|
|
/// Test: Arc<RwLock<HashMap>> compatibility
|
|
///
|
|
/// Verifies: Thread-safe mutable HashMap works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_arc_rwlock_hashmap() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = HashMap::new();
|
|
map.insert("key".to_string(), 42);
|
|
let data = Arc::new(RwLock::new(map.clone()));
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(*listener.try_listen().unwrap().read().unwrap(), map);
|
|
}
|
|
|
|
/// Test: Nested Arc<Mutex> compatibility
|
|
///
|
|
/// Verifies: Nested thread-safe wrappers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_nested_arc_mutex() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let data = Arc::new(Mutex::new(Arc::new(Mutex::new(42))));
|
|
announcer.announce(data.clone()).unwrap();
|
|
let outer = listener.try_listen().unwrap();
|
|
let inner = outer.lock().unwrap();
|
|
assert_eq!(*inner.lock().unwrap(), 42);
|
|
}
|
|
|
|
// === FUNCTION POINTERS (3 tests) ===
|
|
|
|
/// Test: Function pointer (one arg) compatibility
|
|
///
|
|
/// Verifies: Function pointers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_fn_pointer_simple() {
|
|
fn add_one(x: i32) -> i32 {
|
|
x + 1
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::<fn(i32) -> i32>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(add_one).unwrap();
|
|
let f = listener.try_listen().unwrap();
|
|
assert_eq!(f(41), 42);
|
|
}
|
|
|
|
/// Test: Function pointer (no args) compatibility
|
|
///
|
|
/// Verifies: Zero-argument function pointers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_fn_pointer_no_args() {
|
|
fn get_value() -> i32 {
|
|
42
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::<fn() -> i32>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(get_value).unwrap();
|
|
let f = listener.try_listen().unwrap();
|
|
assert_eq!(f(), 42);
|
|
}
|
|
|
|
/// Test: Function pointer (multiple args) compatibility
|
|
///
|
|
/// Verifies: Multi-argument function pointers work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_fn_pointer_multiple_args() {
|
|
fn add(a: i32, b: i32) -> i32 {
|
|
a + b
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::<fn(i32, i32) -> i32>::new();
|
|
let listener = announcement.listener();
|
|
announcer.announce(add).unwrap();
|
|
let f = listener.try_listen().unwrap();
|
|
assert_eq!(f(20, 22), 42);
|
|
}
|
|
|
|
// === TRAIT OBJECTS (3 tests) ===
|
|
|
|
/// Test: Trait object dyn Display compatibility
|
|
///
|
|
/// Verifies: Display trait objects work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_trait_object_display() {
|
|
let (announcer, announcement) = Announcement::<Arc<dyn std::fmt::Display + Send + Sync>>::new();
|
|
let listener = announcement.listener();
|
|
let obj: Arc<dyn std::fmt::Display + Send + Sync> = Arc::new(42);
|
|
let _ = announcer.announce(obj); // Can't use unwrap/expect because dyn Display doesn't implement Debug
|
|
let received = listener.try_listen().unwrap();
|
|
assert_eq!(format!("{}", received), "42");
|
|
}
|
|
|
|
/// Test: Custom trait object compatibility
|
|
///
|
|
/// Verifies: Custom trait objects work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_trait_object_custom() {
|
|
trait MyTrait: Send + Sync {
|
|
fn get_value(&self) -> i32;
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct MyImpl(i32);
|
|
|
|
impl MyTrait for MyImpl {
|
|
fn get_value(&self) -> i32 {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
let (announcer, announcement) = Announcement::<Arc<dyn MyTrait>>::new();
|
|
let listener = announcement.listener();
|
|
let obj: Arc<dyn MyTrait> = Arc::new(MyImpl(42));
|
|
let _ = announcer.announce(obj); // Can't use unwrap/expect because dyn MyTrait doesn't implement Debug
|
|
assert_eq!(listener.try_listen().unwrap().get_value(), 42);
|
|
}
|
|
|
|
/// Test: Trait object dyn Any compatibility
|
|
///
|
|
/// Verifies: Any trait objects with downcasting work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_trait_object_any() {
|
|
use std::any::Any;
|
|
|
|
let (announcer, announcement) = Announcement::<Arc<dyn Any + Send + Sync>>::new();
|
|
let listener = announcement.listener();
|
|
let obj: Arc<dyn Any + Send + Sync> = Arc::new(42i32);
|
|
announcer.announce(obj).unwrap();
|
|
let received = listener.try_listen().unwrap();
|
|
assert_eq!(*received.downcast_ref::<i32>().unwrap(), 42);
|
|
}
|
|
|
|
// === CLOSURES (2 tests) ===
|
|
|
|
/// Test: Closure Fn() compatibility
|
|
///
|
|
/// Verifies: Non-capturing closures work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_closure_fn() {
|
|
let (announcer, announcement) = Announcement::<Arc<dyn Fn() -> i32 + Send + Sync>>::new();
|
|
let listener = announcement.listener();
|
|
let closure: Arc<dyn Fn() -> i32 + Send + Sync> = Arc::new(|| 42);
|
|
let _ = announcer.announce(closure); // Can't use unwrap/expect because dyn Fn doesn't implement Debug
|
|
assert_eq!(listener.try_listen().unwrap()(), 42);
|
|
}
|
|
|
|
/// Test: Closure with capture compatibility
|
|
///
|
|
/// Verifies: Capturing closures work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_closure_with_capture() {
|
|
let (announcer, announcement) = Announcement::<Arc<dyn Fn(i32) -> i32 + Send + Sync>>::new();
|
|
let listener = announcement.listener();
|
|
let captured = 10;
|
|
let closure: Arc<dyn Fn(i32) -> i32 + Send + Sync> = Arc::new(move |x| x + captured);
|
|
let _ = announcer.announce(closure); // Can't use unwrap/expect because dyn Fn doesn't implement Debug
|
|
assert_eq!(listener.try_listen().unwrap()(32), 42);
|
|
}
|
|
|
|
// === OTHER COLLECTION TYPES (5 tests) ===
|
|
|
|
/// Test: VecDeque compatibility
|
|
///
|
|
/// Verifies: Double-ended queues work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vecdeque() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut vd = VecDeque::new();
|
|
vd.push_back(1);
|
|
vd.push_back(2);
|
|
vd.push_front(0);
|
|
announcer.announce(vd.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(vd));
|
|
}
|
|
|
|
/// Test: LinkedList compatibility
|
|
///
|
|
/// Verifies: Linked lists work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_linkedlist() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut ll = LinkedList::new();
|
|
ll.push_back(1);
|
|
ll.push_back(2);
|
|
ll.push_back(3);
|
|
announcer.announce(ll.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ll));
|
|
}
|
|
|
|
/// Test: BinaryHeap compatibility
|
|
///
|
|
/// Verifies: Binary heaps work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_binaryheap() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut heap = BinaryHeap::new();
|
|
heap.push(3);
|
|
heap.push(1);
|
|
heap.push(2);
|
|
announcer.announce(heap.clone()).unwrap();
|
|
let received = listener.try_listen().unwrap();
|
|
assert_eq!(received.len(), 3);
|
|
}
|
|
|
|
// === NONZERO TYPES (3 tests) ===
|
|
|
|
/// Test: NonZeroU8 compatibility
|
|
///
|
|
/// Verifies: Non-zero u8 values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_nonzero_u8() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let nz = NonZeroU8::new(42).unwrap();
|
|
announcer.announce(nz).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(nz));
|
|
}
|
|
|
|
/// Test: NonZeroI32 compatibility
|
|
///
|
|
/// Verifies: Non-zero i32 values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_nonzero_i32() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let nz = NonZeroI32::new(-42).unwrap();
|
|
announcer.announce(nz).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(nz));
|
|
}
|
|
|
|
/// Test: NonZeroU64 compatibility
|
|
///
|
|
/// Verifies: Non-zero u64 values work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_nonzero_u64() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let nz = NonZeroU64::new(u64::MAX).unwrap();
|
|
announcer.announce(nz).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(nz));
|
|
}
|
|
|
|
// === DURATION (2 tests) ===
|
|
|
|
/// Test: Duration compatibility
|
|
///
|
|
/// Verifies: Time durations work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_duration() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let dur = Duration::from_secs(42);
|
|
announcer.announce(dur).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(dur));
|
|
}
|
|
|
|
/// Test: Duration (nanosecond precision) compatibility
|
|
///
|
|
/// Verifies: Precise time durations work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_duration_precise() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let dur = Duration::from_nanos(123456789);
|
|
announcer.announce(dur).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(dur));
|
|
}
|
|
|
|
// === PATH TYPES (2 tests) ===
|
|
|
|
/// Test: PathBuf compatibility
|
|
///
|
|
/// Verifies: Filesystem paths work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_pathbuf() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let path = PathBuf::from("/home/user/file.txt");
|
|
announcer.announce(path.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(path));
|
|
}
|
|
|
|
/// Test: OsString compatibility
|
|
///
|
|
/// Verifies: OS-native strings work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_osstring() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let s = OsString::from("test_string");
|
|
announcer.announce(s.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(s));
|
|
}
|
|
|
|
// === NETWORK TYPES (4 tests) ===
|
|
|
|
/// Test: Ipv4Addr compatibility
|
|
///
|
|
/// Verifies: IPv4 addresses work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_ipv4addr() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ip = Ipv4Addr::new(127, 0, 0, 1);
|
|
announcer.announce(ip).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ip));
|
|
}
|
|
|
|
/// Test: Ipv6Addr compatibility
|
|
///
|
|
/// Verifies: IPv6 addresses work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_ipv6addr() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
|
|
announcer.announce(ip).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ip));
|
|
}
|
|
|
|
/// Test: IpAddr compatibility
|
|
///
|
|
/// Verifies: IP addresses (v4/v6 enum) work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_ipaddr() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
|
|
announcer.announce(ip).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(ip));
|
|
}
|
|
|
|
/// Test: SocketAddr compatibility
|
|
///
|
|
/// Verifies: Socket addresses work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_socketaddr() {
|
|
use std::net::SocketAddrV4;
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080));
|
|
announcer.announce(addr).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(addr));
|
|
}
|
|
|
|
// === RANGE TYPES (3 tests) ===
|
|
|
|
/// Test: Range<T> compatibility
|
|
///
|
|
/// Verifies: Exclusive ranges work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_range() {
|
|
use std::ops::Range;
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let range: Range<i32> = 0..10;
|
|
announcer.announce(range.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(range));
|
|
}
|
|
|
|
/// Test: RangeInclusive<T> compatibility
|
|
///
|
|
/// Verifies: Inclusive ranges work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_range_inclusive() {
|
|
use std::ops::RangeInclusive;
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let range: RangeInclusive<i32> = 0..=10;
|
|
announcer.announce(range.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(range));
|
|
}
|
|
|
|
/// Test: RangeFrom<T> compatibility
|
|
///
|
|
/// Verifies: Unbounded ranges work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_range_from() {
|
|
use std::ops::RangeFrom;
|
|
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let range: RangeFrom<i32> = 5..;
|
|
announcer.announce(range.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(range));
|
|
}
|
|
|
|
// === COMPLEX NESTED TYPES (5 tests) ===
|
|
|
|
/// Test: Vec<Option<T>> compatibility
|
|
///
|
|
/// Verifies: Vectors of options work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_vec_of_options() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let data = vec![Some(1), None, Some(3), None, Some(5)];
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(data));
|
|
}
|
|
|
|
/// Test: HashMap<K, Vec<T>> compatibility
|
|
///
|
|
/// Verifies: Maps of vectors work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_hashmap_of_vecs() {
|
|
let (announcer, announcement) = Announcement::new();
|
|
let listener = announcement.listener();
|
|
let mut map = HashMap::new();
|
|
map.insert("evens".to_string(), vec![2, 4, 6]);
|
|
map.insert("odds".to_string(), vec![1, 3, 5]);
|
|
announcer.announce(map.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(map));
|
|
}
|
|
|
|
/// Test: Option<Result<Vec<T>,E>> compatibility
|
|
///
|
|
/// Verifies: Complex nested types work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_option_result_vec() {
|
|
type Complex = Option<Result<Vec<i32>, String>>;
|
|
|
|
let (announcer, announcement) = Announcement::<Complex>::new();
|
|
let listener = announcement.listener();
|
|
let data = Some(Ok(vec![1, 2, 3]));
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(data));
|
|
}
|
|
|
|
/// Test: Deeply nested types compatibility
|
|
///
|
|
/// Verifies: Complex multi-level nesting works correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_deeply_nested() {
|
|
type DeepNest = Vec<Option<Result<HashMap<String, Vec<i32>>, String>>>;
|
|
|
|
let (announcer, announcement) = Announcement::<DeepNest>::new();
|
|
let listener = announcement.listener();
|
|
|
|
let mut map = HashMap::new();
|
|
map.insert("test".to_string(), vec![1, 2, 3]);
|
|
let data = vec![Some(Ok(map))];
|
|
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(data));
|
|
}
|
|
|
|
/// Test: Tuple of collections compatibility
|
|
///
|
|
/// Verifies: Tuples containing collections work correctly
|
|
/// Category: type
|
|
#[test]
|
|
fn test_tuple_of_collections() {
|
|
type TupleCollections = (Vec<i32>, HashMap<String, String>, HashSet<u8>);
|
|
|
|
let (announcer, announcement) = Announcement::<TupleCollections>::new();
|
|
let listener = announcement.listener();
|
|
|
|
let mut map = HashMap::new();
|
|
map.insert("key".to_string(), "value".to_string());
|
|
|
|
let mut set = HashSet::new();
|
|
set.insert(1);
|
|
set.insert(2);
|
|
|
|
let data = (vec![1, 2, 3], map, set);
|
|
|
|
announcer.announce(data.clone()).unwrap();
|
|
assert_eq!(listener.try_listen(), Some(data));
|
|
}
|