expect_json/expect/ops/expect_string/
expect_string.rs1use crate::expect::ops::expect_string::ExpectStringSubOp;
2use crate::expect_core::expect_op;
3use crate::expect_core::Context;
4use crate::expect_core::ExpectOp;
5use crate::expect_core::ExpectOpResult;
6use crate::JsonType;
7
8#[expect_op(internal, name = "string")]
9#[derive(Debug, Clone, Default, PartialEq)]
10pub struct ExpectString {
11 sub_ops: Vec<ExpectStringSubOp>,
12}
13
14impl ExpectString {
15 pub(crate) fn new() -> Self {
16 Self { sub_ops: vec![] }
17 }
18
19 pub fn empty(mut self) -> Self {
20 self.sub_ops.push(ExpectStringSubOp::Empty);
21 self
22 }
23
24 pub fn not_empty(mut self) -> Self {
25 self.sub_ops.push(ExpectStringSubOp::NotEmpty);
26 self
27 }
28
29 pub fn len(mut self, len: usize) -> Self {
30 self.sub_ops.push(ExpectStringSubOp::Len(len));
31 self
32 }
33
34 pub fn min_len(mut self, min_len: usize) -> Self {
35 self.sub_ops.push(ExpectStringSubOp::MinLen(min_len));
36 self
37 }
38
39 pub fn max_len(mut self, max_len: usize) -> Self {
40 self.sub_ops.push(ExpectStringSubOp::MaxLen(max_len));
41 self
42 }
43
44 pub fn contains<S>(mut self, expected_sub_string: S) -> Self
71 where
72 S: Into<String>,
73 {
74 self.sub_ops
75 .push(ExpectStringSubOp::Contains(expected_sub_string.into()));
76 self
77 }
78
79 pub fn matches_regex<S>(mut self, pattern: S) -> Self
106 where
107 S: Into<String>,
108 {
109 self.sub_ops
110 .push(ExpectStringSubOp::MatchesRegex(pattern.into()));
111 self
112 }
113}
114
115impl ExpectOp for ExpectString {
116 fn on_string(&self, context: &mut Context, received: &str) -> ExpectOpResult<()> {
117 for sub_op in &self.sub_ops {
118 sub_op.on_string(self, context, received)?;
119 }
120
121 Ok(())
122 }
123
124 fn debug_supported_types(&self) -> &'static [JsonType] {
125 &[JsonType::String]
126 }
127}
128
129#[cfg(test)]
130mod test_contains {
131 use crate::expect;
132 use crate::expect_json_eq;
133 use pretty_assertions::assert_eq;
134 use serde_json::json;
135
136 #[test]
137 fn it_should_be_equal_for_identical_strings() {
138 let left = json!("1, 2, 3");
139 let right = json!(expect::string().contains("1, 2, 3"));
140
141 let output = expect_json_eq(&left, &right);
142 assert!(output.is_ok());
143 }
144
145 #[test]
146 fn it_should_be_equal_for_partial_matches_in_middle() {
147 let left = json!("0, 1, 2, 3, 4");
148 let right = json!(expect::string().contains("1, 2, 3"));
149
150 let output = expect_json_eq(&left, &right);
151 assert!(output.is_ok());
152 }
153
154 #[test]
155 fn it_should_be_ok_for_empty_contains() {
156 let left = json!("0, 1, 2, 3, 4, 5");
157 let right = json!(expect::string().contains(""));
158
159 let output = expect_json_eq(&left, &right);
160 assert!(output.is_ok());
161 }
162
163 #[test]
164 fn it_should_error_for_totall_different_values() {
165 let left = json!("1, 2, 3");
166 let right = json!(expect::string().contains("a, b, c"));
167
168 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
169 assert_eq!(
170 output,
171 r#"Json string at root does not contain expected value:
172 expected string to contain "a, b, c", but it was not found.
173 received "1, 2, 3""#
174 );
175 }
176}
177
178#[cfg(test)]
179mod test_empty {
180 use crate::expect;
181 use crate::expect_json_eq;
182 use pretty_assertions::assert_eq;
183 use serde_json::json;
184
185 #[test]
186 fn it_should_pass_when_string_is_empty() {
187 let left = json!("");
188 let right = json!(expect::string().empty());
189
190 let output = expect_json_eq(&left, &right);
191 assert!(output.is_ok(), "assertion error: {output:#?}");
192 }
193
194 #[test]
195 fn it_should_fail_when_string_is_not_empty() {
196 let left = json!("🦊");
197 let right = json!(expect::string().empty());
198
199 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
200 assert_eq!(
201 output,
202 r#"Json expect::string() error at root:
203 expected empty string
204 received "🦊""#
205 );
206 }
207}
208
209#[cfg(test)]
210mod test_not_empty {
211 use crate::expect;
212 use crate::expect_json_eq;
213 use pretty_assertions::assert_eq;
214 use serde_json::json;
215
216 #[test]
217 fn it_should_pass_when_string_is_not_empty() {
218 let left = json!("🦊");
219 let right = json!(expect::string().not_empty());
220
221 let output = expect_json_eq(&left, &right);
222 assert!(output.is_ok(), "assertion error: {output:#?}");
223 }
224
225 #[test]
226 fn it_should_fail_when_string_is_empty() {
227 let left = json!("");
228 let right = json!(expect::string().not_empty());
229
230 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
231 assert_eq!(
232 output,
233 r#"Json expect::string() error at root:
234 expected non-empty string
235 received """#
236 );
237 }
238}
239
240#[cfg(test)]
241mod test_len {
242 use crate::expect;
243 use crate::expect_json_eq;
244 use pretty_assertions::assert_eq;
245 use serde_json::json;
246
247 #[test]
248 fn it_should_pass_when_string_has_same_number_of_characters() {
249 let left = json!("123");
250 let right = json!(expect::string().len(3));
251
252 let output = expect_json_eq(&left, &right);
253 assert!(output.is_ok(), "assertion error: {output:#?}");
254 }
255
256 #[test]
257 fn it_should_fail_when_string_is_too_short() {
258 let left = json!("12");
259 let right = json!(expect::string().len(3));
260
261 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
262 assert_eq!(
263 output,
264 r#"Json expect::string() error at root:
265 expected string to have 3 characters, but it has 2,
266 received "12""#
267 );
268 }
269
270 #[test]
271 fn it_should_fail_when_string_is_too_long() {
272 let left = json!("1234");
273 let right = json!(expect::string().len(3));
274
275 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
276 assert_eq!(
277 output,
278 r#"Json expect::string() error at root:
279 expected string to have 3 characters, but it has 4,
280 received "1234""#
281 );
282 }
283}
284
285#[cfg(test)]
286mod test_min_len {
287 use crate::expect;
288 use crate::expect_json_eq;
289 use pretty_assertions::assert_eq;
290 use serde_json::json;
291
292 #[test]
293 fn it_should_pass_when_string_has_exactly_enough_characters() {
294 let left = json!("123");
295 let right = json!(expect::string().min_len(3));
296
297 let output = expect_json_eq(&left, &right);
298 assert!(output.is_ok(), "assertion error: {output:#?}");
299 }
300
301 #[test]
302 fn it_should_pass_when_string_has_more_than_enough_characters() {
303 let left = json!("12345");
304 let right = json!(expect::string().min_len(3));
305
306 let output = expect_json_eq(&left, &right);
307 assert!(output.is_ok(), "assertion error: {output:#?}");
308 }
309
310 #[test]
311 fn it_should_fail_when_string_is_too_short() {
312 let left = json!("12");
313 let right = json!(expect::string().min_len(3));
314
315 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
316 assert_eq!(
317 output,
318 r#"Json expect::string() error at root:
319 expected string to have at least 3 characters, but it has 2,
320 received "12""#
321 );
322 }
323}
324
325#[cfg(test)]
326mod test_max_len {
327 use crate::expect;
328 use crate::expect_json_eq;
329 use pretty_assertions::assert_eq;
330 use serde_json::json;
331
332 #[test]
333 fn it_should_pass_when_string_has_exactly_enough_characters() {
334 let left = json!("123");
335 let right = json!(expect::string().max_len(3));
336
337 let output = expect_json_eq(&left, &right);
338 assert!(output.is_ok(), "assertion error: {output:#?}");
339 }
340
341 #[test]
342 fn it_should_pass_when_string_has_less_than_enough_characters() {
343 let left = json!("12");
344 let right = json!(expect::string().max_len(5));
345
346 let output = expect_json_eq(&left, &right);
347 assert!(output.is_ok(), "assertion error: {output:#?}");
348 }
349
350 #[test]
351 fn it_should_fail_when_string_is_too_long() {
352 let left = json!("🦊🦊🦊🦊🦊🦊");
353 let right = json!(expect::string().max_len(3));
354
355 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
356 assert_eq!(
357 output,
358 r#"Json expect::string() error at root:
359 expected string to have at most 3 characters, but it has 24,
360 received "🦊🦊🦊🦊🦊🦊""#
361 );
362 }
363}
364
365#[cfg(test)]
366mod test_matches_regex {
367 use crate::expect;
368 use crate::expect_json_eq;
369 use pretty_assertions::assert_eq;
370 use serde_json::json;
371
372 #[test]
373 fn it_should_pass_when_string_matches_regex() {
374 let left = json!("abc123xyz");
375 let right = json!(expect::string().matches_regex(r"^[a-z]+[0-9]+[a-z]+$"));
376 let output = expect_json_eq(&left, &right);
377 assert!(output.is_ok(), "assertion error: {output:#?}");
378 }
379
380 #[test]
381 fn it_should_fail_when_string_does_not_match_regex() {
382 let left = json!("abcxyz");
383 let right = json!(expect::string().matches_regex(r"^[a-z]+[0-9]+[a-z]+$"));
384 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
385 assert_eq!(
386 output,
387 r#"Json string error at root, regex did not match:
388 expected string to match regex pattern '^[a-z]+[0-9]+[a-z]+$',
389 received "abcxyz""#
390 );
391 }
392
393 #[test]
394 fn it_should_fail_when_regex_is_invalid() {
395 let left = json!("abc123xyz");
396 let right = json!(expect::string().matches_regex(r"([a-z]+"));
397 let output = expect_json_eq(&left, &right).unwrap_err().to_string();
398 assert!(
400 output.starts_with(r#"Json expect::string() error at root:"#),
401 "Unexpected error output: {output:#?}"
402 );
403 }
404}