fluent_test/backend/matchers/
option.rs1use crate::backend::Assertion;
2use crate::backend::assertions::sentence::AssertionSentence;
3use std::fmt::Debug;
4
5pub trait OptionMatchers<T: Debug> {
7 fn to_be_some(self) -> Self;
8 fn to_be_none(self) -> Self;
9 fn to_contain(self, expected: &T) -> Self
10 where
11 T: PartialEq;
12}
13
14trait AsOption {
16 type Item: Debug;
17
18 fn is_some_option(&self) -> bool;
19 fn is_none_option(&self) -> bool;
20 fn contains_item<U>(&self, expected: &U) -> bool
21 where
22 U: PartialEq<Self::Item>;
23}
24
25impl<T: Debug + PartialEq> AsOption for Option<T> {
27 type Item = T;
28
29 fn is_some_option(&self) -> bool {
30 self.is_some()
31 }
32
33 fn is_none_option(&self) -> bool {
34 self.is_none()
35 }
36
37 fn contains_item<U>(&self, expected: &U) -> bool
38 where
39 U: PartialEq<Self::Item>,
40 {
41 match self {
42 Some(actual) => expected == actual,
43 None => false,
44 }
45 }
46}
47
48impl<T: Debug + PartialEq> AsOption for &Option<T> {
50 type Item = T;
51
52 fn is_some_option(&self) -> bool {
53 self.is_some()
54 }
55
56 fn is_none_option(&self) -> bool {
57 self.is_none()
58 }
59
60 fn contains_item<U>(&self, expected: &U) -> bool
61 where
62 U: PartialEq<Self::Item>,
63 {
64 match self {
65 Some(actual) => expected == actual,
66 None => false,
67 }
68 }
69}
70
71impl<T, V> OptionMatchers<T> for Assertion<V>
73where
74 T: Debug + Clone + PartialEq,
75 V: AsOption<Item = T> + Debug + Clone,
76{
77 fn to_be_some(self) -> Self {
78 let result = self.value.is_some_option();
79 let sentence = AssertionSentence::new("be", "some");
80
81 return self.add_step(sentence, result);
82 }
83
84 fn to_be_none(self) -> Self {
85 let result = self.value.is_none_option();
86 let sentence = AssertionSentence::new("be", "none");
87
88 return self.add_step(sentence, result);
89 }
90
91 fn to_contain(self, expected: &T) -> Self
92 where
93 T: PartialEq,
94 {
95 let result = self.value.contains_item(expected);
96 let sentence = AssertionSentence::new("contain", format!("{:?}", expected));
97
98 return self.add_step(sentence, result);
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::prelude::*;
105
106 #[test]
107 fn test_option_to_be_some() {
108 crate::Reporter::disable_deduplication();
110
111 let some_value: Option<i32> = Some(42);
112 let none_value: Option<i32> = None;
113
114 expect!(some_value).to_be_some();
116 expect!(none_value).to_be_none();
117 expect!(none_value).not().to_be_some();
118 expect!(some_value).not().to_be_none();
119 }
120
121 #[test]
122 #[should_panic(expected = "be some")]
123 fn test_none_to_be_some_fails() {
124 let value: Option<i32> = None;
125 let _assertion = expect!(value).to_be_some();
126 std::hint::black_box(_assertion);
127 }
128
129 #[test]
130 #[should_panic(expected = "be none")]
131 fn test_some_to_be_none_fails() {
132 let value: Option<i32> = Some(42);
133 let _assertion = expect!(value).to_be_none();
134 std::hint::black_box(_assertion);
135 }
136
137 #[test]
138 fn test_option_to_contain() {
139 crate::Reporter::disable_deduplication();
141
142 let value: Option<i32> = Some(42);
143
144 expect!(value).to_contain(&42);
146 expect!(value).not().to_contain(&43);
147
148 let none_value: Option<i32> = None;
149 expect!(none_value).not().to_contain(&42);
150 }
151
152 #[test]
153 #[should_panic(expected = "contain")]
154 fn test_wrong_value_not_fails() {
155 let value: Option<i32> = Some(42);
156 let _assertion = expect!(value).not().to_contain(&42);
157 std::hint::black_box(_assertion);
158 }
159
160 #[test]
161 #[should_panic(expected = "contain 43")]
162 fn test_missing_value_fails() {
163 let value: Option<i32> = Some(42);
164 let _assertion = expect!(value).to_contain(&43);
165 std::hint::black_box(_assertion);
166 }
167
168 #[test]
169 #[should_panic(expected = "contain 42")]
170 fn test_none_value_fails() {
171 let value: Option<i32> = None;
172 let _assertion = expect!(value).to_contain(&42);
173 std::hint::black_box(_assertion);
174 }
175}