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