Repository: rust-pretty-assertions/rust-pretty-assertions (Rust)

Issue:
assert_eq(a,b,) doesn't show pretty printing
Giving the following MCVE:

```rust
fn main() {
    #[derive(Debug, PartialEq)]
    struct Foo<'a> {
        lorem: &'a str,
        ipsum: u32,
        dolor: Result<String, String>,
    }

    let x = Some(Foo { lorem: "Hello World!", ipsum: 42, dolor: Ok("hey".to_string())});
    let y = Some(Foo { lorem: "Hello Wrold!", ipsum: 42, dolor: Ok("hey ho!".to_string())});

    pretty_assertions::assert_eq!(x, y,);
}
```

```none
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Some(Foo { lorem: "Hello World!", ipsum: 42, dolor: Ok("hey") })`,
 right: `Some(Foo { lorem: "Hello Wrold!", ipsum: 42, dolor: Ok("hey ho!") })`', src\main.rs:12:5
```

Add an extra comma, seem to disable everything.


Discussion:
Like I didn't `use pretty_assertions::assert_eq;` the line:

https://github.com/colin-kiegel/rust-pretty-assertions/blob/2f4058ac7fb5e24a923aef80851c6608b6683d0f/src/lib.rs#L113-L115

fail back to std implementation, I think we need to use a internal second macro to avoid repetition code and the bug. But I'm don't know much about rust declarative macro.

Same problem will happen for `assert_ne!`:

https://github.com/colin-kiegel/rust-pretty-assertions/blob/2f4058ac7fb5e24a923aef80851c6608b6683d0f/src/lib.rs#L147-L155

This should do it (it's probably what was intended).
```diff
 ($left:expr , $right:expr,) => ({ 
-    assert_eq!($left, $right)
+    $crate::assert_eq!($left, $right)
 }); 
