336 lines
9.8 KiB
Rust
336 lines
9.8 KiB
Rust
//! 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<i32>> {
|
|
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<i32, ListenError> {
|
|
Err(ListenError::Timeout)
|
|
}
|
|
|
|
/// Test: Trait test: returns closed
|
|
///
|
|
/// Verifies: Verifies returns closed
|
|
/// Category: trait
|
|
fn returns_closed() -> Result<i32, ListenError> {
|
|
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::<i32>::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::<i32>::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);
|
|
}
|