diff --git a/pretty_assertions/src/lib.rs b/pretty_assertions/src/lib.rs index beead99..a4c0b91 100644 --- a/pretty_assertions/src/lib.rs +++ b/pretty_assertions/src/lib.rs @@ -141,6 +141,43 @@ where } } +/// A comparison of two strings. +/// +/// In contrast to [`Comparison`], which uses the [`core::fmt::Debug`] representaiton, +/// this will print newlines unescaped, resulting in multi-line output for multiline strings. +/// +/// ``` +/// use pretty_assertions::StrComparison; +/// +/// print!("{}", StrComparison::new("foo\nbar", "foo\nbaz")); +/// ``` +/// +/// The values may have different types, although in practice they are usually the same. +pub struct StrComparison<'a> +{ + left: &'a str, + right: &'a str, +} + +impl<'a> StrComparison<'a> +{ + /// Store two values to be compared in future. + /// + /// Expensive diffing is deferred until calling `Debug::fmt`. + pub fn new(left: &'a str, right: &'a str) -> StrComparison<'a> { + StrComparison { left: left, right: right } + } +} + +impl<'a> Display for StrComparison<'a> +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // And then diff the debug output + printer::write_header(f)?; + printer::write_lines(f, self.left, self.right) + } +} + /// Asserts that two expressions are equal to each other (using [`PartialEq`]). /// /// On panic, this macro will print a diff derived from [`Debug`] representation of @@ -186,6 +223,33 @@ macro_rules! assert_eq { }); } +/// TODO +#[macro_export] +macro_rules! assert_str_eq { + ($left:expr, $right:expr$(,)?) => ({ + $crate::assert_str_eq!(@ $left, $right, "", ""); + }); + ($left:expr, $right:expr, $($arg:tt)*) => ({ + $crate::assert_str_eq!(@ $left, $right, ": ", $($arg)+); + }); + (@ $left:expr, $right:expr, $maybe_semicolon:expr, $($arg:tt)*) => ({ + match (&($left), &($right)) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + ::core::panic!("assertion failed: `(left == right)`{}{}\ + \n\ + \n{}\ + \n", + $maybe_semicolon, + format_args!($($arg)*), + $crate::StrComparison::new(left_val, right_val) + ) + } + } + } + }); +} + /// Asserts that two expressions are not equal to each other (using [`PartialEq`]). /// /// On panic, this macro will print the values of the expressions with their diff --git a/pretty_assertions/tests/macros.rs b/pretty_assertions/tests/macros.rs index 3c34f02..a2fdbf8 100644 --- a/pretty_assertions/tests/macros.rs +++ b/pretty_assertions/tests/macros.rs @@ -4,6 +4,46 @@ #[cfg(feature = "alloc")] extern crate alloc; +#[allow(clippy::eq_op)] +mod assert_str_eq { + #[cfg(feature = "alloc")] + use ::alloc::string::{String, ToString}; + #[cfg(feature = "std")] + use ::std::string::{String, ToString}; + + #[test] + fn passes_str() { + let a = "some value"; + ::pretty_assertions::assert_str_eq!(a, a); + } + + #[test] + fn passes_string() { + let a: String = "some value".to_string(); + ::pretty_assertions::assert_str_eq!(a, a); + } + + #[test] + fn passes_comparable_types() { + let s0: &'static str = "foo"; + let s1: String = "foo".to_string(); + ::pretty_assertions::assert_str_eq!(s0, s1); + } + + #[test] + #[should_panic(expected = r#"assertion failed: `(left == right)` + +Diff < left / right > : + foo +baz + +"#)] + fn fails_foo() { + ::pretty_assertions::assert_str_eq!("foo\nbar", "foo\nbaz"); + } +} + #[allow(clippy::eq_op)] mod assert_eq { #[cfg(feature = "alloc")]