```
But the optional `,` can also be captured with this macro pattern.
```rust
($left:expr, $right:expr $(,)?) => { /* do stuff */ }
```
Spent a couple of hours today finding out this bug :(
Thanks for reporting this. A fix has been merged and will be in the next release.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8759bcf..0e013a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
 
 - Support for unsized values (#42, @stanislav-tkach)
 
+## Fixed
+
+- Fix some unhygenic macro expansions (#41, @tommilligan)
+
 ## Internal
 
 - Test Windows targets in CI (#46, @tommilligan)
diff --git a/examples/pretty_assertion.rs b/examples/pretty_assertion.rs
index 2c9ab25..63246c6 100644
--- a/examples/pretty_assertion.rs
+++ b/examples/pretty_assertion.rs
@@ -1,4 +1,3 @@
-#[allow(unused_imports)]
-use pretty_assertions::{assert_eq, assert_ne};
+use pretty_assertions::assert_eq;
 
 include!("standard_assertion.rs");
diff --git a/src/lib.rs b/src/lib.rs
index 402e8be..abe6569 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -114,7 +114,7 @@ impl Display for Comparison {
 #[macro_export]
 macro_rules! assert_eq {
     ($left:expr , $right:expr,) => ({
-        assert_eq!($left, $right)
+        $crate::assert_eq!($left, $right)
     });
     ($left:expr , $right:expr) => ({
         match (&($left), &($right)) {
@@ -148,13 +148,13 @@ macro_rules! assert_eq {
 #[macro_export]
 macro_rules! assert_ne {
     ($left:expr, $right:expr) => ({
-        assert_ne!(@ $left, $right, "", "");
+        $crate::assert_ne!(@ $left, $right, "", "");
     });
     ($left:expr, $right:expr,) => ({
-        assert_ne!(@ $left, $right, "", "");
+        $crate::assert_ne!(@ $left, $right, "", "");
     });
     ($left:expr, $right:expr, $($arg:tt)+) => ({
-        assert_ne!(@ $left, $right, ": ", $($arg)+);
+        $crate::assert_ne!(@ $left, $right, ": ", $($arg)+);
     });
     (@ $left:expr, $right:expr, $maybe_semicolon:expr, $($arg:tt)+) => ({
         match (&($left), &($right)) {


Test patch:
diff --git a/tests/assert_eq.rs b/tests/assert_eq.rs
index 5541dd1..087e5c6 100644
--- a/tests/assert_eq.rs
+++ b/tests/assert_eq.rs
@@ -1,9 +1,5 @@
 #![allow(clippy::eq_op)]
 
-#[allow(unused_imports)]
-use pretty_assertions::{assert_eq, assert_ne};
-extern crate difference;
-
 #[test]
 #[should_panic(expected = r#"assertion failed: `(left == right)`
 
@@ -40,7 +36,7 @@ fn assert_eq() {
         dolor: Ok("hey ho!".to_string()),
     });
 
-    assert_eq!(x, y);
+    pretty_assertions::assert_eq!(x, y);
 }
 
 #[test]
@@ -81,14 +77,14 @@ fn assert_eq_custom() {
         dolor: Ok("hey ho!".to_string()),
     });
 
-    assert_eq!(x, y, "custom panic message");
+    pretty_assertions::assert_eq!(x, y, "custom panic message");
 }
 
 #[test]
 fn assert_eq_with_comparable_types() {
     let s0: &'static str = "foo";
     let s1: String = "foo".to_string();
-    assert_eq!(s0, s1);
+    pretty_assertions::assert_eq!(s0, s1);
 }
 
 #[test]
@@ -113,7 +109,7 @@ fn assert_eq_with_comparable_types() {
 fn issue12() {
     let left = vec![0, 0, 0, 128, 10, 191, 5, 64];
     let right = vec![84, 248, 45, 64];
-    assert_eq!(left, right);
+    pretty_assertions::assert_eq!(left, right);
 }
 
 #[test]
@@ -152,7 +148,7 @@ fn assert_eq_trailing_comma() {
         dolor: Ok("hey ho!".to_string()),
     });
 
-    assert_eq!(x, y,);
+    pretty_assertions::assert_eq!(x, y,);
 }
 
 #[test]
@@ -193,13 +189,13 @@ fn assert_eq_custom_trailing_comma() {
         dolor: Ok("hey ho!".to_string()),
     });
 
-    assert_eq!(x, y, "custom panic message",);
+    pretty_assertions::assert_eq!(x, y, "custom panic message",);
 }
 
 #[test]
 fn assert_eq_unsized() {
     let a: &[u8] = b"e";
-    assert_eq!(*a, *a);
+    pretty_assertions::assert_eq!(*a, *a);
 }
 
 #[test]
@@ -215,5 +211,5 @@ fn assert_eq_unsized() {
 fn assert_eq_unsized_panic() {
     let a: &[u8] = b"e";
     let b: &[u8] = b"ee";
-    assert_eq!(*a, *b);
+    pretty_assertions::assert_eq!(*a, *b);
 }
diff --git a/tests/assert_ne.rs b/tests/assert_ne.rs
index 5760e94..6166032 100644
--- a/tests/assert_ne.rs
+++ b/tests/assert_ne.rs
@@ -1,7 +1,5 @@
 #![allow(clippy::eq_op)]
 
-#[allow(unused_imports)]
-use pretty_assertions::{assert_eq, assert_ne};
 #[test]
 #[should_panic(expected = r#"assertion failed: `(left != right)`
 
@@ -31,7 +29,7 @@ fn assert_ne() {
         dolor: Ok("hey".to_string()),
     });
 
-    assert_ne!(x, x);
+    pretty_assertions::assert_ne!(x, x);
 }
 
 #[test]
@@ -65,14 +63,14 @@ fn assert_ne_custom() {
         dolor: Ok("hey".to_string()),
     });
 
-    assert_ne!(x, x, "custom panic message");
+    pretty_assertions::assert_ne!(x, x, "custom panic message");
 }
 
 #[test]
 #[should_panic]
 fn assert_ne_non_empty_return() {
     fn not_zero(x: u32) -> u32 {
-        assert_ne!(x, 0);
+        pretty_assertions::assert_ne!(x, 0);
         x
     };
     not_zero(0);
@@ -106,7 +104,7 @@ fn assert_ne_partial() {
         }
     }
 
-    assert_ne!(Foo(-0.0), Foo(0.0));
+    pretty_assertions::assert_ne!(Foo(-0.0), Foo(0.0));
 }
 
 #[test]
@@ -138,7 +136,7 @@ fn assert_ne_trailing_comma() {
         dolor: Ok("hey".to_string()),
     });
 
-    assert_ne!(x, x,);
+    pretty_assertions::assert_ne!(x, x,);
 }
 
 #[test]
@@ -172,14 +170,14 @@ fn assert_ne_custom_trailing_comma() {
         dolor: Ok("hey".to_string()),
     });
 
-    assert_ne!(x, x, "custom panic message",);
+    pretty_assertions::assert_ne!(x, x, "custom panic message",);
 }
 
 #[test]
 fn assert_ne_unsized() {
     let a: &[u8] = b"e";
     let b: &[u8] = b"ee";
-    assert_ne!(*a, *b);
+    pretty_assertions::assert_ne!(*a, *b);
 }
 
 #[test]
@@ -193,5 +191,5 @@ fn assert_ne_unsized() {
 "#)]
 fn assert_ne_unsized_panic() {
     let a: &[u8] = b"e";
-    assert_ne!(*a, *a);
+    pretty_assertions::assert_ne!(*a, *a);
 }
diff --git a/tests/pretty_string.rs b/tests/pretty_string.rs
index 750674a..5ab7607 100644
--- a/tests/pretty_string.rs
+++ b/tests/pretty_string.rs
@@ -1,6 +1,5 @@
-#[allow(unused_imports)]
-use pretty_assertions::{assert_eq, assert_ne};
 use std::fmt;
+
 /// Wrapper around string slice that makes debug output `{:?}` to print string same way as `{}`.
 /// Used in different `assert*!` macros in combination with `pretty_assertions` crate to make
 /// test failures to show nice diffs.
@@ -23,5 +22,5 @@ impl<'a> fmt::Debug for PrettyString<'a> {
 [0m
 "#)]
 fn assert_eq_empty_first() {
-    assert_eq!(PrettyString(""), PrettyString("foo"));
+    pretty_assertions::assert_eq!(PrettyString(""), PrettyString("foo"));
 }