fluent_test/backend/matchers/
result.rs

1use crate::backend::Assertion;
2use crate::backend::assertions::sentence::AssertionSentence;
3use std::fmt::Debug;
4
5/// Trait for Result<T, E> assertions
6pub trait ResultMatchers<T: Debug, E: Debug> {
7    fn to_be_ok(self) -> Self;
8    fn to_be_err(self) -> Self;
9    fn to_contain_ok<U: PartialEq<T> + Debug>(self, expected: &U) -> Self;
10    fn to_contain_err<U: PartialEq<E> + Debug>(self, expected: &U) -> Self;
11}
12
13/// Helper trait for Result-like types
14trait AsResult<T: Debug + Clone, E: Debug + Clone> {
15    fn is_ok_result(&self) -> bool;
16    fn is_err_result(&self) -> bool;
17    fn contains_ok<U: PartialEq<T> + Debug>(&self, expected: &U) -> bool;
18    fn contains_err<U: PartialEq<E> + Debug>(&self, expected: &U) -> bool;
19}
20
21// Implementation for Result<T, E>
22impl<T: Debug + Clone, E: Debug + Clone> AsResult<T, E> for Result<T, E> {
23    fn is_ok_result(&self) -> bool {
24        self.is_ok()
25    }
26
27    fn is_err_result(&self) -> bool {
28        self.is_err()
29    }
30
31    fn contains_ok<U: PartialEq<T> + Debug>(&self, expected: &U) -> bool {
32        match self {
33            Ok(actual) => expected == actual,
34            Err(_) => false,
35        }
36    }
37
38    fn contains_err<U: PartialEq<E> + Debug>(&self, expected: &U) -> bool {
39        match self {
40            Ok(_) => false,
41            Err(actual) => expected == actual,
42        }
43    }
44}
45
46// Implementation for &Result<T, E>
47impl<T: Debug + Clone, E: Debug + Clone> AsResult<T, E> for &Result<T, E> {
48    fn is_ok_result(&self) -> bool {
49        self.is_ok()
50    }
51
52    fn is_err_result(&self) -> bool {
53        self.is_err()
54    }
55
56    fn contains_ok<U: PartialEq<T> + Debug>(&self, expected: &U) -> bool {
57        match self {
58            Ok(actual) => expected == actual,
59            Err(_) => false,
60        }
61    }
62
63    fn contains_err<U: PartialEq<E> + Debug>(&self, expected: &U) -> bool {
64        match self {
65            Ok(_) => false,
66            Err(actual) => expected == actual,
67        }
68    }
69}
70
71// Single implementation for any type that implements AsResult
72impl<V, T, E> ResultMatchers<T, E> for Assertion<V>
73where
74    T: Debug + Clone,
75    E: Debug + Clone,
76    V: AsResult<T, E> + Debug + Clone,
77{
78    fn to_be_ok(self) -> Self {
79        let result = self.value.is_ok_result();
80        let sentence = AssertionSentence::new("be", "ok");
81
82        return self.add_step(sentence, result);
83    }
84
85    fn to_be_err(self) -> Self {
86        let result = self.value.is_err_result();
87        let sentence = AssertionSentence::new("be", "err");
88
89        return self.add_step(sentence, result);
90    }
91
92    fn to_contain_ok<U: PartialEq<T> + Debug>(self, expected: &U) -> Self {
93        let result = self.value.contains_ok(expected);
94        let sentence = AssertionSentence::new("contain", format!("ok value {:?}", expected));
95
96        return self.add_step(sentence, result);
97    }
98
99    fn to_contain_err<U: PartialEq<E> + Debug>(self, expected: &U) -> Self {
100        let result = self.value.contains_err(expected);
101        let sentence = AssertionSentence::new("contain", format!("err value {:?}", expected));
102
103        return self.add_step(sentence, result);
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use crate::prelude::*;
110
111    #[test]
112    fn test_result_to_be_ok() {
113        // Disable deduplication for tests
114        crate::Reporter::disable_deduplication();
115
116        let ok_value: Result<i32, &str> = Ok(42);
117        let err_value: Result<i32, &str> = Err("error");
118
119        // These should pass
120        expect!(ok_value).to_be_ok();
121        expect!(err_value).to_be_err();
122        expect!(err_value).not().to_be_ok();
123        expect!(ok_value).not().to_be_err();
124    }
125
126    #[test]
127    #[should_panic(expected = "be ok")]
128    fn test_err_to_be_ok_fails() {
129        let value: Result<i32, &str> = Err("error");
130        let _assertion = expect!(value).to_be_ok();
131        std::hint::black_box(_assertion);
132    }
133
134    #[test]
135    #[should_panic(expected = "be err")]
136    fn test_ok_to_be_err_fails() {
137        let value: Result<i32, &str> = Ok(42);
138        let _assertion = expect!(value).to_be_err();
139        std::hint::black_box(_assertion);
140    }
141
142    #[test]
143    fn test_result_contain_values() {
144        // Disable deduplication for tests
145        crate::Reporter::disable_deduplication();
146
147        let ok_value: Result<i32, &str> = Ok(42);
148        let err_value: Result<i32, &str> = Err("error");
149
150        // These should pass
151        expect!(ok_value).to_contain_ok(&42);
152        expect!(ok_value).not().to_contain_ok(&43);
153        expect!(err_value).to_contain_err(&"error");
154        expect!(err_value).not().to_contain_err(&"different");
155    }
156
157    #[test]
158    #[should_panic(expected = "contain ok value")]
159    fn test_ok_wrong_value_fails() {
160        let value: Result<i32, &str> = Ok(42);
161        let _assertion = expect!(value).to_contain_ok(&43);
162        std::hint::black_box(_assertion);
163    }
164
165    #[test]
166    #[should_panic(expected = "not contain ok value")]
167    fn test_ok_right_value_not_fails() {
168        let value: Result<i32, &str> = Ok(42);
169        let _assertion = expect!(value).not().to_contain_ok(&42);
170        std::hint::black_box(_assertion);
171    }
172
173    #[test]
174    #[should_panic(expected = "contain err value")]
175    fn test_err_wrong_value_fails() {
176        let value: Result<i32, &str> = Err("error");
177        let _assertion = expect!(value).to_contain_err(&"different");
178        std::hint::black_box(_assertion);
179    }
180
181    #[test]
182    #[should_panic(expected = "not contain err value")]
183    fn test_err_right_value_not_fails() {
184        let value: Result<i32, &str> = Err("error");
185        let _assertion = expect!(value).not().to_contain_err(&"error");
186        std::hint::black_box(_assertion);
187    }
188}