diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 1efe56756edde..8ffdc9ab16893 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -125,6 +125,34 @@ macro_rules! assert_eq( }) ) +/// Asserts that two expressions are equivalent to each other, testing equality in +/// both directions. +/// +/// On failure, this macro will print the values of the expressions. +/// +/// # Example +/// +/// ``` +/// let a = 3; +/// let b = 1 + 2; +/// assert_equiv!(a, b); +/// ``` +#[macro_export] +macro_rules! assert_equiv( + ($given:expr , $expected:expr) => ({ + match (&($given), &($expected)) { + (given_val, expected_val) => { + // check both directions of equality.... + if !(given_val.equiv(expected_val) && + expected_val.equiv(given_val)) { + fail!("assertion failed: `left.equiv(right) && right.equiv(left)` \ + (left: `{}`, right: `{}`)", *given_val, *expected_val) + } + } + } + }) +) + /// Ensure that a boolean expression is `true` at runtime. /// /// This will invoke the `fail!` macro if the provided expression cannot be diff --git a/src/libstd/strbuf.rs b/src/libstd/strbuf.rs index 75008745cf38d..44980320f695f 100644 --- a/src/libstd/strbuf.rs +++ b/src/libstd/strbuf.rs @@ -12,6 +12,7 @@ use c_vec::CVec; use char::Char; +use cmp::Equiv; use container::{Container, Mutable}; use fmt; use io::Writer; @@ -238,6 +239,13 @@ impl StrBuf { } } +impl Equiv for StrBuf { + #[inline] + fn equiv(&self, other: &S) -> bool { + self.as_slice() == other.as_slice() + } +} + impl Container for StrBuf { #[inline] fn len(&self) -> uint { @@ -305,6 +313,7 @@ impl ::hash::Hash for StrBuf { #[cfg(test)] mod tests { extern crate test; + use cmp::Equiv; use container::{Container, Mutable}; use self::test::Bencher; use str::{Str, StrSlice}; @@ -332,18 +341,18 @@ mod tests { unsafe { s.push_bytes([ 'D' as u8 ]); } - assert_eq!(s.as_slice(), "ABCD"); + assert_equiv!(s, "ABCD"); } #[test] fn test_push_str() { let mut s = StrBuf::new(); s.push_str(""); - assert_eq!(s.as_slice().slice_from(0), ""); + assert_equiv!(s, ""); s.push_str("abc"); - assert_eq!(s.as_slice().slice_from(0), "abc"); + assert_equiv!(s, "abc"); s.push_str("ประเทศไทย中华Việt Nam"); - assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam"); + assert_equiv!(s, "abcประเทศไทย中华Việt Nam"); } #[test] @@ -354,18 +363,18 @@ mod tests { data.push_char('¢'); // 2 byte data.push_char('€'); // 3 byte data.push_char('𤭢'); // 4 byte - assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢"); + assert_equiv!(data, "ประเทศไทย中华b¢€𤭢"); } #[test] fn test_str_truncate() { let mut s = StrBuf::from_str("12345"); s.truncate(5); - assert_eq!(s.as_slice(), "12345"); + assert_equiv!(s, "12345"); s.truncate(3); - assert_eq!(s.as_slice(), "123"); + assert_equiv!(s, "123"); s.truncate(0); - assert_eq!(s.as_slice(), ""); + assert_equiv!(s, ""); let mut s = StrBuf::from_str("12345"); let p = s.as_slice().as_ptr();