//! Tests for trait implementations (Display, Error, Debug, etc.) //! //! These tests ensure that all trait implementations are properly covered //! by the test suite, particularly for error types. use announcement::{AnnounceError, Announcement, ListenError}; use std::error::Error; // ============================================================================= // AnnounceError Trait Implementation Tests // ============================================================================= /// Test: Trait test: announce error display /// /// Verifies: Verifies announce error display /// Category: trait #[test] fn test_announce_error_display() { let err = AnnounceError::AlreadyAnnounced(42); let display_str = format!("{}", err); assert_eq!(display_str, "a value has already been announced"); } /// Test: Trait test: announce error display string type /// /// Verifies: Verifies announce error display string type /// Category: trait #[test] fn test_announce_error_display_string_type() { let err = AnnounceError::AlreadyAnnounced("test".to_string()); let display_str = format!("{}", err); assert_eq!(display_str, "a value has already been announced"); } /// Test: Trait test: announce error to string /// /// Verifies: Verifies announce error to string /// Category: trait #[test] fn test_announce_error_to_string() { let err = AnnounceError::AlreadyAnnounced(99); assert_eq!(err.to_string(), "a value has already been announced"); } /// Test: Trait test: announce error std error trait /// /// Verifies: Verifies announce error std error trait /// Category: trait #[test] fn test_announce_error_std_error_trait() { let err = AnnounceError::AlreadyAnnounced(42); // Verify it implements std::error::Error by using it as a trait object let _err_ref: &dyn Error = &err; // Verify source() returns None (default implementation) assert!(err.source().is_none()); } /// Test: Trait test: announce error debug /// /// Verifies: Verifies announce error debug /// Category: trait #[test] fn test_announce_error_debug() { let err = AnnounceError::AlreadyAnnounced(42); let debug_str = format!("{:?}", err); assert!(debug_str.contains("AlreadyAnnounced")); assert!(debug_str.contains("42")); } // ============================================================================= // ListenError Trait Implementation Tests // ============================================================================= /// Test: Trait test: listen error timeout display /// /// Verifies: Verifies listen error timeout display /// Category: trait #[test] fn test_listen_error_timeout_display() { let err = ListenError::Timeout; let display_str = format!("{}", err); assert_eq!( display_str, "timeout elapsed while waiting for announcement" ); } /// Test: Trait test: listen error closed display /// /// Verifies: Verifies listen error closed display /// Category: trait #[test] fn test_listen_error_closed_display() { let err = ListenError::Closed; let display_str = format!("{}", err); assert_eq!(display_str, "announcer was dropped without announcing"); } /// Test: Trait test: listen error timeout to string /// /// Verifies: Verifies listen error timeout to string /// Category: trait #[test] fn test_listen_error_timeout_to_string() { let err = ListenError::Timeout; assert_eq!( err.to_string(), "timeout elapsed while waiting for announcement" ); } /// Test: Trait test: listen error closed to string /// /// Verifies: Verifies listen error closed to string /// Category: trait #[test] fn test_listen_error_closed_to_string() { let err = ListenError::Closed; assert_eq!(err.to_string(), "announcer was dropped without announcing"); } /// Test: Trait test: listen error std error trait /// /// Verifies: Verifies listen error std error trait /// Category: trait #[test] fn test_listen_error_std_error_trait() { let err = ListenError::Timeout; // Verify it implements std::error::Error by using it as a trait object let _err_ref: &dyn Error = &err; // Verify source() returns None (default implementation) assert!(err.source().is_none()); } /// Test: Trait test: listen error debug /// /// Verifies: Verifies listen error debug /// Category: trait #[test] fn test_listen_error_debug() { let timeout_err = ListenError::Timeout; let closed_err = ListenError::Closed; let timeout_debug = format!("{:?}", timeout_err); let closed_debug = format!("{:?}", closed_err); assert!(timeout_debug.contains("Timeout")); assert!(closed_debug.contains("Closed")); } // ============================================================================= // Clone and PartialEq Tests for Error Types // ============================================================================= /// Test: Trait test: announce error clone /// /// Verifies: Verifies announce error clone /// Category: trait #[test] fn test_announce_error_clone() { let err1 = AnnounceError::AlreadyAnnounced(42); let err2 = err1.clone(); assert_eq!(err1, err2); } /// Test: Trait test: announce error partial eq /// /// Verifies: Verifies announce error partial eq /// Category: trait #[test] fn test_announce_error_partial_eq() { let err1 = AnnounceError::AlreadyAnnounced(42); let err2 = AnnounceError::AlreadyAnnounced(42); let err3 = AnnounceError::AlreadyAnnounced(99); assert_eq!(err1, err2); assert_ne!(err1, err3); } /// Test: Trait test: listen error clone /// /// Verifies: Verifies listen error clone /// Category: trait #[test] fn test_listen_error_clone() { let err1 = ListenError::Timeout; let err2 = err1; // Copy trait is used here, not Clone assert_eq!(err1, err2); } /// Test: Trait test: listen error partial eq /// /// Verifies: Verifies listen error partial eq /// Category: trait #[test] fn test_listen_error_partial_eq() { let timeout1 = ListenError::Timeout; let timeout2 = ListenError::Timeout; let closed = ListenError::Closed; assert_eq!(timeout1, timeout2); assert_ne!(timeout1, closed); } // ============================================================================= // Error Usage in Result Context Tests // ============================================================================= /// Test: Trait test: announce error in result /// /// Verifies: Verifies announce error in result /// Category: trait #[test] fn test_announce_error_in_result() { /// Test: Trait test: returns error /// /// Verifies: Verifies returns error /// Category: trait fn returns_error() -> Result<(), AnnounceError> { Err(AnnounceError::AlreadyAnnounced(42)) } let result = returns_error(); assert!(result.is_err()); let err = result.unwrap_err(); assert_eq!(format!("{}", err), "a value has already been announced"); } /// Test: Trait test: listen error in result /// /// Verifies: Verifies listen error in result /// Category: trait #[test] fn test_listen_error_in_result() { /// Test: Trait test: returns timeout /// /// Verifies: Verifies returns timeout /// Category: trait fn returns_timeout() -> Result { Err(ListenError::Timeout) } /// Test: Trait test: returns closed /// /// Verifies: Verifies returns closed /// Category: trait fn returns_closed() -> Result { Err(ListenError::Closed) } let timeout_result = returns_timeout(); assert!(timeout_result.is_err()); assert_eq!( format!("{}", timeout_result.unwrap_err()), "timeout elapsed while waiting for announcement" ); let closed_result = returns_closed(); assert!(closed_result.is_err()); assert_eq!( format!("{}", closed_result.unwrap_err()), "announcer was dropped without announcing" ); } // ============================================================================= // Real-World Error Scenario Tests // ============================================================================= /// Test: Trait test: listen error closed from dropped announcer /// /// Verifies: Verifies listen error closed from dropped announcer /// Category: trait #[tokio::test] async fn test_listen_error_closed_from_dropped_announcer() { let (announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); // Drop announcer to trigger Closed error drop(announcer); let result = listener.listen().await; assert!(result.is_err()); let err = result.unwrap_err(); assert_eq!(err, ListenError::Closed); assert_eq!( format!("{}", err), "announcer was dropped without announcing" ); // Verify Error trait methods assert!(err.source().is_none()); } /// Test: Trait test: listen error timeout from timeout blocking /// /// Verifies: Verifies listen error timeout from timeout blocking /// Category: trait #[cfg(feature = "std")] #[test] fn test_listen_error_timeout_from_timeout_blocking() { use std::time::Duration; let (_announcer, announcement) = Announcement::::new(); let listener = announcement.listener(); // Try to listen with a very short timeout (will timeout) let result = listener.listen_timeout_blocking(Duration::from_millis(1)); assert!(result.is_err()); let err = result.unwrap_err(); assert_eq!(err, ListenError::Timeout); assert_eq!( format!("{}", err), "timeout elapsed while waiting for announcement" ); // Verify Error trait methods assert!(err.source().is_none()); } /// Test: Trait test: announce error into inner preserves value /// /// Verifies: Verifies announce error into inner preserves value /// Category: trait #[test] fn test_announce_error_into_inner_preserves_value() { let original_value = vec![1, 2, 3, 4, 5]; let err = AnnounceError::AlreadyAnnounced(original_value.clone()); let recovered_value = err.into_inner(); assert_eq!(recovered_value, original_value); }