assert_str/
lib.rs

1//! Macros for asserting of multiline strings [`String`] and [`&str`].
2//! The API is very similar to the API provided by the stdlib's own assert_eq!
3//! or assert_ne!. Left and right expression could be different types.
4//!
5//! # Examples
6//!
7//! Some examples are provided in the docs for
8//! [each individual macro](#macros).
9//!
10//! [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
11//! [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
12
13/// Asserts that multiline strings([`&str`] or [`String`]) are identical. It
14/// ignores different new line characters for different OSes: `\n` or `\r\n`.
15///
16/// # Examples
17///
18/// Test on equality of two strings generated on different OSes:
19///
20/// ```
21/// use assert_str::assert_str_eq;
22/// assert_str_eq!("This string\nEnd", "This string\r\nEnd", "Responces should be equal");
23/// ```
24///
25/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
26/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
27#[macro_export]
28macro_rules! assert_str_eq {
29    ($left:expr, $right:expr) => ({
30        match (&$left, &$right) {
31            (left_val, right_val) => {
32                let left_lines = left_val.lines().collect::<Vec<_>>();
33                let right_lines = right_val.lines().collect::<Vec<_>>();
34                if !(left_lines == right_lines) {
35                    panic!(r#"assertion failed: `(left == right)`
36  left: `{}`,
37 right: `{}`"#, left_lines.join("\n"), right_lines.join("\n"))
38                }
39            }
40        }
41    });
42    ($left:expr, $right:expr,) => ({
43        $crate::assert_str_eq!($left, $right)
44    });
45    ($left:expr, $right:expr, $($arg:tt)+) => ({
46        match (&$left, &$right) {
47            (left_val, right_val) => {
48                let left_lines = left_val.lines().collect::<Vec<_>>();
49                let right_lines = right_val.lines().collect::<Vec<_>>();
50                if !(left_lines == right_lines) {
51                    panic!(r#"assertion failed: `(left == right)`
52  left: `{}`,
53 right: `{}`: {}"#, left_lines.join("\n"), right_lines.join("\n"),
54                    format_args!($($arg)+))
55                }
56            }
57        }
58    });
59}
60
61/// Asserts that multiline strings([`&str`] or [`String`]) are not identical. It
62/// ignores different new line characters for different OSes: `\n` or `\r\n`.
63///
64/// # Examples
65///
66/// Test on inequality of two strings generated on different OSes:
67///
68/// ```
69/// use assert_str::assert_str_ne;
70/// assert_str_ne!("This string\nEnd", "This string\r\nFinalEnd", "Responces should not be equal");
71/// ```
72///
73/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
74/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
75#[macro_export]
76macro_rules! assert_str_ne {
77    ($left:expr, $right:expr) => ({
78        match (&$left, &$right) {
79            (left_val, right_val) => {
80                let left_lines = left_val.lines().collect::<Vec<_>>();
81                let right_lines = right_val.lines().collect::<Vec<_>>();
82                if (left_lines == right_lines) {
83                    panic!(r#"assertion failed: `(left != right)`
84  left: `{}`,
85 right: `{}`"#, left_lines.join("\n"), right_lines.join("\n"))
86                }
87            }
88        }
89    });
90    ($left:expr, $right:expr,) => ({
91        $crate::assert_str_ne!($left, $right)
92    });
93    ($left:expr, $right:expr, $($arg:tt)+) => ({
94        match (&$left, &$right) {
95            (left_val, right_val) => {
96                let left_lines = left_val.lines().collect::<Vec<_>>();
97                let right_lines = right_val.lines().collect::<Vec<_>>();
98                if (left_lines == right_lines) {
99                    panic!(r#"assertion failed: `(left != right)`
100  left: `{}`,
101  right: `{}`: {}"#, left_lines.join("\n"), right_lines.join("\n"),
102                    format_args!($($arg)+))
103                }
104            }
105        }
106    });
107}
108
109/// Asserts that multiline strings([`&str`] or [`String`]) are identical when
110/// every line is trimmed and empty lines are removed. It ignores different
111/// new line characters for different OSes: `\n` or `\r\n`.
112///
113/// # Examples
114///
115/// Test on equality of two trimmed strings generated on different OSes:
116///
117/// ```
118/// use assert_str::assert_str_trim_eq;
119/// assert_str_trim_eq!("<html>\t \n\t<head> \n\t</head></html>",
120///     "<html>\r\n<head>\r\n</head></html>", "Responces should be equal");
121/// ```
122///
123/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
124/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
125#[macro_export]
126macro_rules! assert_str_trim_eq {
127    ($left:expr, $right:expr) => ({
128        match (&$left, &$right) {
129            (left_val, right_val) => {
130                let left_lines = left_val
131                    .lines()
132                    .map(|line| line.trim())
133                    .filter(|line| !line.is_empty())
134                    .collect::<Vec<_>>();
135
136                let right_lines = right_val
137                    .lines()
138                    .map(|line| line.trim())
139                    .filter(|line| !line.is_empty())
140                    .collect::<Vec<_>>();
141
142                if !(left_lines == right_lines) {
143                    panic!(r#"assertion failed: `(left == right)`
144  left: `{}`,
145 right: `{}`"#, left_lines.join("\n"), right_lines.join("\n"))
146                }
147            }
148        }
149    });
150    ($left:expr, $right:expr,) => ({
151        $crate::assert_str_trim_eq!($left, $right)
152    });
153    ($left:expr, $right:expr, $($arg:tt)+) => ({
154        match (&$left, &$right) {
155            (left_val, right_val) => {
156                let left_lines = left_val
157                    .lines()
158                    .map(|line| line.trim())
159                    .filter(|line| !line.is_empty())
160                    .collect::<Vec<_>>();
161
162                let right_lines = right_val
163                    .lines()
164                    .map(|line| line.trim())
165                    .filter(|line| !line.is_empty())
166                    .collect::<Vec<_>>();
167
168                if !(left_lines == right_lines) {
169                    panic!(r#"assertion failed: `(left == right)`
170  left: `{}`,
171 right: `{}`: {}"#, left_lines.join("\n"), right_lines.join("\n"),
172                    format_args!($($arg)+))
173                }
174            }
175        }
176    });
177}
178
179/// Asserts that multiline strings([`&str`] or [`String`]) are identical. It
180/// ignores different new line characters for different OSes: `\n` or `\r\n`
181///
182/// # Examples
183///
184/// Test on equality of two trimmed strings:
185///
186/// ```
187/// use assert_str::assert_str_trim_ne;
188/// assert_str_trim_ne!("<html>\t \n\t<head> \n\t</head></html>",
189///     "<HTML><head></head></html>", "Responces should not be equal");
190/// ```
191///
192/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
193/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
194#[macro_export]
195macro_rules! assert_str_trim_ne {
196    ($left:expr, $right:expr) => ({
197        match (&$left, &$right) {
198            (left_val, right_val) => {
199                let left_lines = left_val
200                    .lines()
201                    .map(|x| x.trim())
202                    .filter(|line| !line.is_empty())
203                    .collect::<Vec<_>>();
204
205                let right_lines = right_val
206                    .lines()
207                    .map(|x| x.trim())
208                    .filter(|line| !line.is_empty())
209                    .collect::<Vec<_>>();
210
211                if (left_lines == right_lines) {
212                    panic!(r#"assertion failed: `(left != right)`
213  left: `{}`,
214 right: `{}`"#, left_lines.join("\n"), right_lines.join("\n"))
215                }
216            }
217        }
218    });
219    ($left:expr, $right:expr,) => ({
220        $crate::assert_str_trim_ne!($left, $right)
221    });
222    ($left:expr, $right:expr, $($arg:tt)+) => ({
223        match (&$left, &$right) {
224            (left_val, right_val) => {
225                let left_lines = left_val
226                    .lines()
227                    .map(|x| x.trim())
228                    .filter(|line| !line.is_empty())
229                    .collect::<Vec<_>>();
230
231                let right_lines = right_val
232                    .lines()
233                    .map(|x| x.trim())
234                    .filter(|line| !line.is_empty())
235                    .collect::<Vec<_>>();
236
237                if (left_lines == right_lines) {
238                    panic!(r#"assertion failed: `(left != right)`
239  left: `{}`,
240 right: `{}`: {}"#, left_lines.join("\n"), right_lines.join("\n"),
241                    format_args!($($arg)+))
242                }
243            }
244        }
245    });
246}
247
248/// Asserts that multiline strings([`&str`] or [`String`]) are identical when
249/// every line is trimmed and new lines are removed.
250///
251/// # Examples
252///
253/// Test on equality of two trimmed strings:
254///
255/// ```
256/// use assert_str::assert_str_trim_all_eq;
257/// assert_str_trim_all_eq!("<html>\t \n\t<head> \n\t</head></html>",
258///     "<html><head></head></html>", "Responces should be equal");
259/// ```
260///
261/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
262/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
263#[macro_export]
264macro_rules! assert_str_trim_all_eq {
265    ($left:expr, $right:expr) => ({
266        match (&$left, &$right) {
267            (left_val, right_val) => {
268                let left_lines = left_val
269                    .lines()
270                    .map(|line| line.trim())
271                    .filter(|line| !line.is_empty())
272                    .collect::<Vec<_>>();
273
274                let right_lines = right_val
275                    .lines()
276                    .map(|line| line.trim())
277                    .filter(|line| !line.is_empty())
278                    .collect::<Vec<_>>();
279
280                if !(left_lines == right_lines) {
281                    panic!(r#"assertion failed: `(left == right)`
282  left: `{}`,
283 right: `{}`"#, left_lines.join("\n"), right_lines.join("\n"))
284                }
285            }
286        }
287    });
288    ($left:expr, $right:expr,) => ({
289        $crate::assert_str_trim_eq!($left, $right)
290    });
291    ($left:expr, $right:expr, $($arg:tt)+) => ({
292        match (&$left, &$right) {
293            (left_val, right_val) => {
294                let left_lines = left_val
295                    .lines()
296                    .map(|line| line.trim())
297                    .fold(String::new(), |acc, x| acc + x);
298
299                let right_lines = right_val
300                    .lines()
301                    .map(|line| line.trim())
302                    .fold(String::new(), |acc, x| acc + x);
303
304                if !(left_lines == right_lines) {
305                    panic!(r#"assertion failed: `(left == right)`
306  left: `{}`,
307 right: `{}`: {}"#, left_lines, right_lines,
308                    format_args!($($arg)+))
309                }
310            }
311        }
312    });
313}
314
315/// Asserts that multiline strings([`&str`] or [`String`]) are identical when
316/// every line is trimmed and new lines are removed.
317///
318/// # Examples
319///
320/// Test on inequality of two trimmed strings:
321///
322/// ```
323/// use assert_str::assert_str_trim_all_ne;
324/// assert_str_trim_all_ne!("<html>\t \n\t<head> \n\t</head></html>",
325///     "<HTML><head></head></html>", "Responces should not be equal");
326/// ```
327///
328/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
329/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
330#[macro_export]
331macro_rules! assert_str_trim_all_ne {
332    ($left:expr, $right:expr) => ({
333        match (&$left, &$right) {
334            (left_val, right_val) => {
335                let left_lines = left_val
336                    .lines()
337                    .map(|x| x.trim())
338                    .fold(String::new(), |acc, x| acc + x);
339
340                let right_lines = right_val
341                    .lines()
342                    .map(|x| x.trim())
343                    .fold(String::new(), |acc, x| acc + x);
344
345                if (left_lines == right_lines) {
346                    panic!(r#"assertion failed: `(left != right)`
347  left: `{}`,
348 right: `{}`"#, left_lines, right_lines)
349                }
350            }
351        }
352    });
353    ($left:expr, $right:expr,) => ({
354        $crate::assert_str_trim_ne!($left, $right)
355    });
356    ($left:expr, $right:expr, $($arg:tt)+) => ({
357        match (&$left, &$right) {
358            (left_val, right_val) => {
359                let left_lines = left_val
360                    .lines()
361                    .map(|x| x.trim())
362                    .fold(String::new(), |acc, x| acc + x);
363
364                let right_lines = right_val
365                    .lines()
366                    .map(|x| x.trim())
367                    .fold(String::new(), |acc, x| acc + x);
368
369                if (left_lines == right_lines) {
370                    panic!(r#"assertion failed: `(left != right)`
371  left: `{}`,
372 right: `{}`: {}"#, left_lines, right_lines,
373                    format_args!($($arg)+))
374                }
375            }
376        }
377    });
378}
379
380#[cfg(test)]
381mod tests {
382    #[test]
383    fn cross_str_equal_simple() {
384        assert_str_eq!("Line\nLine2", "Line\r\nLine2");
385        assert_str_eq!("Line\nLine2".to_owned(), "Line\r\nLine2");
386        assert_str_eq!("Line\nLine2", "Line\r\nLine2".to_owned());
387        assert_str_eq!("Line\nLine2".to_owned(), "Line\r\nLine2".to_owned());
388        assert_str_eq!("Line\nLine2", "Line\r\nLine2",);
389    }
390
391    #[test]
392    fn cross_str_equal_message() {
393        assert_str_eq!("Line\nLine2".to_owned(), "Line\r\nLine2", "Message");
394        assert_str_eq!("Line\nLine2", "Line\r\nLine2".to_owned(), "Message");
395        assert_str_eq!("L\nLine2".to_owned(), "L\r\nLine2".to_owned(), "Message");
396        assert_str_eq!("Line\nLine2", "Line\r\nLine2", "Message");
397    }
398
399    #[test]
400    fn cross_str_not_equal_simple() {
401        assert_str_ne!("Line\nLine2", "Line\r\nLine");
402        assert_str_ne!("Line\nLine2".to_owned(), "Line\r\nLine");
403        assert_str_ne!("Line\nLine2", "Line\r\nLine".to_owned());
404        assert_str_ne!("Line\nLine2", "Line\r\nLine",);
405    }
406
407    #[test]
408    fn cross_str_not_equal_message() {
409        assert_str_ne!("Line\nLine2".to_owned(), "Line\r\nLine", "Message");
410        assert_str_ne!("Line\nLine2", "Line\r\nLine".to_owned(), "Message");
411        assert_str_ne!("L\nLine2".to_owned(), "L\r\nLine".to_owned(), "Message");
412        assert_str_ne!("Line\nLine2", "Line\r\nLine", "Message");
413    }
414
415    #[test]
416    fn cross_str_trim_equal() {
417        let left = "String  \n Line ".to_owned();
418        let right = "String\r\nLine".to_owned();
419        assert_str_trim_eq!(left, right);
420        assert_str_trim_eq!(&left, right);
421        assert_str_trim_eq!(left, &right);
422        assert_str_trim_eq!(&left, &right);
423        assert_str_trim_eq!(left, right,);
424    }
425
426    #[test]
427    fn cross_str_trim_equal_message() {
428        let left = "String  \n Line ".to_owned();
429        let right = "String\r\nLine".to_owned();
430        assert_str_trim_eq!(&left, right, "Message");
431        assert_str_trim_eq!(left, &right, "Message");
432        assert_str_trim_eq!(left, right, "Message");
433        assert_str_trim_eq!(&left, &right, "Message");
434    }
435
436    #[test]
437    fn cross_str_trim_not_equal() {
438        let left = "String  \n Line ".to_owned();
439        let right = "String\r\n12".to_owned();
440        assert_str_trim_ne!(left, right);
441        assert_str_trim_ne!(&left, right);
442        assert_str_trim_ne!(left, &right);
443        assert_str_trim_ne!(&left, &right);
444        assert_str_trim_ne!(left, right,);
445    }
446
447    #[test]
448    fn cross_str_trim_not_equal_message() {
449        let left = "String  \n Line ".to_owned();
450        let right = "String\r\n12".to_owned();
451        assert_str_trim_ne!(left, right, "Message");
452        assert_str_trim_ne!(&left, right, "Message");
453        assert_str_trim_ne!(left, &right, "Message");
454        assert_str_trim_ne!(&left, &right, "Message");
455    }
456
457    #[test]
458    fn cross_str_trim_all_equal() {
459        let left = "String  \n Line ".to_owned();
460        let right = "String\r\nLine".to_owned();
461        assert_str_trim_all_eq!(left, right);
462        assert_str_trim_all_eq!(&left, right);
463        assert_str_trim_all_eq!(left, &right);
464        assert_str_trim_all_eq!(&left, &right);
465        assert_str_trim_all_eq!(left, right,);
466    }
467
468    #[test]
469    fn cross_str_trim_all_equal_message() {
470        let left = "String  \n Line ".to_owned();
471        let right = "StringLine".to_owned();
472        assert_str_trim_all_eq!(&left, right, "Message");
473        assert_str_trim_all_eq!(left, &right, "Message");
474        assert_str_trim_all_eq!(left, right, "Message");
475        assert_str_trim_all_eq!(&left, &right, "Message");
476    }
477
478    #[test]
479    fn cross_str_trim_all_not_equal() {
480        let left = "String  \n Line ".to_owned();
481        let right = "Stringline".to_owned();
482        assert_str_trim_all_ne!(left, right);
483        assert_str_trim_all_ne!(&left, right);
484        assert_str_trim_all_ne!(left, &right);
485        assert_str_trim_all_ne!(&left, &right);
486        assert_str_trim_all_ne!(left, right,);
487    }
488
489    #[test]
490    fn cross_str_trim_all_not_equal_message() {
491        let left = "String  \n Line ".to_owned();
492        let right = "String12".to_owned();
493        assert_str_trim_all_ne!(left, right, "Message");
494        assert_str_trim_all_ne!(&left, right, "Message");
495        assert_str_trim_all_ne!(left, &right, "Message");
496        assert_str_trim_all_ne!(&left, &right, "Message");
497    }
498}