Skip to main content

orion_error/
testcase.rs

1use crate::{core::DomainReason, ErrorCategory, ErrorIdentityProvider, StructError};
2
3#[allow(dead_code)]
4// 测试专用断言 (无消息)
5pub trait TestAssert {
6    type Output;
7    fn assert(self) -> Self::Output;
8}
9
10#[allow(dead_code)]
11// 测试专用断言 (带消息)
12pub trait TestAssertWithMsg<A> {
13    type Output;
14    fn assert(self, msg: A) -> Self::Output;
15}
16
17impl<T, E> TestAssert for Result<T, E>
18where
19    E: std::fmt::Display,
20{
21    type Output = T;
22
23    fn assert(self) -> T {
24        self.unwrap_or_else(|e| panic!("[TEST ASSERTION FAILED] \n Error details: {e}"))
25    }
26}
27
28impl<T, E> TestAssertWithMsg<&str> for Result<T, E>
29where
30    E: std::fmt::Display,
31{
32    type Output = T;
33
34    fn assert(self, msg: &str) -> T {
35        self.unwrap_or_else(|e| panic!("[TEST ASSERTION FAILED] {msg} \n Error details: {e}"))
36    }
37}
38
39impl<T> TestAssert for Option<T> {
40    type Output = T;
41
42    fn assert(self) -> T {
43        self.unwrap_or_else(|| panic!("[OPTION ASSERTION FAILED] ",))
44    }
45}
46
47pub fn assert_err_code<R>(err: &StructError<R>, code: &str)
48where
49    R: DomainReason + ErrorIdentityProvider,
50{
51    assert_eq!(err.reason().stable_code(), code);
52}
53
54pub fn assert_err_category<R>(err: &StructError<R>, category: ErrorCategory)
55where
56    R: DomainReason + ErrorIdentityProvider,
57{
58    assert_eq!(err.reason().error_category(), category);
59}
60
61pub fn assert_err_identity<R>(err: &StructError<R>, code: &str, category: ErrorCategory)
62where
63    R: DomainReason + ErrorIdentityProvider,
64{
65    assert_err_code(err, code);
66    assert_err_category(err, category);
67}
68
69pub fn assert_err_operation<R>(err: &StructError<R>, operation: &str)
70where
71    R: DomainReason,
72{
73    assert_eq!(err.action_main().as_deref(), Some(operation));
74}
75
76pub fn assert_err_path<R>(err: &StructError<R>, path: &str)
77where
78    R: DomainReason,
79{
80    assert_eq!(err.target_path().as_deref(), Some(path));
81}
82
83#[cfg(test)]
84mod tests {
85    use super::{
86        assert_err_category, assert_err_code, assert_err_identity, assert_err_operation,
87        assert_err_path,
88    };
89    use crate::{ErrorCategory, ErrorWith, StructError, UvsReason};
90
91    #[test]
92    fn test_assert_err_code_helper() {
93        let err = StructError::from(UvsReason::system_error());
94        assert_err_code(&err, "sys.io_error");
95    }
96
97    #[test]
98    fn test_assert_err_category_helper() {
99        let err = StructError::from(UvsReason::business_error());
100        assert_err_category(&err, ErrorCategory::Biz);
101    }
102
103    #[test]
104    fn test_assert_err_identity_helper() {
105        let err = StructError::from(UvsReason::network_error());
106        assert_err_identity(&err, "sys.network_error", ErrorCategory::Sys);
107    }
108
109    #[test]
110    fn test_assert_err_operation_helper() {
111        let err = StructError::from(UvsReason::system_error())
112            .with_detail("read config failed")
113            .doing("load config");
114        assert_err_operation(&err, "load config");
115    }
116
117    #[test]
118    fn test_assert_err_path_helper() {
119        let err = StructError::from(UvsReason::system_error())
120            .with_detail("read config failed")
121            .doing("load config")
122            .at("config.toml");
123        assert_err_path(&err, "load config / config.toml");
124    }
125}