fluent_test/backend/matchers/
string.rs1use crate::backend::Assertion;
2use crate::backend::assertions::sentence::AssertionSentence;
3use std::fmt::Debug;
4
5pub trait StringMatchers {
7 fn to_be_empty(self) -> Self;
8 fn to_have_length(self, expected: usize) -> Self;
9
10 fn to_contain(self, substring: &str) -> Self;
12
13 fn to_contain_substring(self, substring: &str) -> Self;
15
16 fn to_start_with(self, prefix: &str) -> Self;
17 fn to_end_with(self, suffix: &str) -> Self;
18 fn to_match(self, pattern: &str) -> Self;
19}
20
21trait AsString {
23 fn is_empty_string(&self) -> bool;
24 fn length_string(&self) -> usize;
25 fn contains_substring(&self, substring: &str) -> bool;
26 fn starts_with_substring(&self, prefix: &str) -> bool;
27 fn ends_with_substring(&self, suffix: &str) -> bool;
28 fn matches_pattern(&self, pattern: &str) -> bool;
29}
30
31impl AsString for String {
33 fn is_empty_string(&self) -> bool {
34 self.is_empty()
35 }
36
37 fn length_string(&self) -> usize {
38 self.len()
39 }
40
41 fn contains_substring(&self, substring: &str) -> bool {
42 self.contains(substring)
43 }
44
45 fn starts_with_substring(&self, prefix: &str) -> bool {
46 self.starts_with(prefix)
47 }
48
49 fn ends_with_substring(&self, suffix: &str) -> bool {
50 self.ends_with(suffix)
51 }
52
53 fn matches_pattern(&self, pattern: &str) -> bool {
54 self.contains(pattern)
56 }
57}
58
59impl AsString for &str {
61 fn is_empty_string(&self) -> bool {
62 self.is_empty()
63 }
64
65 fn length_string(&self) -> usize {
66 self.len()
67 }
68
69 fn contains_substring(&self, substring: &str) -> bool {
70 self.contains(substring)
71 }
72
73 fn starts_with_substring(&self, prefix: &str) -> bool {
74 self.starts_with(prefix)
75 }
76
77 fn ends_with_substring(&self, suffix: &str) -> bool {
78 self.ends_with(suffix)
79 }
80
81 fn matches_pattern(&self, pattern: &str) -> bool {
82 self.contains(pattern)
84 }
85}
86
87impl<V> StringMatchers for Assertion<V>
89where
90 V: AsString + Debug + Clone,
91{
92 fn to_be_empty(self) -> Self {
93 let result = self.value.is_empty_string();
94 let sentence = AssertionSentence::new("be", "empty");
95
96 return self.add_step(sentence, result);
97 }
98
99 fn to_have_length(self, expected: usize) -> Self {
100 let actual_length = self.value.length_string();
101 let result = actual_length == expected;
102 let sentence = AssertionSentence::new("have", format!("length {}", expected));
103
104 return self.add_step(sentence, result);
105 }
106
107 fn to_contain(self, substring: &str) -> Self {
108 return self.to_contain_substring(substring);
109 }
110
111 fn to_contain_substring(self, substring: &str) -> Self {
112 let result = self.value.contains_substring(substring);
113 let sentence = AssertionSentence::new("contain", format!("\"{}\"", substring));
114
115 return self.add_step(sentence, result);
116 }
117
118 fn to_start_with(self, prefix: &str) -> Self {
119 let result = self.value.starts_with_substring(prefix);
120 let sentence = AssertionSentence::new("start with", format!("\"{}\"", prefix));
121
122 return self.add_step(sentence, result);
123 }
124
125 fn to_end_with(self, suffix: &str) -> Self {
126 let result = self.value.ends_with_substring(suffix);
127 let sentence = AssertionSentence::new("end with", format!("\"{}\"", suffix));
128
129 return self.add_step(sentence, result);
130 }
131
132 fn to_match(self, pattern: &str) -> Self {
133 let result = self.value.matches_pattern(pattern);
135 let sentence = AssertionSentence::new("match", format!("pattern \"{}\"", pattern));
136
137 return self.add_step(sentence, result);
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use crate::prelude::*;
144
145 #[test]
146 fn test_string_to_be_empty() {
147 crate::Reporter::disable_deduplication();
149
150 expect!("").to_be_empty();
152 expect!("hello").not().to_be_empty();
153 expect!(String::new()).to_be_empty();
154 expect!(String::from("hello")).not().to_be_empty();
155 }
156
157 #[test]
158 #[should_panic(expected = "be empty")]
159 fn test_non_empty_to_be_empty_fails() {
160 let _assertion = expect!("hello").to_be_empty();
161 std::hint::black_box(_assertion);
162 }
163
164 #[test]
165 #[should_panic(expected = "not be empty")]
166 fn test_empty_not_to_be_empty_fails() {
167 let _assertion = expect!("").not().to_be_empty();
168 std::hint::black_box(_assertion);
169 }
170
171 #[test]
172 fn test_string_to_have_length() {
173 crate::Reporter::disable_deduplication();
175
176 expect!("hello").to_have_length(5);
178 expect!("hello").not().to_have_length(4);
179 expect!(String::from("hello")).to_have_length(5);
180 }
181
182 #[test]
183 #[should_panic(expected = "have length")]
184 fn test_wrong_length_fails() {
185 let _assertion = expect!("hello").to_have_length(4);
186 std::hint::black_box(_assertion);
187 }
188
189 #[test]
190 #[should_panic(expected = "not have length")]
191 fn test_right_length_not_fails() {
192 let _assertion = expect!("hello").not().to_have_length(5);
193 std::hint::black_box(_assertion);
194 }
195
196 #[test]
197 fn test_string_to_contain() {
198 crate::Reporter::disable_deduplication();
200
201 expect!("hello world").to_contain("hello");
203 expect!("hello world").not().to_contain("goodbye");
204 expect!(String::from("hello world")).to_contain("world");
205 }
206
207 #[test]
208 #[should_panic(expected = "not contain")]
209 fn test_not_contains_when_it_does_fails() {
210 let _assertion = expect!("hello world").not().to_contain("hello");
211 std::hint::black_box(_assertion);
212 }
213
214 #[test]
215 #[should_panic(expected = "contain")]
216 fn test_contains_when_it_doesnt_fails() {
217 let _assertion = expect!("hello world").to_contain("goodbye");
218 std::hint::black_box(_assertion);
219 }
220
221 #[test]
222 fn test_string_to_start_with() {
223 crate::Reporter::disable_deduplication();
225
226 expect!("hello world").to_start_with("hello");
228 expect!("hello world").not().to_start_with("world");
229 expect!(String::from("hello world")).to_start_with("hello");
230 }
231
232 #[test]
233 #[should_panic(expected = "not start with")]
234 fn test_not_starts_with_when_it_does_fails() {
235 let _assertion = expect!("hello world").not().to_start_with("hello");
236 std::hint::black_box(_assertion);
237 }
238
239 #[test]
240 #[should_panic(expected = "start with")]
241 fn test_starts_with_when_it_doesnt_fails() {
242 let _assertion = expect!("hello world").to_start_with("world");
243 std::hint::black_box(_assertion);
244 }
245
246 #[test]
247 fn test_string_to_end_with() {
248 crate::Reporter::disable_deduplication();
250
251 expect!("hello world").to_end_with("world");
253 expect!("hello world").not().to_end_with("hello");
254 expect!(String::from("hello world")).to_end_with("world");
255 }
256
257 #[test]
258 #[should_panic(expected = "not end with")]
259 fn test_not_ends_with_when_it_does_fails() {
260 let _assertion = expect!("hello world").not().to_end_with("world");
261 std::hint::black_box(_assertion);
262 }
263
264 #[test]
265 #[should_panic(expected = "end with")]
266 fn test_ends_with_when_it_doesnt_fails() {
267 let _assertion = expect!("hello world").to_end_with("hello");
268 std::hint::black_box(_assertion);
269 }
270
271 #[test]
272 fn test_string_to_match() {
273 crate::Reporter::disable_deduplication();
275
276 expect!("hello world").to_match("world");
278 expect!("hello world").not().to_match("goodbye");
279 expect!(String::from("hello world")).to_match("hello");
280 }
281
282 #[test]
283 #[should_panic(expected = "not match")]
284 fn test_not_matches_when_it_does_fails() {
285 let _assertion = expect!("hello world").not().to_match("hello");
286 std::hint::black_box(_assertion);
287 }
288
289 #[test]
290 #[should_panic(expected = "match")]
291 fn test_matches_when_it_doesnt_fails() {
292 let _assertion = expect!("hello world").to_match("goodbye");
293 std::hint::black_box(_assertion);
294 }
295}