rust-pretty-assertions icon indicating copy to clipboard operation
rust-pretty-assertions copied to clipboard

API Request: Add support for compare between value and reference to value, i.e. `assert_eq!(1, &1)`

Open Sajjon opened this issue 9 months ago • 4 comments

assert_eq! and assert_ne! macros would be even more convenient to use if they supported (&T, T) (and (T, &T)) comparision - which is not something std assert_eq! supports, I know, but pretty_assertions is better than std!

I naively wrote this:

#[macro_export]
macro_rules! expect_eq {
    ($left:expr, $right:expr$(,)?) => ({
        $crate::expect_eq!(@ $left, $right, "", "");
    });
    ($left:expr, $right:expr, $($arg:tt)*) => ({
        $crate::expect_eq!(@ $left, $right, ": ", $($arg)+);
    });
    (@ $left:expr, $right:expr, $maybe_colon:expr, $($arg:tt)*) => ({
        fn test<T: std::cmp::PartialEq + std::fmt::Debug>(
            left_val: impl std::borrow::Borrow<T>,
            right_val: impl std::borrow::Borrow<T>
        ) {
            let lhs = left_val.borrow();
            let rhs = right_val.borrow();
            pretty_assertions::assert_eq!(lhs, rhs);
        }
        test($left, $right);
    });
}

which makes these test compile (and pass...):


#[cfg(test)]
mod tests {

    #[derive(Debug, PartialEq)]
    struct Foo(u8);

    #[test]
    fn val_val() {
        expect_eq!(1, 1);
        expect_eq!(Foo(1), Foo(1));
    }

    #[test]
    fn val_ref() {
        expect_eq!(1, &1);
        expect_eq!(Foo(1), &Foo(1));
    }

    #[test]
    fn ref_val() {
        expect_eq!(&1, 1);
        expect_eq!(&Foo(1), Foo(1));
    }
}

Unfortunately (&T, &T) does not work with that... i.e. expect_eq!(&1, &1); does not compile. Hopefully some smarter person than me can fix that. And then it would be cool if pretty_assertions were to adopt it!

WDYT?

Sajjon avatar Feb 25 '25 15:02 Sajjon