Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically use StrComparison for comparing strings #92

Merged
merged 3 commits into from Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 37 additions & 1 deletion pretty_assertions/src/lib.rs
Expand Up @@ -242,13 +242,14 @@ macro_rules! assert_eq {
match (&($left), &($right)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
use $crate::private::CreateComparison;
::core::panic!("assertion failed: `(left == right)`{}{}\
\n\
\n{}\
\n",
$maybe_colon,
format_args!($($arg)*),
$crate::Comparison::new(left_val, right_val)
(left_val, right_val).create_comparison()
)
}
}
Expand Down Expand Up @@ -430,3 +431,38 @@ macro_rules! assert_matches {
}
});
}

// Not public API. Used by the expansion of this crate's assert macros.
#[doc(hidden)]
pub mod private {
#[cfg(feature = "alloc")]
use alloc::string::String;

pub trait CompareAsStrByDefault: AsRef<str> {}
dtolnay marked this conversation as resolved.
Show resolved Hide resolved
impl CompareAsStrByDefault for str {}
impl CompareAsStrByDefault for String {}
impl<T: CompareAsStrByDefault + ?Sized> CompareAsStrByDefault for &T {}

pub trait CreateComparison {
type Comparison;
fn create_comparison(self) -> Self::Comparison;
}

impl<'a, T, U> CreateComparison for &'a (T, U) {
type Comparison = crate::Comparison<'a, T, U>;
fn create_comparison(self) -> Self::Comparison {
crate::Comparison::new(&self.0, &self.1)
}
}

impl<'a, T, U> CreateComparison for (&'a T, &'a U)
where
T: CompareAsStrByDefault + ?Sized,
U: CompareAsStrByDefault + ?Sized,
{
type Comparison = crate::StrComparison<'a, T, U>;
fn create_comparison(self) -> Self::Comparison {
crate::StrComparison::new(self.0, self.1)
}
}
}
65 changes: 53 additions & 12 deletions pretty_assertions/tests/macros.rs
Expand Up @@ -32,23 +32,23 @@ mod assert_str_eq {
::pretty_assertions::assert_str_eq!(s0, s1);
}

#[test]
fn passes_as_ref_types() {
#[derive(PartialEq)]
struct MyString(String);
#[derive(PartialEq)]
struct MyString(String);

impl AsRef<str> for MyString {
fn as_ref(&self) -> &str {
&self.0
}
impl AsRef<str> for MyString {
fn as_ref(&self) -> &str {
&self.0
}
}

impl PartialEq<String> for MyString {
fn eq(&self, other: &String) -> bool {
&self.0 == other
}
impl PartialEq<String> for MyString {
fn eq(&self, other: &String) -> bool {
&self.0 == other
}
}

#[test]
fn passes_as_ref_types() {
let s0 = MyString("foo".to_string());
let s1 = "foo".to_string();
::pretty_assertions::assert_str_eq!(s0, s1);
Expand All @@ -62,6 +62,21 @@ mod assert_str_eq {
<bar
>baz

"#)]
fn fails_as_ref_types() {
let s0 = MyString("foo\nbar".to_string());
let s1 = "foo\nbaz".to_string();
::pretty_assertions::assert_str_eq!(s0, s1);
}

#[test]
#[should_panic(expected = r#"assertion failed: `(left == right)`

Diff < left / right > :
foo
<bar
>baz

"#)]
fn fails_foo() {
::pretty_assertions::assert_str_eq!("foo\nbar", "foo\nbaz");
Expand Down Expand Up @@ -161,6 +176,32 @@ mod assert_eq {
fn fails_custom_trailing_comma() {
::pretty_assertions::assert_eq!(666, 999, "custom panic message",);
}

#[test]
#[should_panic(expected = r#"assertion failed: `(left == right)`

Diff < left / right > :
foo
<bar
>baz

"#)]
fn fails_str() {
::pretty_assertions::assert_eq!("foo\nbar", "foo\nbaz");
}

#[test]
#[should_panic(expected = r#"assertion failed: `(left == right)`

Diff < left / right > :
foo
<bar
>baz

"#)]
fn fails_string() {
::pretty_assertions::assert_eq!("foo\nbar".to_string(), "foo\nbaz".to_string());
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding these - I also added a couple more tests to cover the String/AsRef cases. Could you push these onto your branch, or give me access to do so?

commit 872b7233da10a4c69ca5cc1fd744e95fbb5af3aa
Author: Tom Milligan <tom@reinfer.io>
Date:   Wed Mar 9 07:55:13 2022 +0000

    [review] add more macro tests

diff --git a/pretty_assertions/tests/macros.rs b/pretty_assertions/tests/macros.rs
index bbbe8de..fbb5e84 100644
--- a/pretty_assertions/tests/macros.rs
+++ b/pretty_assertions/tests/macros.rs
@@ -32,23 +32,23 @@ mod assert_str_eq {
         ::pretty_assertions::assert_str_eq!(s0, s1);
     }
 
-    #[test]
-    fn passes_as_ref_types() {
-        #[derive(PartialEq)]
-        struct MyString(String);
+    #[derive(PartialEq)]
+    struct MyString(String);
 
-        impl AsRef<str> for MyString {
-            fn as_ref(&self) -> &str {
-                &self.0
-            }
+    impl AsRef<str> for MyString {
+        fn as_ref(&self) -> &str {
+            &self.0
         }
+    }
 
-        impl PartialEq<String> for MyString {
-            fn eq(&self, other: &String) -> bool {
-                &self.0 == other
-            }
+    impl PartialEq<String> for MyString {
+        fn eq(&self, other: &String) -> bool {
+            &self.0 == other
         }
+    }
 
+    #[test]
+    fn passes_as_ref_types() {
         let s0 = MyString("foo".to_string());
         let s1 = "foo".to_string();
         ::pretty_assertions::assert_str_eq!(s0, s1);
@@ -62,10 +62,38 @@ mod assert_str_eq {
 �[31m<ba�[0m�[1;48;5;52;31mr�[0m
 �[32m>ba�[0m�[1;48;5;22;32mz�[0m
 
+"#)]
+    fn fails_as_ref_types() {
+        let s0 = MyString("foo\nbar".to_string());
+        let s1 = "foo\nbaz".to_string();
+        ::pretty_assertions::assert_str_eq!(s0, s1);
+    }
+
+    #[test]
+    #[should_panic(expected = r#"assertion failed: `(left == right)`
+
+�[1mDiff�[0m �[31m< left�[0m / �[32mright >�[0m :
+ foo
+�[31m<ba�[0m�[1;48;5;52;31mr�[0m
+�[32m>ba�[0m�[1;48;5;22;32mz�[0m
+
 "#)]
     fn fails_foo() {
         ::pretty_assertions::assert_str_eq!("foo\nbar", "foo\nbaz");
     }
+
+    #[test]
+    #[should_panic(expected = r#"assertion failed: `(left == right)`
+
+�[1mDiff�[0m �[31m< left�[0m / �[32mright >�[0m :
+ foo
+�[31m<ba�[0m�[1;48;5;52;31mr�[0m
+�[32m>ba�[0m�[1;48;5;22;32mz�[0m
+
+"#)]
+    fn fails_string() {
+        ::pretty_assertions::assert_eq!("foo\nbar".to_string(), "foo\nbaz".to_string());
+    }
 }
 
 #[allow(clippy::eq_op)]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great—I've committed this change (except I moved your new fails_string from mod assert_str_eq to mod assert_eq, since it is testing assert_eq!).


mod assert_ne {
Expand Down