diff options
| author | Weicao-CatilGrass <1992414357@qq.com> | 2026-06-09 21:08:20 +0800 |
|---|---|---|
| committer | Weicao-CatilGrass <1992414357@qq.com> | 2026-06-09 22:23:16 +0800 |
| commit | 514929c3b8ee0d4f540be5eb4bc8c1a10e62095d (patch) | |
| tree | 8faeeb71075a695354496af38eb527085bb37f92 /mingling_core/src/any.rs | |
| parent | 92cccd9517e764508dfa0342ae2ea254661d0a8f (diff) | |
Add unit and integration tests for mingling_core
Diffstat (limited to 'mingling_core/src/any.rs')
| -rw-r--r-- | mingling_core/src/any.rs | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs index 46ebced..8ee07f5 100644 --- a/mingling_core/src/any.rs +++ b/mingling_core/src/any.rs @@ -146,3 +146,258 @@ impl<G> From<AnyOutput<G>> for ChainProcess<G> { ChainProcess::Ok((value, NextProcess::Chain)) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::Groupped; + + /// Mock enum for testing AnyOutput + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[allow(dead_code)] + enum MockGroup { + Alpha, + Beta, + Gamma, + } + + impl std::fmt::Display for MockGroup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + MockGroup::Alpha => write!(f, "Alpha"), + MockGroup::Beta => write!(f, "Beta"), + MockGroup::Gamma => write!(f, "Gamma"), + } + } + } + + #[derive(Debug, Clone, PartialEq)] + #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + struct AlphaData { + value: i32, + } + + impl Groupped<MockGroup> for AlphaData { + fn member_id() -> MockGroup { + MockGroup::Alpha + } + } + + #[derive(Debug, Clone, PartialEq)] + #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + struct BetaData { + name: String, + } + + impl Groupped<MockGroup> for BetaData { + fn member_id() -> MockGroup { + MockGroup::Beta + } + } + + #[derive(Debug, Clone, PartialEq)] + #[allow(dead_code)] + #[cfg_attr(feature = "general_renderer", derive(serde::Serialize))] + struct GammaData; + + impl Groupped<MockGroup> for GammaData { + fn member_id() -> MockGroup { + MockGroup::Gamma + } + } + + // AnyOutput::new + + #[test] + fn test_any_output_new_stores_type_id_and_member_id() { + let data = AlphaData { value: 42 }; + let output = AnyOutput::new(data); + + assert_eq!(output.type_id, std::any::TypeId::of::<AlphaData>()); + assert_eq!(output.member_id, MockGroup::Alpha); + } + + // AnyOutput::downcast + + #[test] + fn test_any_output_downcast_success() { + let data = AlphaData { value: 99 }; + let output = AnyOutput::new(data); + + let result: Result<AlphaData, _> = output.downcast::<AlphaData>(); + assert!(result.is_ok()); + assert_eq!(result.unwrap().value, 99); + } + + #[test] + fn test_any_output_downcast_failure() { + let data = AlphaData { value: 10 }; + let output = AnyOutput::new(data); + + let result: Result<BetaData, _> = output.downcast::<BetaData>(); + assert!(result.is_err()); + } + + // AnyOutput::is + + #[test] + fn test_any_output_is_true_for_matching_type() { + let data = AlphaData { value: 7 }; + let output = AnyOutput::new(data); + + assert!(output.is::<AlphaData>()); + } + + #[test] + fn test_any_output_is_false_for_non_matching_type() { + let data = AlphaData { value: 7 }; + let output = AnyOutput::new(data); + + assert!(!output.is::<BetaData>()); + } + + // AnyOutput::route_chain + + #[test] + fn test_route_chain_returns_ok_with_chain_next() { + let data = AlphaData { value: 1 }; + let output = AnyOutput::new(data); + + let result = output.route_chain(); + match result { + ChainProcess::Ok((any, next)) => { + assert_eq!(any.member_id, MockGroup::Alpha); + assert_eq!(next, NextProcess::Chain); + } + _ => panic!("Expected ChainProcess::Ok"), + } + } + + // AnyOutput::route_renderer + + #[test] + fn test_route_renderer_returns_ok_with_renderer_next() { + let data = AlphaData { value: 2 }; + let output = AnyOutput::new(data); + + let result = output.route_renderer(); + match result { + ChainProcess::Ok((any, next)) => { + assert_eq!(any.member_id, MockGroup::Alpha); + assert_eq!(next, NextProcess::Renderer); + } + _ => panic!("Expected ChainProcess::Ok"), + } + } + + // AnyOutput: Deref / DerefMut + + #[test] + fn test_any_output_deref_accesses_inner_any() { + let data = AlphaData { value: 5 }; + let output = AnyOutput::new(data); + + let inner: &dyn std::any::Any = &*output; + assert!(inner.downcast_ref::<AlphaData>().is_some()); + } + + #[test] + fn test_any_output_deref_mut_allows_modification() { + let data = AlphaData { value: 0 }; + let mut output = AnyOutput::new(data); + + let inner: &mut dyn std::any::Any = &mut *output; + if let Some(ref mut v) = inner.downcast_mut::<AlphaData>() { + v.value = 100; + } + + let result: Result<AlphaData, _> = output.downcast::<AlphaData>(); + assert_eq!(result.unwrap().value, 100); + } + + // ChainProcess::From<AnyOutput> + + #[test] + fn test_chain_process_from_any_output() { + let data = AlphaData { value: 3 }; + let output = AnyOutput::new(data); + + let cp: ChainProcess<MockGroup> = output.into(); + match cp { + ChainProcess::Ok((any, next)) => { + assert_eq!(any.member_id, MockGroup::Alpha); + assert_eq!(next, NextProcess::Chain); + } + _ => panic!("Expected ChainProcess::Ok"), + } + } + + // NextProcess::Display + + #[test] + fn test_next_process_display_chain() { + assert_eq!(format!("{}", NextProcess::Chain), "Chain"); + } + + #[test] + fn test_next_process_display_renderer() { + assert_eq!(format!("{}", NextProcess::Renderer), "Renderer"); + } + + // AnyOutput::restore general_renderer feature only + + #[cfg(feature = "general_renderer")] + #[test] + fn test_any_output_restore_success() { + use serde::Serialize; + + #[derive(Debug, Clone, PartialEq, Serialize)] + struct SerData { + x: i32, + } + + impl Groupped<MockGroup> for SerData { + fn member_id() -> MockGroup { + MockGroup::Gamma + } + } + + let data = SerData { x: 42 }; + let output = AnyOutput::new(data); + let restored: Option<SerData> = output.restore::<SerData>(); + assert_eq!(restored, Some(SerData { x: 42 })); + } + + #[cfg(feature = "general_renderer")] + #[test] + fn test_any_output_restore_type_mismatch() { + use serde::Serialize; + + #[derive(Debug, Clone, PartialEq, Serialize)] + struct SerA { + a: i32, + } + + #[derive(Debug, Clone, PartialEq, Serialize)] + struct SerB { + b: String, + } + + impl Groupped<MockGroup> for SerA { + fn member_id() -> MockGroup { + MockGroup::Alpha + } + } + + impl Groupped<MockGroup> for SerB { + fn member_id() -> MockGroup { + MockGroup::Beta + } + } + + let data = SerA { a: 1 }; + let output = AnyOutput::new(data); + let restored: Option<SerB> = output.restore::<SerB>(); + assert_eq!(restored, None); + } +} |
