From eedf13a4d9222f131fe2f943331afd343a2d3a59 Mon Sep 17 00:00:00 2001 From: haraldmaida Date: Fri, 13 Jun 2025 10:38:14 +0200 Subject: [PATCH] feat: implement `Not` expectation combinator and revise failure messages --- src/bigdecimal/tests.rs | 4 +- src/boolean/mod.rs | 32 ++++-- src/boolean/tests.rs | 14 ++- src/char/mod.rs | 225 +++++++++++++++++++++++++++++--------- src/char/tests.rs | 60 +++++----- src/char_count.rs | 66 +++++++++-- src/colored/tests.rs | 2 +- src/equality.rs | 34 +++--- src/error/mod.rs | 55 ++++++---- src/error/tests.rs | 16 +-- src/expectations.rs | 124 +++++++++------------ src/float/mod.rs | 62 +++-------- src/float/tests.rs | 58 +++++----- src/integer/tests.rs | 22 ++-- src/iterator/mod.rs | 115 +++++++++++++++---- src/length.rs | 115 +++++++++++++------ src/lib.rs | 14 +-- src/map/mod.rs | 199 ++++++++++++++++++--------------- src/map/tests.rs | 100 +++++++++-------- src/num_bigint/tests.rs | 4 +- src/number.rs | 213 +++++++++++++++++++++++------------- src/option/mod.rs | 46 ++++---- src/option/tests.rs | 28 +++-- src/order/mod.rs | 101 ++++++++++++++--- src/order/tests.rs | 50 +++++---- src/panic/mod.rs | 2 + src/panic/tests.rs | 4 +- src/predicate/mod.rs | 14 ++- src/prelude.rs | 1 + src/range/mod.rs | 133 +++++++++++----------- src/range/tests.rs | 40 +++---- src/result/mod.rs | 60 +++++----- src/result/tests.rs | 24 ++-- src/rust_decimal/tests.rs | 2 +- src/slice/tests.rs | 60 +++++----- src/spec/mod.rs | 33 ++++-- src/spec/tests.rs | 22 ++-- src/string/mod.rs | 185 +++++++++++++++++++++++++------ src/string/tests.rs | 66 +++++------ src/vec/tests.rs | 34 +++--- 40 files changed, 1508 insertions(+), 931 deletions(-) diff --git a/src/bigdecimal/tests.rs b/src/bigdecimal/tests.rs index d59d2a0..8f4e80d 100644 --- a/src/bigdecimal/tests.rs +++ b/src/bigdecimal/tests.rs @@ -27,7 +27,7 @@ fn verify_bigdecimal_is_equal_to_other_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is equal to BigDecimal(sign=Minus, scale=3, digits=[42831]) + r"assertion failed: expected subject to be equal to BigDecimal(sign=Minus, scale=3, digits=[42831]) but was: BigDecimal(sign=Plus, scale=3, digits=[42831]) expected: BigDecimal(sign=Minus, scale=3, digits=[42831]) " @@ -181,7 +181,7 @@ fn verify_bigdecimalref_is_equal_to_other_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is equal to BigDecimalRef { sign: Minus, digits: 42831, scale: 3 } + r"assertion failed: expected subject to be equal to BigDecimalRef { sign: Minus, digits: 42831, scale: 3 } but was: BigDecimalRef { sign: Plus, digits: 42831, scale: 3 } expected: BigDecimalRef { sign: Minus, digits: 42831, scale: 3 } " diff --git a/src/boolean/mod.rs b/src/boolean/mod.rs index 5d2bc0a..aaed486 100644 --- a/src/boolean/mod.rs +++ b/src/boolean/mod.rs @@ -3,7 +3,7 @@ use crate::assertions::AssertBoolean; use crate::colored::{mark_missing, mark_unexpected}; use crate::expectations::{IsFalse, IsTrue}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::format; use crate::std::string::String; @@ -25,30 +25,46 @@ impl Expectation for IsTrue { *subject } - fn message(&self, expression: &Expression<'_>, actual: &bool, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&true, format); + fn message( + &self, + expression: &Expression<'_>, + actual: &bool, + inverted: bool, + format: &DiffFormat, + ) -> String { + let marked_actual = mark_unexpected(&actual, format); + let marked_expected = mark_missing(&!inverted, format); format!( - "expected {expression} is {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to be {:?}\n but was: {marked_actual}\n expected: {marked_expected}", true ) } } +impl Invertible for IsTrue {} + impl Expectation for IsFalse { fn test(&mut self, subject: &bool) -> bool { !*subject } - fn message(&self, expression: &Expression<'_>, actual: &bool, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &bool, + inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&false, format); + let marked_expected = mark_missing(&inverted, format); format!( - "expected {expression} is {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to be {:?}\n but was: {marked_actual}\n expected: {marked_expected}", false ) } } +impl Invertible for IsFalse {} + #[cfg(test)] mod tests; diff --git a/src/boolean/tests.rs b/src/boolean/tests.rs index 47f042d..e9d15c7 100644 --- a/src/boolean/tests.rs +++ b/src/boolean/tests.rs @@ -23,10 +23,12 @@ fn verify_bool_is_not_equal_to_false_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is not equal to false + &[ + r"assertion failed: expected my_thing to be not equal to false but was: false expected: not false -"] +" + ] ); } @@ -47,7 +49,7 @@ fn verify_bool_is_true_fails() { .named("my_thing") .is_true() .display_failures(), - &[r"assertion failed: expected my_thing is true + &[r"assertion failed: expected my_thing to be true but was: false expected: true "] @@ -63,7 +65,7 @@ fn verify_bool_is_false_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is false + &[r"assertion failed: expected my_thing to be false but was: true expected: false "] @@ -83,7 +85,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is true\n \ + &["assertion failed: expected subject to be true\n \ but was: \u{1b}[31mfalse\u{1b}[0m\n \ expected: \u{1b}[32mtrue\u{1b}[0m\n\ "] @@ -99,7 +101,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is false\n \ + &["assertion failed: expected subject to be false\n \ but was: \u{1b}[31mtrue\u{1b}[0m\n \ expected: \u{1b}[33mfalse\u{1b}[0m\n\ "] diff --git a/src/char/mod.rs b/src/char/mod.rs index 44069ee..58141c4 100644 --- a/src/char/mod.rs +++ b/src/char/mod.rs @@ -4,7 +4,7 @@ use crate::expectations::{ IsAlphabetic, IsAlphanumeric, IsAscii, IsControlChar, IsDigit, IsLowerCase, IsUpperCase, IsWhitespace, }; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::format; use crate::std::string::{String, ToString}; @@ -87,22 +87,39 @@ impl Expectation for IsLowerCase { subject.is_lowercase() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", actual.to_uppercase().to_string()) + } else { + ("", actual.to_lowercase().to_string()) + }; let marked_actual = mark_unexpected_char(*actual, format); - let marked_expected = mark_missing_substr(&actual.to_lowercase().to_string(), format); - format!("expected {expression} is lowercase\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(&expected, format); + format!("expected {expression} to be {not}lowercase\n but was: {marked_actual}\n expected: {marked_expected}") } } +impl Invertible for IsLowerCase {} + impl Expectation<&char> for IsLowerCase { fn test(&mut self, subject: &&char) -> bool { - subject.is_lowercase() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - let marked_expected = mark_missing_substr(&actual.to_lowercase().to_string(), format); - format!("expected {expression} is lowercase\n but was: {marked_actual}\n expected: {marked_expected}") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -111,22 +128,39 @@ impl Expectation for IsUpperCase { subject.is_uppercase() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", actual.to_lowercase().to_string()) + } else { + ("", actual.to_uppercase().to_string()) + }; let marked_actual = mark_unexpected_char(*actual, format); - let marked_expected = mark_missing_substr(&actual.to_uppercase().to_string(), format); - format!("expected {expression} is uppercase\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(&expected, format); + format!("expected {expression} to be {not}uppercase\n but was: {marked_actual}\n expected: {marked_expected}") } } +impl Invertible for IsUpperCase {} + impl Expectation<&char> for IsUpperCase { fn test(&mut self, subject: &&char) -> bool { - subject.is_uppercase() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - let marked_expected = mark_missing_substr(&actual.to_uppercase().to_string(), format); - format!("expected {expression} is uppercase\n but was: {marked_actual}\n expected: {marked_expected}") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -135,20 +169,34 @@ impl Expectation for IsAscii { subject.is_ascii() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is an ASCII character\n but was: {marked_actual}\n expected: an ASCII character") + format!("expected {expression} to be {not}an ASCII character\n but was: {marked_actual}\n expected: {not}an ASCII character") } } +impl Invertible for IsAscii {} + impl Expectation<&char> for IsAscii { fn test(&mut self, subject: &&char) -> bool { - subject.is_ascii() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is an ASCII character\n but was: {marked_actual}\n expected: an ASCII character") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -157,20 +205,34 @@ impl Expectation for IsAlphabetic { subject.is_alphabetic() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is an alphabetic character\n but was: {marked_actual}\n expected: an alphabetic character") + format!("expected {expression} to be {not}an alphabetic character\n but was: {marked_actual}\n expected: {not}an alphabetic character") } } +impl Invertible for IsAlphabetic {} + impl Expectation<&char> for IsAlphabetic { fn test(&mut self, subject: &&char) -> bool { - subject.is_alphabetic() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is an alphabetic character\n but was: {marked_actual}\n expected: an alphabetic character") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -179,20 +241,34 @@ impl Expectation for IsAlphanumeric { subject.is_alphanumeric() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is an alphanumeric character\n but was: {marked_actual}\n expected: an alphanumeric character") + format!("expected {expression} to be {not}an alphanumeric character\n but was: {marked_actual}\n expected: {not}an alphanumeric character") } } +impl Invertible for IsAlphanumeric {} + impl Expectation<&char> for IsAlphanumeric { fn test(&mut self, subject: &&char) -> bool { - subject.is_alphanumeric() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is an alphanumeric character\n but was: {marked_actual}\n expected: an alphanumeric character") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -201,20 +277,34 @@ impl Expectation for IsControlChar { subject.is_control() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is a control character\n but was: {marked_actual}\n expected: a control character") + format!("expected {expression} to be {not}a control character\n but was: {marked_actual}\n expected: {not}a control character") } } +impl Invertible for IsControlChar {} + impl Expectation<&char> for IsControlChar { fn test(&mut self, subject: &&char) -> bool { - subject.is_control() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is a control character\n but was: {marked_actual}\n expected: a control character") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -223,22 +313,35 @@ impl Expectation for IsDigit { subject.is_digit(self.radix) } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let radix = self.radix; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is a digit in the radix {radix}\n but was: {marked_actual}\n expected: a digit in the radix {radix}") + format!("expected {expression} to be {not}a digit in the radix {radix}\n but was: {marked_actual}\n expected: {not}a digit in the radix {radix}") } } +impl Invertible for IsDigit {} + impl Expectation<&char> for IsDigit { fn test(&mut self, subject: &&char) -> bool { - subject.is_digit(self.radix) + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let radix = self.radix; - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is a digit in the radix {radix}\n but was: {marked_actual}\n expected: a digit in the radix {radix}") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } @@ -247,20 +350,34 @@ impl Expectation for IsWhitespace { subject.is_whitespace() } - fn message(&self, expression: &Expression<'_>, actual: &char, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &char, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_char(*actual, format); - format!("expected {expression} is a whitespace\n but was: {marked_actual}\n expected: a whitespace") + format!("expected {expression} to be {not}whitespace\n but was: {marked_actual}\n expected: {not}whitespace") } } +impl Invertible for IsWhitespace {} + impl Expectation<&char> for IsWhitespace { fn test(&mut self, subject: &&char) -> bool { - subject.is_whitespace() + >::test(self, subject) } - fn message(&self, expression: &Expression<'_>, actual: &&char, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected_char(**actual, format); - format!("expected {expression} is a whitespace\n but was: {marked_actual}\n expected: a whitespace") + fn message( + &self, + expression: &Expression<'_>, + actual: &&char, + inverted: bool, + format: &DiffFormat, + ) -> String { + >::message(self, expression, actual, inverted, format) } } diff --git a/src/char/tests.rs b/src/char/tests.rs index fc4f71d..1ef7fef 100644 --- a/src/char/tests.rs +++ b/src/char/tests.rs @@ -13,7 +13,7 @@ fn verify_char_is_lowercase_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is lowercase + &[r"assertion failed: expected subject to be lowercase but was: M expected: m "] @@ -31,7 +31,7 @@ fn verify_borrowed_char_is_lowercase_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is lowercase + &[r"assertion failed: expected subject to be lowercase but was: M expected: m "] @@ -49,7 +49,7 @@ fn verify_char_is_uppercase_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is uppercase + &[r"assertion failed: expected subject to be uppercase but was: k expected: K "] @@ -67,7 +67,7 @@ fn verify_borrowed_char_is_uppercase_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is uppercase + &[r"assertion failed: expected subject to be uppercase but was: x expected: X "] @@ -85,10 +85,12 @@ fn verify_char_is_ascii_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is an ASCII character + &[ + r"assertion failed: expected subject to be an ASCII character but was: € expected: an ASCII character -"] +" + ] ); } @@ -103,10 +105,12 @@ fn verify_borrowed_char_is_ascii_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is an ASCII character + &[ + r"assertion failed: expected subject to be an ASCII character but was: ❤ expected: an ASCII character -"] +" + ] ); } @@ -122,7 +126,7 @@ fn verify_char_is_alphabetic_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is an alphabetic character + r"assertion failed: expected subject to be an alphabetic character but was: 1 expected: an alphabetic character " @@ -142,7 +146,7 @@ fn verify_borrowed_char_is_alphabetic_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is an alphabetic character + r"assertion failed: expected subject to be an alphabetic character but was: @ expected: an alphabetic character " @@ -163,7 +167,7 @@ fn verify_char_is_alphanumeric_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is an alphanumeric character + r"assertion failed: expected subject to be an alphanumeric character but was: @ expected: an alphanumeric character " @@ -184,7 +188,7 @@ fn verify_borrowed_char_is_alphanumeric_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is an alphanumeric character + r"assertion failed: expected subject to be an alphanumeric character but was: + expected: an alphanumeric character " @@ -203,10 +207,12 @@ fn verify_char_is_control_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is a control character + &[ + r"assertion failed: expected subject to be a control character but was: [ expected: a control character -"] +" + ] ); } @@ -221,10 +227,12 @@ fn verify_borrowed_char_is_control_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is a control character + &[ + r"assertion failed: expected subject to be a control character but was: @ expected: a control character -"] +" + ] ); } @@ -240,7 +248,7 @@ fn verify_char_is_digit_in_radix_10_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 10 + r"assertion failed: expected subject to be a digit in the radix 10 but was: A expected: a digit in the radix 10 " @@ -260,7 +268,7 @@ fn verify_borrowed_char_is_digit_in_radix_10_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 10 + r"assertion failed: expected subject to be a digit in the radix 10 but was: F expected: a digit in the radix 10 " @@ -280,7 +288,7 @@ fn verify_char_is_digit_in_radix_16_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 16 + r"assertion failed: expected subject to be a digit in the radix 16 but was: G expected: a digit in the radix 16 " @@ -300,7 +308,7 @@ fn verify_borrowed_char_is_digit_in_radix_16_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 16 + r"assertion failed: expected subject to be a digit in the radix 16 but was: g expected: a digit in the radix 16 " @@ -320,7 +328,7 @@ fn verify_char_is_digit_in_radix_7_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 7 + r"assertion failed: expected subject to be a digit in the radix 7 but was: 7 expected: a digit in the radix 7 " @@ -340,7 +348,7 @@ fn verify_borrowed_char_is_digit_in_radix_7_fails() { assert_eq!( failures, &[ - r"assertion failed: expected subject is a digit in the radix 7 + r"assertion failed: expected subject to be a digit in the radix 7 but was: 9 expected: a digit in the radix 7 " @@ -359,9 +367,9 @@ fn verify_char_is_whitespace_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is a whitespace + &[r"assertion failed: expected subject to be whitespace but was: _ - expected: a whitespace + expected: whitespace "] ); } @@ -377,9 +385,9 @@ fn verify_borrowed_char_is_whitespace_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is a whitespace + &[r"assertion failed: expected subject to be whitespace but was: = - expected: a whitespace + expected: whitespace "] ); } diff --git a/src/char_count.rs b/src/char_count.rs index 04cee98..6539ac5 100644 --- a/src/char_count.rs +++ b/src/char_count.rs @@ -64,11 +64,18 @@ where subject.char_count_property() == self.expected_char_count } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not in " } else { "" }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_char_count, format); format!( - "expected {expression} has a char count of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}have a char count of {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected_char_count ) } @@ -83,11 +90,18 @@ where self.expected_range.contains(&subject.char_count_property()) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not in " } else { "" }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_range, format); format!( - "expected {expression} has a char count of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}have a char count within {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected_range, ) } @@ -101,11 +115,18 @@ where subject.char_count_property() < self.expected_char_count } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">=") } else { ("", "<") }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_char_count, format); format!( - "expected {expression} has a char count less than {:?}\n but was: {marked_actual}\n expected: < {marked_expected}", + "expected {expression} to {not}have a char count less than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_char_count, ) } @@ -119,11 +140,18 @@ where subject.char_count_property() > self.expected_char_count } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<=") } else { ("", ">") }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_char_count, format); format!( - "expected {expression} has a char count greater than {:?}\n but was: {marked_actual}\n expected: > {marked_expected}", + "expected {expression} to {not}have a char count greater than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_char_count, ) } @@ -137,11 +165,18 @@ where subject.char_count_property() <= self.expected_char_count } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">") } else { ("", "<=") }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_char_count, format); format!( - "expected {expression} has at most a char count of {:?}\n but was: {marked_actual}\n expected: <= {marked_expected}", + "expected {expression} to {not}have at most a char count of {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_char_count, ) } @@ -155,11 +190,18 @@ where subject.char_count_property() >= self.expected_char_count } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<") } else { ("", ">=") }; let marked_actual = mark_unexpected(&actual.char_count_property(), format); let marked_expected = mark_missing(&self.expected_char_count, format); format!( - "expected {expression} has at least a char count of {:?}\n but was: {marked_actual}\n expected: >= {marked_expected}", + "expected {expression} to {not}have at least a char count of {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_char_count, ) } diff --git a/src/colored/tests.rs b/src/colored/tests.rs index 6ffb2d2..d43fcae 100644 --- a/src/colored/tests.rs +++ b/src/colored/tests.rs @@ -59,7 +59,7 @@ mod with_colored_feature { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject is equal to Some(Foo { lorem: \"Hello World!\", ipsum: 42, dolor: Some(\"hey ho!\") })\n \ + "assertion failed: expected subject to be equal to Some(Foo { lorem: \"Hello World!\", ipsum: 42, dolor: Some(\"hey ho!\") })\n \ but was: Some(Foo { lorem: \"\u{1b}[31m¡\u{1b}[0mH\u{1b}[31mo\u{1b}[0ml\u{1b}[31ma,\u{1b}[0m W\u{1b}[31me\u{1b}[0ml\u{1b}[31mt\u{1b}[0m!\", ipsum: 42, dolor: Some(\"hey\") })\n \ expected: Some(Foo { lorem: \"H\u{1b}[32me\u{1b}[0ml\u{1b}[32mlo\u{1b}[0m W\u{1b}[32mor\u{1b}[0ml\u{1b}[32md\u{1b}[0m!\", ipsum: 42, dolor: Some(\"hey\u{1b}[32m ho!\u{1b}[0m\") })\n\ ", diff --git a/src/equality.rs b/src/equality.rs index 6e5eaf5..aa6e995 100644 --- a/src/equality.rs +++ b/src/equality.rs @@ -2,8 +2,8 @@ use crate::assertions::AssertEquality; use crate::colored::mark_diff; -use crate::expectations::{IsEqualTo, IsNotEqualTo}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::expectations::{IsEqualTo, Not}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::{format, string::String}; @@ -18,7 +18,7 @@ where } fn is_not_equal_to(self, expected: E) -> Self { - self.expecting(IsNotEqualTo { expected }) + self.expecting(Not(IsEqualTo { expected })) } } @@ -31,28 +31,20 @@ where subject == &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected = &self.expected; let (marked_actual, marked_expected) = mark_diff(actual, expected, format); format!( - "expected {expression} is equal to {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to be {not}equal to {expected:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", ) } } -impl Expectation for IsNotEqualTo -where - S: PartialEq + Debug, - E: Debug, -{ - fn test(&mut self, subject: &S) -> bool { - subject != &self.expected - } - - fn message(&self, expression: &Expression<'_>, actual: &S, _format: &DiffFormat) -> String { - format!( - "expected {expression} is not equal to {:?}\n but was: {actual:?}\n expected: not {:?}", - &self.expected, &self.expected - ) - } -} +impl Invertible for IsEqualTo {} diff --git a/src/error/mod.rs b/src/error/mod.rs index 36e2f45..3d751d3 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -1,7 +1,7 @@ use crate::assertions::AssertErrorHasSource; use crate::colored::{mark_missing, mark_missing_substr, mark_unexpected, mark_unexpected_substr}; -use crate::expectations::{ErrorHasNoSource, ErrorHasSource, ErrorHasSourceMessage}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::expectations::{ErrorHasSource, ErrorHasSourceMessage, Not}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::error::Error; use crate::std::format; use crate::std::string::{String, ToString}; @@ -12,7 +12,7 @@ where R: FailingStrategy, { fn has_no_source(self) -> Self { - self.expecting(ErrorHasNoSource) + self.expecting(Not(ErrorHasSource)) } fn has_source(self) -> Self { @@ -31,21 +31,6 @@ where } } -impl Expectation for ErrorHasNoSource -where - S: Error, -{ - fn test(&mut self, subject: &S) -> bool { - subject.source().is_none() - } - - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("", format); - format!("expected {expression} has no source\n but was: {marked_actual}\n expected: {marked_expected}") - } -} - impl Expectation for ErrorHasSource where S: Error, @@ -54,13 +39,26 @@ where subject.source().is_some() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (a, expected) = if inverted { + ("no", "") + } else { + ("a", "") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("", format); - format!("expected {expression} has a source\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to have {a} source\n but was: {marked_actual}\n expected: {marked_expected}") } } +impl Invertible for ErrorHasSource {} + impl Expectation for ErrorHasSourceMessage where S: Error, @@ -71,20 +69,29 @@ where .is_some_and(|msg| msg.to_string() == self.expected_source_message) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected = &self.expected_source_message; if let Some(actual_source) = actual.source() { let marked_actual = mark_unexpected_substr(&actual_source.to_string(), format); let marked_expected = mark_missing_substr(expected, format); - format!("expected {expression} has source message \"{expected}\"\n but was: \"{marked_actual}\"\n expected: \"{marked_expected}\"") + format!("expected {expression} to have a source message {not}equal to \"{expected}\"\n but was: \"{marked_actual}\"\n expected: \"{marked_expected}\"") } else { let mut marked_actual = mark_unexpected(actual, format); marked_actual.push_str(" - which has no source"); let marked_expected = mark_missing(expected, format); - format!("expected {expression} has source message \"{expected}\"\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to have a source message {not}equal to \"{expected}\"\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } } +impl Invertible for ErrorHasSourceMessage {} + #[cfg(test)] mod tests; diff --git a/src/error/tests.rs b/src/error/tests.rs index 4ac9a57..580ed92 100644 --- a/src/error/tests.rs +++ b/src/error/tests.rs @@ -57,7 +57,7 @@ fn verify_error_has_no_source_fails() { assert_eq!( failures, - &[r"assertion failed: expected my error has no source + &[r"assertion failed: expected my error to have no source but was: SuperError { source: Foo } expected: "] @@ -84,7 +84,7 @@ fn verify_error_has_source_fails() { assert_eq!( failures, - &[r"assertion failed: expected my error has a source + &[r"assertion failed: expected my error to have a source but was: Bar expected: "] @@ -114,7 +114,7 @@ fn verify_error_has_source_message_fails_wrong_source() { assert_eq!( failures, &[ - r#"assertion failed: expected my error has source message "foo error" + r#"assertion failed: expected my error to have a source message equal to "foo error" but was: "bar error" expected: "foo error" "# @@ -134,7 +134,7 @@ fn verify_error_has_source_message_fails_error_without_source() { assert_eq!( failures, &[ - r#"assertion failed: expected my error has source message "foo error" + r#"assertion failed: expected my error to have a source message equal to "foo error" but was: Foo - which has no source expected: "foo error" "# @@ -172,7 +172,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject has no source\n \ + &["assertion failed: expected subject to have no source\n \ but was: \u{1b}[31mSuperError { source: Foo }\u{1b}[0m\n \ expected: \u{1b}[33m\u{1b}[0m\n\ "] @@ -190,7 +190,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject has a source\n \ + &["assertion failed: expected subject to have a source\n \ but was: \u{1b}[31mFoo\u{1b}[0m\n \ expected: \u{1b}[33m\u{1b}[0m\n\ "] @@ -211,7 +211,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject has source message \"foo error\"\n \ + "assertion failed: expected subject to have a source message equal to \"foo error\"\n \ but was: \"\u{1b}[31mbar error\u{1b}[0m\"\n \ expected: \"\u{1b}[33mfoo error\u{1b}[0m\"\n\ " @@ -231,7 +231,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject has source message \"foo error\"\n \ + "assertion failed: expected subject to have a source message equal to \"foo error\"\n \ but was: \u{1b}[31mFoo\u{1b}[0m - which has no source\n \ expected: \u{1b}[33m\"foo error\"\u{1b}[0m\n\ " diff --git a/src/expectations.rs b/src/expectations.rs index 9664765..ea682d9 100644 --- a/src/expectations.rs +++ b/src/expectations.rs @@ -7,6 +7,32 @@ use crate::std::marker::PhantomData; use crate::std::{string::String, vec::Vec}; use hashbrown::HashSet; +/// Combinator for expectations that inverts the contained expectation. +/// +/// This combinator can only be used with expectations that implement the +/// [`Invertible`] trait (additional to the [`Expectation`] trait). +/// +/// Most of the expectations provided by this crate do implement the +/// [`Invertible`] trait and thus can be used with the [`Not`] combinator. +/// +/// # Examples +/// +/// ``` +/// use asserting::expectations::{HasLength, IsEmpty, IsEqualTo, IsNegative, StringContains}; +/// use asserting::prelude::*; +/// +/// assert_that!(41).expecting(Not(IsEqualTo { expected: 42 })); +/// assert_that!([1, 2, 3]).expecting(Not(IsEmpty)); +/// assert_that!(37.9).expecting(Not(IsNegative)); +/// assert_that!([1, 2, 3]).expecting(Not(HasLength { expected_length: 4 })); +/// assert_that!("almost").expecting(Not(StringContains { expected: "entire" })); +/// ``` +/// +/// [`Expectation`]: crate::spec::Expectation +/// [`Invertible`]: crate::spec::Invertible +#[must_use] +pub struct Not(pub E); + #[must_use] pub struct Predicate { pub predicate: F, @@ -24,11 +50,6 @@ pub struct IsEqualTo { pub expected: E, } -#[must_use] -pub struct IsNotEqualTo { - pub expected: E, -} - #[must_use] pub struct IsCloseTo { pub expected: E, @@ -54,31 +75,6 @@ impl IsCloseTo { } } -#[must_use] -pub struct IsNotCloseTo { - pub expected: E, - pub margin: M, -} - -impl IsNotCloseTo -where - M: Default, -{ - pub fn new(expected: E) -> Self { - Self { - expected, - margin: M::default(), - } - } -} - -impl IsNotCloseTo { - pub fn within_margin(mut self, margin: impl Into) -> Self { - self.margin = margin.into(); - self - } -} - #[must_use] pub struct IsLessThan { pub expected: E, @@ -130,33 +126,12 @@ impl IsInRange { } } -#[must_use] -pub struct IsNotInRange { - pub expected_range: R, - _element_type: PhantomData, -} - -impl IsNotInRange { - pub fn new(expected_range: R) -> Self { - Self { - expected_range, - _element_type: PhantomData, - } - } -} - #[must_use] pub struct IsNegative; -#[must_use] -pub struct IsNotNegative; - #[must_use] pub struct IsPositive; -#[must_use] -pub struct IsNotPositive; - #[must_use] pub struct IsZero; @@ -169,9 +144,6 @@ pub struct IsFinite; #[must_use] pub struct IsInfinite; -#[must_use] -pub struct IsNotANumber; - #[must_use] pub struct IsANumber; @@ -197,9 +169,6 @@ pub struct IsUpperCase; #[must_use] pub struct IsAscii; -#[must_use] -pub struct IsNonAscii; - #[must_use] pub struct IsAlphabetic; @@ -239,9 +208,6 @@ pub struct HasError { pub expected: E, } -#[must_use] -pub struct ErrorHasNoSource; - #[must_use] pub struct ErrorHasSource; @@ -253,9 +219,6 @@ pub struct ErrorHasSourceMessage { #[must_use] pub struct IsEmpty; -#[must_use] -pub struct IsNotEmpty; - #[must_use] pub struct HasLength { pub expected_length: E, @@ -544,21 +507,11 @@ pub struct MapContainsKey { pub expected_key: E, } -#[must_use] -pub struct MapDoesNotContainKey { - pub expected_key: E, -} - #[must_use] pub struct MapContainsValue { pub expected_value: E, } -#[must_use] -pub struct MapDoesNotContainValue { - pub expected_value: E, -} - #[must_use] pub struct MapContainsKeys { pub expected_keys: Vec, @@ -672,3 +625,28 @@ mod panic { pub actual_message: Option>, } } + +mod combinators { + use crate::expectations::Not; + use crate::spec::{DiffFormat, Expectation, Expression, Invertible}; + use crate::std::string::String; + + impl Expectation for Not + where + E: Invertible + Expectation, + { + fn test(&mut self, subject: &S) -> bool { + !self.0.test(subject) + } + + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + self.0.message(expression, actual, !inverted, format) + } + } +} diff --git a/src/float/mod.rs b/src/float/mod.rs index e6a5107..022d15e 100644 --- a/src/float/mod.rs +++ b/src/float/mod.rs @@ -97,8 +97,8 @@ impl IsNanProperty for f64 { mod cmp { use crate::assertions::{AssertIsCloseToWithDefaultMargin, AssertIsCloseToWithinMargin}; use crate::colored::mark_diff; - use crate::expectations::{IsCloseTo, IsNotCloseTo}; - use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; + use crate::expectations::{IsCloseTo, Not}; + use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::{format, string::String}; use float_cmp::{ApproxEq, F32Margin, F64Margin}; @@ -113,9 +113,9 @@ mod cmp { } fn is_not_close_to(self, expected: f32) -> Self { - self.expecting( - IsNotCloseTo::<_, F32Margin>::new(expected).within_margin((4. * f32::EPSILON, 4)), - ) + self.expecting(Not( + IsCloseTo::<_, F32Margin>::new(expected).within_margin((4. * f32::EPSILON, 4)) + )) } } @@ -128,7 +128,7 @@ mod cmp { } fn is_not_close_to_with_margin(self, expected: f32, margin: impl Into) -> Self { - self.expecting(IsNotCloseTo::new(expected).within_margin(margin)) + self.expecting(Not(IsCloseTo::new(expected).within_margin(margin))) } } @@ -143,9 +143,9 @@ mod cmp { } fn is_not_close_to(self, expected: f64) -> Self { - self.expecting( - IsNotCloseTo::<_, F64Margin>::new(expected).within_margin((4. * f64::EPSILON, 4)), - ) + self.expecting(Not( + IsCloseTo::<_, F64Margin>::new(expected).within_margin((4. * f64::EPSILON, 4)) + )) } } @@ -158,7 +158,7 @@ mod cmp { } fn is_not_close_to_with_margin(self, expected: f64, margin: impl Into) -> Self { - self.expecting(IsNotCloseTo::new(expected).within_margin(margin)) + self.expecting(Not(IsCloseTo::new(expected).within_margin(margin))) } } @@ -171,31 +171,18 @@ mod cmp { &self, expression: &Expression<'_>, actual: &f32, + inverted: bool, format: &DiffFormat, ) -> String { + let not = if inverted { "not " } else { "" }; let (marked_actual, marked_expected) = mark_diff(actual, &self.expected, format); - format!("expected {expression} is close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {marked_actual}\n expected: {marked_expected}", + format!("expected {expression} to be {not}close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {marked_actual}\n expected: {marked_expected}", &self.expected, self.margin.epsilon, self.margin.ulps ) } } - impl Expectation for IsNotCloseTo { - fn test(&mut self, subject: &f32) -> bool { - !subject.approx_eq(self.expected, self.margin) - } - - fn message( - &self, - expression: &Expression<'_>, - actual: &f32, - _format: &DiffFormat, - ) -> String { - format!("expected {expression} is not close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {actual:?}\n expected: {:?}", - &self.expected, self.margin.epsilon, self.margin.ulps, &self.expected - ) - } - } + impl Invertible for IsCloseTo {} impl Expectation for IsCloseTo { fn test(&mut self, subject: &f64) -> bool { @@ -206,31 +193,18 @@ mod cmp { &self, expression: &Expression<'_>, actual: &f64, + inverted: bool, format: &DiffFormat, ) -> String { + let not = if inverted { "not " } else { "" }; let (marked_actual, marked_expected) = mark_diff(actual, &self.expected, format); - format!("expected {expression} is close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {marked_actual}\n expected: {marked_expected}", + format!("expected {expression} to be {not}close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {marked_actual}\n expected: {marked_expected}", &self.expected, self.margin.epsilon, self.margin.ulps ) } } - impl Expectation for IsNotCloseTo { - fn test(&mut self, subject: &f64) -> bool { - !subject.approx_eq(self.expected, self.margin) - } - - fn message( - &self, - expression: &Expression<'_>, - actual: &f64, - _format: &DiffFormat, - ) -> String { - format!("expected {expression} is not close to {:?}\n within a margin of epsilon={:e} and ulps={}\n but was: {actual:?}\n expected: {:?}", - &self.expected, self.margin.epsilon, self.margin.ulps, &self.expected - ) - } - } + impl Invertible for IsCloseTo {} } #[cfg(test)] diff --git a/src/float/tests.rs b/src/float/tests.rs index 24477d6..326a2f2 100644 --- a/src/float/tests.rs +++ b/src/float/tests.rs @@ -35,7 +35,7 @@ fn verify_f64_is_negative_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is negative + &[r"assertion failed: expected some_number to be negative but was: 0.0 expected: < 0 "] @@ -79,7 +79,7 @@ fn verify_f64_is_not_negative_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is not negative + &[r"assertion failed: expected some_number to be not negative but was: -0.001 expected: >= 0 "] @@ -119,7 +119,7 @@ fn verify_f64_is_positive_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is positive + &[r"assertion failed: expected some_number to be positive but was: 0.0 expected: > 0 "] @@ -163,7 +163,7 @@ fn verify_f64_is_not_positive_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is not positive + &[r"assertion failed: expected some_number to be not positive but was: 0.001 expected: <= 0 "] @@ -199,7 +199,7 @@ fn verify_f64_is_zero_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is zero + &[r"assertion failed: expected some_number to be zero but was: 1.0 expected: 0.0 "] @@ -235,7 +235,7 @@ fn verify_f64_is_one_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is one + &[r"assertion failed: expected some_number to be one but was: 0.0 expected: 1.0 "] @@ -285,7 +285,7 @@ fn verify_f64_is_finite_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is finite + &[r"assertion failed: expected some_number to be finite but was: -inf expected: a finite number "] @@ -320,7 +320,7 @@ fn verify_f64_is_infinite_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is infinite + &[r"assertion failed: expected some_number to be infinite but was: 0.0 expected: an infinite number "] @@ -374,7 +374,7 @@ fn verify_f64_is_a_number_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is a number + &[r"assertion failed: expected some_number to be a number but was: NaN expected: a number "] @@ -395,12 +395,10 @@ fn verify_f32_is_not_a_number_fails() { assert_eq!( failures, - &[ - r"assertion failed: expected some_number is not a number (NaN) + &[r"assertion failed: expected some_number to be not a number but was: 0.0 expected: NaN -" - ] +"] ); } @@ -429,12 +427,10 @@ fn verify_f64_is_not_a_number_fails() { assert_eq!( failures, - &[ - r"assertion failed: expected some_number is not a number (NaN) + &[r"assertion failed: expected some_number to be not a number but was: 0.0 expected: NaN -" - ] +"] ); } @@ -456,7 +452,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is close to 3.15 + &[r"assertion failed: expected tau / 2 to be close to 3.15 within a margin of epsilon=4.7683716e-7 and ulps=4 but was: 3.14 expected: 3.15 @@ -478,7 +474,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is not close to 3.14 + &[r"assertion failed: expected tau / 2 to be not close to 3.14 within a margin of epsilon=4.7683716e-7 and ulps=4 but was: 3.14 expected: 3.14 @@ -500,7 +496,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is close to 3.15 + &[r"assertion failed: expected tau / 2 to be close to 3.15 within a margin of epsilon=2.3841858e-7 and ulps=3 but was: 3.14 expected: 3.15 @@ -522,7 +518,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is not close to 3.14 + &[r"assertion failed: expected tau / 2 to be not close to 3.14 within a margin of epsilon=2.3841858e-7 and ulps=3 but was: 3.14 expected: 3.14 @@ -544,7 +540,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is close to 3.15 + &[r"assertion failed: expected tau / 2 to be close to 3.15 within a margin of epsilon=8.881784197001252e-16 and ulps=4 but was: 3.14 expected: 3.15 @@ -566,7 +562,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is not close to 3.14 + &[r"assertion failed: expected tau / 2 to be not close to 3.14 within a margin of epsilon=8.881784197001252e-16 and ulps=4 but was: 3.14 expected: 3.14 @@ -588,7 +584,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is close to 3.15 + &[r"assertion failed: expected tau / 2 to be close to 3.15 within a margin of epsilon=4.440892098500626e-16 and ulps=3 but was: 3.14 expected: 3.15 @@ -610,7 +606,7 @@ mod cmp { assert_eq!( failures, - &[r"assertion failed: expected tau / 2 is not close to 3.14 + &[r"assertion failed: expected tau / 2 to be not close to 3.14 within a margin of epsilon=4.440892098500626e-16 and ulps=3 but was: 3.14 expected: 3.14 @@ -631,11 +627,13 @@ mod cmp { assert_eq!( failures, - &["assertion failed: expected subject is close to 3.15148\n \ + &[ + "assertion failed: expected subject to be close to 3.15148\n \ within a margin of epsilon=2.3841858e-7 and ulps=3\n \ but was: 3.1\u{1b}[31m41\u{1b}[0m5\u{1b}[31m9\u{1b}[0m\n \ expected: 3.15\u{1b}[34m148\u{1b}[0m\n\ - "] + " + ] ); } @@ -648,11 +646,13 @@ mod cmp { assert_eq!( failures, - &["assertion failed: expected subject is close to 3.15148\n \ + &[ + "assertion failed: expected subject to be close to 3.15148\n \ within a margin of epsilon=4.440892098500626e-16 and ulps=3\n \ but was: 3.1\u{1b}[31m41\u{1b}[0m5\u{1b}[31m9\u{1b}[0m\n \ expected: 3.15\u{1b}[34m148\u{1b}[0m\n\ - "] + " + ] ); } } diff --git a/src/integer/tests.rs b/src/integer/tests.rs index 5b04e3f..6c87666 100644 --- a/src/integer/tests.rs +++ b/src/integer/tests.rs @@ -37,7 +37,7 @@ fn verify_i32_is_equal_to_i32_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is equal to -42 + &[r"assertion failed: expected my_thing to be equal to -42 but was: 42 expected: -42 "] @@ -101,7 +101,7 @@ fn verify_i32_is_negative_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is negative + &[r"assertion failed: expected some_number to be negative but was: 0 expected: < 0 "] @@ -173,7 +173,7 @@ fn verify_i32_is_not_negative_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is not negative + &[r"assertion failed: expected some_number to be not negative but was: -1 expected: >= 0 "] @@ -237,7 +237,7 @@ fn verify_i32_is_positive_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is positive + &[r"assertion failed: expected some_number to be positive but was: 0 expected: > 0 "] @@ -309,7 +309,7 @@ fn verify_i32_is_not_positive_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is not positive + &[r"assertion failed: expected some_number to be not positive but was: 1 expected: <= 0 "] @@ -390,7 +390,7 @@ fn verify_u64_is_zero_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is zero + &[r"assertion failed: expected some_number to be zero but was: 1 expected: 0 "] @@ -471,7 +471,7 @@ fn verify_u64_is_one_fails() { assert_eq!( failures, - &[r"assertion failed: expected some_number is one + &[r"assertion failed: expected some_number to be one but was: 0 expected: 1 "] @@ -491,7 +491,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is equal to 42\n \ + &["assertion failed: expected subject to be equal to 42\n \ but was: \u{1b}[31m37\u{1b}[0m\n \ expected: \u{1b}[34m42\u{1b}[0m\n\ "] @@ -507,10 +507,12 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is not equal to 42\n \ + &[ + "assertion failed: expected subject to be not equal to 42\n \ but was: 42\n \ expected: not 42\n\ - "] + " + ] ); } } diff --git a/src/iterator/mod.rs b/src/iterator/mod.rs index 1f03262..9e005b8 100644 --- a/src/iterator/mod.rs +++ b/src/iterator/mod.rs @@ -12,7 +12,7 @@ use crate::expectations::{ IterContainsSequence, IterEndsWith, IterStartsWith, }; use crate::properties::DefinedOrderProperty; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::cmp::Ordering; use crate::std::fmt::Debug; use crate::std::mem; @@ -41,16 +41,25 @@ where subject.iter().any(|e| e == &self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_all_items_in_collection(actual, format, mark_unexpected); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} to contain {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}contain {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", &self.expected, ) } } +impl Invertible for IterContains {} + impl<'a, S, T, E, R> AssertIteratorContainsInAnyOrder<'a, Vec, E, R> for Spec<'a, S, R> where S: IntoIterator, @@ -112,7 +121,13 @@ where extra.is_empty() && missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let missing = collect_selected_values(&self.missing, &self.expected); let extra = collect_selected_values(&self.extra, actual); let marked_actual = @@ -121,7 +136,7 @@ where mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing); format!( - r"expected {expression} contains exactly in any order {:?} + r"expected {expression} to contain exactly in any order {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?} @@ -145,11 +160,17 @@ where false } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_all_items_in_collection(actual, format, mark_unexpected); let marked_expected = mark_all_items_in_collection(&self.expected, format, mark_missing); format!( - r"expected {expression} contains any of {:?} + r"expected {expression} to contain any of {:?} but was: {marked_actual} expected: {marked_expected}", &self.expected, @@ -174,7 +195,13 @@ where missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let mut extra = HashSet::new(); for (actual_index, actual) in actual.iter().enumerate() { if !self.expected.iter().any(|expected| actual == expected) { @@ -188,7 +215,7 @@ where let missing = collect_selected_values(&self.missing, &self.expected); format!( - r"expected {expression} contains all of {:?} + r"expected {expression} to contain all of {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?}", @@ -214,7 +241,13 @@ where extra.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let mut missing = HashSet::new(); for (expected_index, expected) in self.expected.iter().enumerate() { if !actual.iter().any(|value| value == expected) { @@ -228,7 +261,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} contains only {:?} + r"expected {expression} to contain only {:?} but was: {marked_actual} expected: {marked_expected} extra: {extra:?}", @@ -259,7 +292,13 @@ where duplicates.is_empty() && extra.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let actual_duplicates_and_extras = self.duplicates.union(&self.extra).copied().collect(); let marked_actual = mark_selected_items_in_collection( actual, @@ -285,7 +324,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} contains only once {:?} + r"expected {expression} to contain only once {:?} but was: {marked_actual} expected: {marked_expected} extra: {extra:?} @@ -378,7 +417,13 @@ where out_of_order.is_empty() && extra.is_empty() && missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let out_of_order = collect_selected_values(&self.out_of_order, actual); let mut expected_indices = self.missing.clone(); for (expected_index, expected) in self.expected.iter().enumerate() { @@ -400,7 +445,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} contains exactly in order {:?} + r"expected {expression} to contain exactly in order {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?} @@ -477,7 +522,13 @@ where false } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected); let marked_expected = @@ -486,7 +537,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} contains sequence {:?} + r"expected {expression} to contain the sequence {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?} @@ -519,13 +570,19 @@ where missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let marked_expected = mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing); let missing = collect_selected_values(&self.missing, &self.expected); format!( - r"expected {expression} contains all of {:?} in order + r"expected {expression} to contain all of {:?} in order but was: {actual:?} expected: {marked_expected} missing: {missing:?}", @@ -562,7 +619,13 @@ where extra.is_empty() && missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected); let marked_expected = @@ -571,7 +634,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} starts with {:?} + r"expected {expression} to start with {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?} @@ -609,7 +672,13 @@ where extra.is_empty() && missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &Vec, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &Vec, + _inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected); let marked_expected = @@ -618,7 +687,7 @@ where let extra = collect_selected_values(&self.extra, actual); format!( - r"expected {expression} ends with {:?} + r"expected {expression} to end with {:?} but was: {marked_actual} expected: {marked_expected} missing: {missing:?} diff --git a/src/length.rs b/src/length.rs index 83e0975..176090f 100644 --- a/src/length.rs +++ b/src/length.rs @@ -4,10 +4,10 @@ use crate::assertions::{AssertEmptiness, AssertHasLength}; use crate::colored::{mark_missing, mark_unexpected}; use crate::expectations::{ HasAtLeastLength, HasAtMostLength, HasLength, HasLengthGreaterThan, HasLengthInRange, - HasLengthLessThan, IsEmpty, IsNotEmpty, + HasLengthLessThan, IsEmpty, Not, }; use crate::properties::{IsEmptyProperty, LengthProperty}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::ops::RangeBounds; use crate::std::{format, string::String}; @@ -22,7 +22,7 @@ where } fn is_not_empty(self) -> Self { - self.expecting(IsNotEmpty) + self.expecting(Not(IsEmpty)) } } @@ -34,27 +34,24 @@ where subject.is_empty_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "") + } else { + ("", "") + }; let marked_actual = mark_unexpected(actual, format); - format!("expected {expression} is empty\n but was: {marked_actual}\n expected: ") + format!("expected {expression} to be {not}empty\n but was: {marked_actual}\n expected: {expected}") } } -impl Expectation for IsNotEmpty -where - S: IsEmptyProperty + Debug, -{ - fn test(&mut self, subject: &S) -> bool { - !subject.is_empty_property() - } - - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - format!( - "expected {expression} is not empty\n but was: {marked_actual}\n expected: ", - ) - } -} +impl Invertible for IsEmpty {} impl AssertHasLength for Spec<'_, S, R> where @@ -97,16 +94,25 @@ where subject.length_property() == self.expected_length } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_length, format); format!( - "expected {expression} has length {}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}have a length of {}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected_length, ) } } +impl Invertible for HasLength {} + impl Expectation for HasLengthInRange where S: LengthProperty + Debug, @@ -116,16 +122,25 @@ where self.expected_range.contains(&subject.length_property()) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_range, format); format!( - "expected {expression} has length in range {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}have a length within range {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected_range, ) } } +impl Invertible for HasLengthInRange {} + impl Expectation for HasLengthLessThan where S: LengthProperty + Debug, @@ -134,16 +149,25 @@ where subject.length_property() < self.expected_length } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">=") } else { ("", "<") }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_length, format); format!( - "expected {expression} has a length less than {:?}\n but was: {marked_actual}\n expected: < {marked_expected}", + "expected {expression} to {not}have a length less than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_length, ) } } +impl Invertible for HasLengthLessThan {} + impl Expectation for HasLengthGreaterThan where S: LengthProperty + Debug, @@ -152,16 +176,25 @@ where subject.length_property() > self.expected_length } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<=") } else { ("", ">") }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_length, format); format!( - "expected {expression} has a length greater than {:?}\n but was: {marked_actual}\n expected: > {marked_expected}", + "expected {expression} to {not}have a length greater than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_length, ) } } +impl Invertible for HasLengthGreaterThan {} + impl Expectation for HasAtMostLength where S: LengthProperty + Debug, @@ -170,16 +203,25 @@ where subject.length_property() <= self.expected_length } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">") } else { ("", "<=") }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_length, format); format!( - "expected {expression} has at most a length of {:?}\n but was: {marked_actual}\n expected: <= {marked_expected}", + "expected {expression} to {not}have at most a length of {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_length, ) } } +impl Invertible for HasAtMostLength {} + impl Expectation for HasAtLeastLength where S: LengthProperty + Debug, @@ -188,12 +230,21 @@ where subject.length_property() >= self.expected_length } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<") } else { ("", ">=") }; let marked_actual = mark_unexpected(&actual.length_property(), format); let marked_expected = mark_missing(&self.expected_length, format); format!( - "expected {expression} has at least a length of {:?}\n but was: {marked_actual}\n expected: >= {marked_expected}", + "expected {expression} to {not}have at least a length of {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected_length, ) } } + +impl Invertible for HasAtLeastLength {} diff --git a/src/lib.rs b/src/lib.rs index 35c8536..9e8b4f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ //! will print the error message: //! //! ```console -//! assertion failed: expected 6 * 8 - 5 is equal to 42 +//! assertion failed: expected 6 * 8 - 5 to be equal to 42 //! but was: 43 //! expected: 42 //! ``` @@ -153,7 +153,7 @@ //! but was: "the answer to all important questions is 42" //! expected: "unimportant" //! -//! assertion failed: expected subject has at most a length of 41 +//! assertion failed: expected subject to have at most a length of 41 //! but was: 43 //! expected: <= 41 //! ``` @@ -319,7 +319,7 @@ //! let failures = verify_that!(7 * 5).is_equal_to(42).display_failures(); //! //! assert_that!(failures).contains_exactly([ -//! r"assertion failed: expected 7 * 5 is equal to 42 +//! r"assertion failed: expected 7 * 5 to be equal to 42 //! but was: 35 //! expected: 42 //! " @@ -424,7 +424,7 @@ //! } //! } //! -//! fn message(&self, expression: &Expression<'_>, actual: &Either, _format: &DiffFormat) -> String { +//! fn message(&self, expression: &Expression<'_>, actual: &Either, _inverted: bool, _format: &DiffFormat) -> String { //! format!( //! "expected {expression} is {:?}\n but was: {actual:?}\n expected: {:?}", //! Either::Left::<_, Unknown>(Unknown), @@ -461,7 +461,7 @@ //! # } //! # } //! # -//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _format: &DiffFormat) -> String { +//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _inverted: bool, _format: &DiffFormat) -> String { //! # format!( //! # "expected {expression} is {:?}\n but was: {actual:?}\n expected: {:?}", //! # Either::Left::<_, Unknown>(Unknown), @@ -508,7 +508,7 @@ //! # } //! # } //! # -//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _format: &DiffFormat) -> String { +//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _inverted: bool, _format: &DiffFormat) -> String { //! # format!( //! # "expected {expression} is {:?}\n but was: {actual:?}\n expected: {:?}", //! # Either::Left::<_, Unknown>(Unknown), @@ -562,7 +562,7 @@ //! # } //! # } //! # -//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _format: &DiffFormat) -> String { +//! # fn message(&self, expression: &Expression<'_>, actual: &Either, _inverted: bool, _format: &DiffFormat) -> String { //! # format!( //! # "expected {expression} is {:?}\n but was: {actual:?}\n expected: {:?}", //! # Either::Left::<_, Unknown>(Unknown), diff --git a/src/map/mod.rs b/src/map/mod.rs index 896b3b0..d31e578 100644 --- a/src/map/mod.rs +++ b/src/map/mod.rs @@ -5,11 +5,11 @@ use crate::colored::{ }; use crate::expectations::{ MapContainsExactlyKeys, MapContainsKey, MapContainsKeys, MapContainsValue, MapContainsValues, - MapDoesNotContainKey, MapDoesNotContainKeys, MapDoesNotContainValue, MapDoesNotContainValues, + MapDoesNotContainKeys, MapDoesNotContainValues, Not, }; use crate::iterator::collect_selected_values; use crate::properties::MapProperties; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::format; use crate::std::string::String; @@ -29,7 +29,7 @@ where } fn does_not_contain_key(self, expected_key: E) -> Self { - self.expecting(MapDoesNotContainKey { expected_key }) + self.expecting(Not(MapContainsKey { expected_key })) } fn contains_keys(self, expected_keys: impl IntoIterator) -> Self { @@ -56,50 +56,45 @@ where subject.keys_property().any(|k| k == &self.expected_key) } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + inverted: bool, + format: &DiffFormat, + ) -> String { let expected_key = &self.expected_key; let actual_entries: Vec<_> = actual.entries_property().collect(); - let marked_actual = - mark_all_entries_in_map(&actual_entries, format, mark_unexpected_substr); + let (not, marked_actual) = if inverted { + let found: HashSet = actual_entries + .iter() + .enumerate() + .filter_map(|(index, (k, _))| { + if *k == &self.expected_key { + Some(index) + } else { + None + } + }) + .collect(); + let selected_entries_marked = mark_selected_entries_in_map( + &actual_entries, + &found, + format, + mark_unexpected_substr, + ); + ("not ", selected_entries_marked) + } else { + let all_entries_marked = + mark_all_entries_in_map(&actual_entries, format, mark_unexpected_substr); + ("", all_entries_marked) + }; let marked_expected = mark_missing(&self.expected_key, format); - - format!("expected {expression} contains key {expected_key:?}\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to {not}contain the key {expected_key:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } -impl Expectation for MapDoesNotContainKey -where - M: MapProperties, - ::Key: PartialEq + Debug, - ::Value: Debug, - E: Debug, -{ - fn test(&mut self, subject: &M) -> bool { - subject.keys_property().all(|k| k != &self.expected_key) - } - - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { - let expected_key = &self.expected_key; - let actual_entries: Vec<_> = actual.entries_property().collect(); - let found: HashSet = actual_entries - .iter() - .enumerate() - .filter_map(|(index, (k, _))| { - if *k == &self.expected_key { - Some(index) - } else { - None - } - }) - .collect(); - - let marked_actual = - mark_selected_entries_in_map(&actual_entries, &found, format, mark_unexpected_substr); - let marked_expected = mark_missing(&self.expected_key, format); - - format!("expected {expression} does not contain key {expected_key:?}\n but was: {marked_actual}\n expected: {marked_expected}") - } -} +impl Invertible for MapContainsKey {} impl Expectation for MapContainsKeys where @@ -119,7 +114,13 @@ where missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + _inverted: bool, + format: &DiffFormat, + ) -> String { let expected_keys = &self.expected_keys; let missing = &self.missing; let actual_entries: Vec<_> = actual.entries_property().collect(); @@ -143,7 +144,7 @@ where let missing_keys = collect_selected_values(missing, expected_keys); format!( - r"expected {expression} contains keys {expected_keys:?} + r"expected {expression} to contain the keys {expected_keys:?} but was: {marked_actual} expected: {marked_expected} missing: {missing_keys:?}" @@ -169,7 +170,13 @@ where extra.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + _inverted: bool, + format: &DiffFormat, + ) -> String { let expected_keys = &self.expected_keys; let extra = &self.extra; let actual_entries: Vec<_> = actual.entries_property().collect(); @@ -187,7 +194,7 @@ where let extra_keys = collect_selected_values(&found, &actual_keys); format!( - r"expected {expression} does not contain keys {expected_keys:?} + r"expected {expression} to not contain the keys {expected_keys:?} but was: {marked_actual} expected: {marked_expected} extra: {extra_keys:?}" @@ -218,7 +225,13 @@ where missing.is_empty() && extra.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + _inverted: bool, + format: &DiffFormat, + ) -> String { let expected_keys = &self.expected_keys; let missing = &self.missing; let extra = &self.extra; @@ -233,7 +246,7 @@ where let extra_keys = collect_selected_values(extra, &actual_keys); format!( - r"expected {expression} contains exactly the keys {expected_keys:?} + r"expected {expression} to contain exactly the keys {expected_keys:?} but was: {marked_actual} expected: {marked_expected} missing: {missing_keys:?} @@ -255,7 +268,7 @@ where } fn does_not_contain_value(self, expected_value: E) -> Self { - self.expecting(MapDoesNotContainValue { expected_value }) + self.expecting(Not(MapContainsValue { expected_value })) } fn contains_values(self, expected_values: impl IntoIterator) -> Self { @@ -278,50 +291,46 @@ where subject.values_property().any(|v| v == &self.expected_value) } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + inverted: bool, + format: &DiffFormat, + ) -> String { let expected_value = &self.expected_value; let actual_entries: Vec<_> = actual.entries_property().collect(); - let marked_actual = - mark_all_entries_in_map(&actual_entries, format, mark_unexpected_substr); + let (not, marked_actual) = if inverted { + let found: HashSet = actual_entries + .iter() + .enumerate() + .filter_map(|(index, (_, v))| { + if *v == &self.expected_value { + Some(index) + } else { + None + } + }) + .collect(); + let selected_entries_marked = mark_selected_entries_in_map( + &actual_entries, + &found, + format, + mark_unexpected_substr, + ); + ("not ", selected_entries_marked) + } else { + let all_entries_marked = + mark_all_entries_in_map(&actual_entries, format, mark_unexpected_substr); + ("", all_entries_marked) + }; let marked_expected = mark_missing(&self.expected_value, format); - format!("expected {expression} contains value {expected_value:?}\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to {not}contain the value {expected_value:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } -impl Expectation for MapDoesNotContainValue -where - M: MapProperties, - ::Key: Debug, - ::Value: PartialEq + Debug, - E: Debug, -{ - fn test(&mut self, subject: &M) -> bool { - subject.values_property().all(|v| v != &self.expected_value) - } - - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { - let expected_value = &self.expected_value; - let actual_entries: Vec<_> = actual.entries_property().collect(); - let found: HashSet = actual_entries - .iter() - .enumerate() - .filter_map(|(index, (_, v))| { - if *v == &self.expected_value { - Some(index) - } else { - None - } - }) - .collect(); - - let marked_actual = - mark_selected_entries_in_map(&actual_entries, &found, format, mark_unexpected_substr); - let marked_expected = mark_missing(&self.expected_value, format); - - format!("expected {expression} does not contain value {expected_value:?}\n but was: {marked_actual}\n expected: {marked_expected}") - } -} +impl Invertible for MapContainsValue {} impl Expectation for MapContainsValues where @@ -341,7 +350,13 @@ where missing.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + _inverted: bool, + format: &DiffFormat, + ) -> String { let expected_values = &self.expected_values; let missing = &self.missing; let actual_entries: Vec<_> = actual.entries_property().collect(); @@ -365,7 +380,7 @@ where let missing_values = collect_selected_values(missing, expected_values); format!( - r"expected {expression} contains values {expected_values:?} + r"expected {expression} to contain the values {expected_values:?} but was: {marked_actual} expected: {marked_expected} missing: {missing_values:?}" @@ -391,7 +406,13 @@ where extra.is_empty() } - fn message(&self, expression: &Expression<'_>, actual: &M, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &M, + _inverted: bool, + format: &DiffFormat, + ) -> String { let expected_values = &self.expected_values; let extra = &self.extra; let actual_entries: Vec<_> = actual.entries_property().collect(); @@ -412,7 +433,7 @@ where let extra_values = collect_selected_values(&found, &actual_values); format!( - r"expected {expression} does not contain values {expected_values:?} + r"expected {expression} to not contain the values {expected_values:?} but was: {marked_actual} expected: {marked_expected} extra: {extra_values:?}" diff --git a/src/map/tests.rs b/src/map/tests.rs index 2711ddf..b857d0d 100644 --- a/src/map/tests.rs +++ b/src/map/tests.rs @@ -88,7 +88,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains key 7 + r"assertion failed: expected foo_map to contain the key 7 but was: {formatted_actual} expected: 7 " @@ -116,9 +116,9 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map does not contain key 5 + r"assertion failed: expected foo_map to not contain the key 5 but was: {formatted_actual} - expected: 5 + expected: not 5 " )] ); @@ -158,7 +158,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map contains value "six" + r#"assertion failed: expected foo_map to contain the value "six" but was: {formatted_actual} expected: "six" "# @@ -186,9 +186,9 @@ mod hashbrown { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map does not contain value "five" + r#"assertion failed: expected foo_map to not contain the value "five" but was: {formatted_actual} - expected: "five" + expected: not "five" "# )] ); @@ -214,7 +214,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 4] + r"assertion failed: expected foo_map to contain the keys [5, 3, 4] but was: {formatted_actual} expected: [5, 3, 4] missing: [3] @@ -236,7 +236,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 4] + r"assertion failed: expected foo_map to contain the keys [5, 3, 4] but was: {formatted_actual} expected: [5, 3, 4] missing: [3] @@ -258,7 +258,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 4] + r"assertion failed: expected foo_map to contain the keys [5, 3, 4] but was: {formatted_actual} expected: [5, 3, 4] missing: [3] @@ -287,7 +287,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map contains values ["one", "two", "three"] + r#"assertion failed: expected foo_map to contain the values ["one", "two", "three"] but was: {formatted_actual} expected: ["one", "two", "three"] missing: ["two", "three"] @@ -323,7 +323,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map does not contain keys [5, 3, 4] + r"assertion failed: expected foo_map to not contain the keys [5, 3, 4] but was: {formatted_actual} expected: [5, 3, 4] extra: {formatted_extra} @@ -352,7 +352,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map does not contain values ["one", "two", "three"] + r#"assertion failed: expected foo_map to not contain the values ["one", "two", "three"] but was: {formatted_actual} expected: ["one", "two", "three"] extra: ["one"] @@ -388,7 +388,7 @@ mod hashbrown { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains exactly the keys [5, 2, 6, 3] + r"assertion failed: expected foo_map to contain exactly the keys [5, 2, 6, 3] but was: {formatted_actual} expected: [5, 2, 6, 3] missing: [2, 3] @@ -489,7 +489,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains key 7 + r"assertion failed: expected foo_map to contain the key 7 but was: {formatted_actual} expected: 7 " @@ -517,9 +517,9 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map does not contain key 4 + r"assertion failed: expected foo_map to not contain the key 4 but was: {formatted_actual} - expected: 4 + expected: not 4 " )] ); @@ -559,7 +559,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map contains value "six" + r#"assertion failed: expected foo_map to contain the value "six" but was: {formatted_actual} expected: "six" "# @@ -587,9 +587,9 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map does not contain value "four" + r#"assertion failed: expected foo_map to not contain the value "four" but was: {formatted_actual} - expected: "four" + expected: not "four" "# )] ); @@ -615,7 +615,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [2, 3, 5] + r"assertion failed: expected foo_map to contain the keys [2, 3, 5] but was: {formatted_actual} expected: [2, 3, 5] missing: [2, 3] @@ -637,7 +637,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [2, 3, 5] + r"assertion failed: expected foo_map to contain the keys [2, 3, 5] but was: {formatted_actual} expected: [2, 3, 5] missing: [2, 3] @@ -659,7 +659,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [2, 3, 5] + r"assertion failed: expected foo_map to contain the keys [2, 3, 5] but was: {formatted_actual} expected: [2, 3, 5] missing: [2, 3] @@ -688,7 +688,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map contains values ["one", "two", "three"] + r#"assertion failed: expected foo_map to contain the values ["one", "two", "three"] but was: {formatted_actual} expected: ["one", "two", "three"] missing: ["two", "three"] @@ -717,7 +717,7 @@ mod std_hash_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains exactly the keys [4, 5, 6, 3] + r"assertion failed: expected foo_map to contain exactly the keys [4, 5, 6, 3] but was: {formatted_actual} expected: [4, 5, 6, 3] missing: [3] @@ -816,7 +816,7 @@ mod btree_map { assert_eq!( failures, - &[r#"assertion failed: expected foo_map contains key 7 + &[r#"assertion failed: expected foo_map to contain the key 7 but was: {1: "one", 4: "four", 5: "five"} expected: 7 "#] @@ -841,10 +841,12 @@ mod btree_map { assert_eq!( failures, - &[r#"assertion failed: expected foo_map does not contain key 1 + &[ + r#"assertion failed: expected foo_map to not contain the key 1 but was: {1: "one", 4: "four", 5: "five"} - expected: 1 -"#] + expected: not 1 +"# + ] ); } @@ -880,10 +882,12 @@ mod btree_map { assert_eq!( failures, - &[r#"assertion failed: expected foo_map contains value "six" + &[ + r#"assertion failed: expected foo_map to contain the value "six" but was: {1: "one", 4: "four", 5: "five"} expected: "six" -"#] +"# + ] ); } @@ -906,9 +910,9 @@ mod btree_map { assert_eq!( failures, &[ - r#"assertion failed: expected foo_map does not contain value "one" + r#"assertion failed: expected foo_map to not contain the value "one" but was: {1: "one", 4: "four", 5: "five"} - expected: "one" + expected: not "one" "# ] ); @@ -934,7 +938,7 @@ mod btree_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 7] + r"assertion failed: expected foo_map to contain the keys [5, 3, 7] but was: {formatted_actual} expected: [5, 3, 7] missing: [3, 7] @@ -956,7 +960,7 @@ mod btree_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 7] + r"assertion failed: expected foo_map to contain the keys [5, 3, 7] but was: {formatted_actual} expected: [5, 3, 7] missing: [3, 7] @@ -978,7 +982,7 @@ mod btree_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains keys [5, 3, 7] + r"assertion failed: expected foo_map to contain the keys [5, 3, 7] but was: {formatted_actual} expected: [5, 3, 7] missing: [3, 7] @@ -1007,7 +1011,7 @@ mod btree_map { assert_eq!( failures, &[format!( - r#"assertion failed: expected foo_map contains values ["one", "two", "three"] + r#"assertion failed: expected foo_map to contain the values ["one", "two", "three"] but was: {formatted_actual} expected: ["one", "two", "three"] missing: ["two", "three"] @@ -1043,7 +1047,7 @@ mod btree_map { assert_eq!( failures, &[format!( - r"assertion failed: expected foo_map contains exactly the keys [5, 2, 6, 3] + r"assertion failed: expected foo_map to contain exactly the keys [5, 2, 6, 3] but was: {formatted_actual} expected: [5, 2, 6, 3] missing: [2, 3] @@ -1079,7 +1083,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map contains key 2\n \ + "assertion failed: expected foo_map to contain the key 2\n \ but was: {formatted_actual}\n \ expected: \u{1b}[32m2\u{1b}[0m\n\ " @@ -1102,9 +1106,9 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map does not contain key 1\n \ + "assertion failed: expected foo_map to not contain the key 1\n \ but was: {formatted_actual}\n \ - expected: \u{1b}[32m1\u{1b}[0m\n\ + expected: not \u{1b}[32m1\u{1b}[0m\n\ " )] ); @@ -1128,7 +1132,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map contains value \"three\"\n \ + "assertion failed: expected foo_map to contain the value \"three\"\n \ but was: {formatted_actual}\n \ expected: \u{1b}[32m\"three\"\u{1b}[0m\n\ " @@ -1151,9 +1155,9 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map does not contain value \"four\"\n \ + "assertion failed: expected foo_map to not contain the value \"four\"\n \ but was: {formatted_actual}\n \ - expected: \u{1b}[32m\"four\"\u{1b}[0m\n\ + expected: not \u{1b}[32m\"four\"\u{1b}[0m\n\ " )] ); @@ -1175,7 +1179,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map contains keys [5, 2, 4, 7]\n \ + "assertion failed: expected foo_map to contain the keys [5, 2, 4, 7]\n \ but was: {formatted_actual}\n \ expected: [5, \u{1b}[32m2\u{1b}[0m, 4, \u{1b}[32m7\u{1b}[0m]\n \ missing: [2, 7]\n\ @@ -1207,7 +1211,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map does not contain keys [5, 2, 4, 7]\n \ + "assertion failed: expected foo_map to not contain the keys [5, 2, 4, 7]\n \ but was: {formatted_actual}\n \ expected: [\u{1b}[32m5\u{1b}[0m, 2, \u{1b}[32m4\u{1b}[0m, 7]\n \ extra: {formatted_extra}\n\ @@ -1232,7 +1236,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map contains values [\"five\", \"two\", \"four\", \"seven\"]\n \ + "assertion failed: expected foo_map to contain the values [\"five\", \"two\", \"four\", \"seven\"]\n \ but was: {formatted_actual}\n \ expected: [\"five\", \u{1b}[32m\"two\"\u{1b}[0m, \"four\", \u{1b}[32m\"seven\"\u{1b}[0m]\n \ missing: [\"two\", \"seven\"]\n\ @@ -1264,7 +1268,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map does not contain values [\"five\", \"two\", \"four\", \"seven\"]\n \ + "assertion failed: expected foo_map to not contain the values [\"five\", \"two\", \"four\", \"seven\"]\n \ but was: {formatted_actual}\n \ expected: [\u{1b}[32m\"five\"\u{1b}[0m, \"two\", \u{1b}[32m\"four\"\u{1b}[0m, \"seven\"]\n \ extra: {formatted_extra}\n\ @@ -1296,7 +1300,7 @@ mod colored { assert_eq!( failures, &[format!( - "assertion failed: expected foo_map contains exactly the keys [5, 2, 6, 3]\n \ + "assertion failed: expected foo_map to contain exactly the keys [5, 2, 6, 3]\n \ but was: {formatted_actual}\n \ expected: [5, \u{1b}[32m2\u{1b}[0m, 6, \u{1b}[32m3\u{1b}[0m]\n \ missing: [2, 3]\n \ diff --git a/src/num_bigint/tests.rs b/src/num_bigint/tests.rs index 9049e96..90a1801 100644 --- a/src/num_bigint/tests.rs +++ b/src/num_bigint/tests.rs @@ -18,7 +18,7 @@ fn verify_bigint_is_equal_to_other_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is equal to -42 + &[r"assertion failed: expected subject to be equal to -42 but was: 42 expected: -42 "] @@ -156,7 +156,7 @@ fn verify_biguint_is_equal_to_other_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is equal to 22 + &[r"assertion failed: expected subject to be equal to 22 but was: 42 expected: 22 "] diff --git a/src/number.rs b/src/number.rs index 88b7699..e24ccd2 100644 --- a/src/number.rs +++ b/src/number.rs @@ -5,14 +5,14 @@ use crate::assertions::{ }; use crate::colored::{mark_missing, mark_missing_substr, mark_unexpected}; use crate::expectations::{ - HasPrecisionOf, HasScaleOf, IsANumber, IsFinite, IsInfinite, IsInteger, IsNegative, - IsNotANumber, IsNotNegative, IsNotPositive, IsOne, IsPositive, IsZero, + HasPrecisionOf, HasScaleOf, IsANumber, IsFinite, IsInfinite, IsInteger, IsNegative, IsOne, + IsPositive, IsZero, Not, }; use crate::properties::{ AdditiveIdentityProperty, DecimalProperties, InfinityProperty, IsNanProperty, MultiplicativeIdentityProperty, SignumProperty, }; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::format; use crate::std::string::String; @@ -27,7 +27,7 @@ where } fn is_not_negative(self) -> Self { - self.expecting(IsNotNegative) + self.expecting(Not(IsNegative)) } fn is_positive(self) -> Self { @@ -35,7 +35,7 @@ where } fn is_not_positive(self) -> Self { - self.expecting(IsNotPositive) + self.expecting(Not(IsPositive)) } } @@ -47,27 +47,25 @@ where subject.is_negative_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", ">= 0") + } else { + ("", "< 0") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("< 0", format); - format!("expected {expression} is negative\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}negative\n but was: {marked_actual}\n expected: {marked_expected}") } } -impl Expectation for IsNotNegative -where - S: SignumProperty + Debug, -{ - fn test(&mut self, subject: &S) -> bool { - !subject.is_negative_property() - } - - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr(">= 0", format); - format!("expected {expression} is not negative\n but was: {marked_actual}\n expected: {marked_expected}") - } -} +impl Invertible for IsNegative {} impl Expectation for IsPositive where @@ -77,27 +75,25 @@ where subject.is_positive_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "<= 0") + } else { + ("", "> 0") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("> 0", format); - format!("expected {expression} is positive\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}positive\n but was: {marked_actual}\n expected: {marked_expected}") } } -impl Expectation for IsNotPositive -where - S: SignumProperty + Debug, -{ - fn test(&mut self, subject: &S) -> bool { - !subject.is_positive_property() - } - - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("<= 0", format); - format!("expected {expression} is not positive\n but was: {marked_actual}\n expected: {marked_expected}") - } -} +impl Invertible for IsPositive {} impl AssertNumericIdentity for Spec<'_, S, R> where @@ -121,13 +117,22 @@ where *subject == ::additive_identity() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(&actual, format); let marked_expected = mark_missing(&S::additive_identity(), format); - format!("expected {expression} is zero\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to be {not}zero\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } +impl Invertible for IsZero {} + impl Expectation for IsOne where S: MultiplicativeIdentityProperty + PartialEq + Debug, @@ -136,13 +141,22 @@ where *subject == ::multiplicative_identity() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&S::multiplicative_identity(), format); - format!("expected {expression} is one\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to be {not}one\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } +impl Invertible for IsOne {} + impl AssertInfinity for Spec<'_, S, R> where S: InfinityProperty + Debug, @@ -165,13 +179,26 @@ where subject.is_finite_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "a non-finite number") + } else { + ("", "a finite number") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("a finite number", format); - format!("expected {expression} is finite\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}finite\n but was: {marked_actual}\n expected: {marked_expected}") } } +impl Invertible for IsFinite {} + impl Expectation for IsInfinite where S: InfinityProperty + Debug, @@ -180,20 +207,33 @@ where subject.is_infinite_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "a non-infinite number") + } else { + ("", "an infinite number") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("an infinite number", format); - format!("expected {expression} is infinite\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}infinite\n but was: {marked_actual}\n expected: {marked_expected}") } } +impl Invertible for IsInfinite {} + impl AssertNotANumber for Spec<'_, S, R> where S: IsNanProperty + Debug, R: FailingStrategy, { fn is_not_a_number(self) -> Self { - self.expecting(IsNotANumber) + self.expecting(Not(IsANumber)) } fn is_a_number(self) -> Self { @@ -209,27 +249,25 @@ where !subject.is_nan_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "NaN") + } else { + ("", "a number") + }; let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("a number", format); - format!("expected {expression} is a number\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}a number\n but was: {marked_actual}\n expected: {marked_expected}") } } -impl Expectation for IsNotANumber -where - S: IsNanProperty + Debug, -{ - fn test(&mut self, subject: &S) -> bool { - subject.is_nan_property() - } - - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing_substr("NaN", format); - format!("expected {expression} is not a number (NaN)\n but was: {marked_actual}\n expected: {marked_expected}") - } -} +impl Invertible for IsANumber {} impl AssertDecimalNumber for Spec<'_, S, R> where @@ -257,14 +295,23 @@ where subject.scale_property() == self.expected_scale } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected_scale = self.expected_scale; let marked_actual = mark_unexpected(&actual.scale_property(), format); let marked_expected = mark_missing(&expected_scale, format); - format!("expected {expression} to have a scale of {expected_scale}\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to {not}have a scale of {expected_scale}\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } +impl Invertible for HasScaleOf {} + impl Expectation for HasPrecisionOf where S: DecimalProperties + Debug, @@ -273,11 +320,18 @@ where subject.precision_property() == self.expected_precision } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected_precision = self.expected_precision; let marked_actual = mark_unexpected(&actual.precision_property(), format); let marked_expected = mark_missing(&expected_precision, format); - format!("expected {expression} to have a precision of {expected_precision}\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to {not}have a precision of {expected_precision}\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } @@ -289,9 +343,20 @@ where subject.is_integer_property() } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, expected) = if inverted { + ("not ", "a decimal value with non-zero fraction") + } else { + ("", "an integer value") + }; let marked_actual = mark_unexpected(&actual, format); - let marked_expected = mark_missing_substr("an integer value", format); - format!("expected {expression} to be an integer value\n but was: {marked_actual}\n expected: {marked_expected}") + let marked_expected = mark_missing_substr(expected, format); + format!("expected {expression} to be {not}an integer value\n but was: {marked_actual}\n expected: {marked_expected}") } } diff --git a/src/option/mod.rs b/src/option/mod.rs index cc52e69..ee0a528 100644 --- a/src/option/mod.rs +++ b/src/option/mod.rs @@ -5,7 +5,9 @@ use crate::assertions::{ }; use crate::colored::{mark_missing, mark_unexpected}; use crate::expectations::{HasValue, IsNone, IsSome}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec, Unknown}; +use crate::spec::{ + DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec, Unknown, +}; use crate::std::fmt::Debug; use crate::std::{format, string::String}; @@ -99,13 +101,14 @@ where &self, expression: &Expression<'_>, actual: &Option, + _inverted: bool, format: &DiffFormat, ) -> String { let expected = Some(Unknown); let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&expected, format); format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" ) } } @@ -115,21 +118,17 @@ where T: Debug, { fn test(&mut self, subject: &&Option) -> bool { - subject.is_some() + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Option, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = Some(Unknown); - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&expected, format); - format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } @@ -145,13 +144,14 @@ where &self, expression: &Expression<'_>, actual: &Option, + _inverted: bool, format: &DiffFormat, ) -> String { let expected = None::; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&expected, format); format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" ) } } @@ -161,21 +161,17 @@ where T: Debug, { fn test(&mut self, subject: &&Option) -> bool { - subject.is_none() + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Option, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = None::; - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&expected, format); - format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } @@ -194,36 +190,36 @@ where &self, expression: &Expression<'_>, actual: &Option, + inverted: bool, format: &DiffFormat, ) -> String { + let not = if inverted { "not " } else { "" }; let expected = &self.expected; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&Some(expected), format); - format!("expected {expression} is some containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}") + format!("expected {expression} to be some {not}containing {expected:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}") } } +impl Invertible for HasValue {} + impl Expectation<&Option> for HasValue where T: PartialEq + Debug, E: Debug, { fn test(&mut self, subject: &&Option) -> bool { - subject - .as_ref() - .is_some_and(|value| value == &self.expected) + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Option, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = &self.expected; - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&Some(expected), format); - format!("expected {expression} is some containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}") + >>::message(self, expression, actual, inverted, format) } } diff --git a/src/option/tests.rs b/src/option/tests.rs index f73f90d..ef810dc 100644 --- a/src/option/tests.rs +++ b/src/option/tests.rs @@ -56,7 +56,7 @@ fn verify_option_of_custom_struct_is_none_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is None + &[r"assertion failed: expected my_thing to be None but was: Some(Foo) expected: None "] @@ -87,7 +87,7 @@ fn verify_option_of_custom_struct_is_some_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is Some(_) + &[r"assertion failed: expected my_thing to be Some(_) but was: None expected: Some(_) "] @@ -118,7 +118,7 @@ fn verify_borrowed_option_of_custom_struct_is_none_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is None + &[r"assertion failed: expected my_thing to be None but was: Some(Foo) expected: None "] @@ -149,7 +149,7 @@ fn verify_borrowed_option_of_custom_struct_is_some_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is Some(_) + &[r"assertion failed: expected my_thing to be Some(_) but was: None expected: Some(_) "] @@ -195,7 +195,7 @@ fn verify_option_of_string_has_some_value_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing is some containing "labore dolores voluptate culpa" + r#"assertion failed: expected my_thing to be some containing "labore dolores voluptate culpa" but was: Some("labore dolore voluptate culpa") expected: Some("labore dolores voluptate culpa") "# @@ -241,10 +241,12 @@ fn verify_option_of_custom_struct_has_value_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is some containing Foo + &[ + r"assertion failed: expected my_thing to be some containing Foo but was: None expected: Some(Foo) -"] +" + ] ); } @@ -272,10 +274,12 @@ fn verify_borrowed_option_of_custom_struct_has_value_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is some containing Foo + &[ + r"assertion failed: expected my_thing to be some containing Foo but was: None expected: Some(Foo) -"] +" + ] ); } @@ -341,7 +345,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is Some(_)\n \ + &["assertion failed: expected subject to be Some(_)\n \ but was: \u{1b}[31mNone\u{1b}[0m\n \ expected: \u{1b}[33mSome(_)\u{1b}[0m\n\ "] @@ -359,7 +363,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is None\n \ + &["assertion failed: expected subject to be None\n \ but was: \u{1b}[31mSome(3500)\u{1b}[0m\n \ expected: \u{1b}[33mNone\u{1b}[0m\n\ "] @@ -378,7 +382,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is some containing [1, 2, 3, 5, 7]\n \ + "assertion failed: expected subject to be some containing [1, 2, 3, 5, 7]\n \ but was: \u{1b}[31mNone\u{1b}[0m\n \ expected: \u{1b}[33mSome([1, 2, 3, 5, 7])\u{1b}[0m\n\ " diff --git a/src/order/mod.rs b/src/order/mod.rs index 4c15e76..d97eda0 100644 --- a/src/order/mod.rs +++ b/src/order/mod.rs @@ -5,7 +5,7 @@ use crate::colored::{mark_missing, mark_unexpected}; use crate::expectations::{ IsAfter, IsAtLeast, IsAtMost, IsBefore, IsBetween, IsGreaterThan, IsLessThan, }; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::{format, string::String}; @@ -53,16 +53,25 @@ where subject < &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">=") } else { ("", "<") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is less than {:?}\n but was: {marked_actual}\n expected: < {marked_expected}", + "expected {expression} to be {not}less than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsLessThan {} + impl Expectation for IsAtMost where S: PartialOrd + Debug, @@ -72,16 +81,25 @@ where subject <= &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">") } else { ("", "<=") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is at most {:?}\n but was: {marked_actual}\n expected: <= {marked_expected}", + "expected {expression} to be {not}at most {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsAtMost {} + impl Expectation for IsGreaterThan where S: PartialOrd + Debug, @@ -91,16 +109,25 @@ where subject > &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<=") } else { ("", ">") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is greater than {:?}\n but was: {marked_actual}\n expected: > {marked_expected}", + "expected {expression} to be {not}greater than {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsGreaterThan {} + impl Expectation for IsAtLeast where S: PartialOrd + Debug, @@ -110,16 +137,25 @@ where subject >= &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<") } else { ("", ">=") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is at least {:?}\n but was: {marked_actual}\n expected: >= {marked_expected}", + "expected {expression} to be {not}at least {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsAtLeast {} + impl Expectation for IsBefore where S: PartialOrd + Debug, @@ -129,16 +165,25 @@ where subject < &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", ">=") } else { ("", "<") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is before {:?}\n but was: {marked_actual}\n expected: < {marked_expected}", + "expected {expression} to be {not}before {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsBefore {} + impl Expectation for IsAfter where S: PartialOrd + Debug, @@ -148,16 +193,25 @@ where subject > &self.expected } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { ("not ", "<=") } else { ("", ">") }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} is after {:?}\n but was: {marked_actual}\n expected: > {marked_expected}", + "expected {expression} to be {not}after {:?}\n but was: {marked_actual}\n expected: {cmp} {marked_expected}", self.expected, ) } } +impl Invertible for IsAfter {} + impl Expectation for IsBetween where S: PartialOrd + Debug, @@ -167,24 +221,37 @@ where subject >= &self.min && subject <= &self.max } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, cmp) = if inverted { + ("not ", "> x or x >") + } else { + ("", "<= x <=") + }; let marked_actual = mark_unexpected(actual, format); - let marked_start = if actual < &self.min { + let marked_start = if (actual < &self.min) || inverted { mark_missing(&self.min, format) } else { format!("{:?}", &self.min) }; - let marked_end = if actual > &self.max { + let marked_end = if (actual > &self.max) || inverted { mark_missing(&self.max, format) } else { format!("{:?}", &self.max) }; format!( - "expected {expression} is between {:?} and {:?}\n but was: {marked_actual}\n expected: {marked_start} <= x <= {marked_end}", + "expected {expression} to be {not}between {:?} and {:?}\n but was: {marked_actual}\n expected: {marked_start} {cmp} {marked_end}", self.min, self.max ) } } +impl Invertible for IsBetween {} + #[cfg(test)] mod tests; diff --git a/src/order/tests.rs b/src/order/tests.rs index 305a9e9..7247e0b 100644 --- a/src/order/tests.rs +++ b/src/order/tests.rs @@ -22,7 +22,7 @@ fn verify_i32_is_less_than_other_i32_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is less than 42 + &[r"assertion failed: expected my_thing to be less than 42 but was: 42 expected: < 42 "] @@ -47,7 +47,7 @@ fn verify_i32_is_greater_than_other_i32_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is greater than 42 + &[r"assertion failed: expected my_thing to be greater than 42 but was: 42 expected: > 42 "] @@ -72,7 +72,7 @@ fn verify_i32_is_at_most_other_i32_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is at most 41 + &[r"assertion failed: expected my_thing to be at most 41 but was: 42 expected: <= 41 "] @@ -97,7 +97,7 @@ fn verify_i32_is_at_least_other_i32_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is at least 43 + &[r"assertion failed: expected my_thing to be at least 43 but was: 42 expected: >= 43 "] @@ -126,7 +126,7 @@ fn verify_char_is_less_than_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is less than 'C' + &[r"assertion failed: expected my_thing to be less than 'C' but was: 'C' expected: < 'C' "] @@ -151,7 +151,7 @@ fn verify_char_is_greater_than_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is greater than 'D' + &[r"assertion failed: expected my_thing to be greater than 'D' but was: 'D' expected: > 'D' "] @@ -176,7 +176,7 @@ fn verify_char_is_at_most_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is at most 'B' + &[r"assertion failed: expected my_thing to be at most 'B' but was: 'C' expected: <= 'B' "] @@ -201,7 +201,7 @@ fn verify_char_is_at_least_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is at least 'E' + &[r"assertion failed: expected my_thing to be at least 'E' but was: 'D' expected: >= 'E' "] @@ -226,7 +226,7 @@ fn verify_char_is_before_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is before 'L' + &[r"assertion failed: expected my_thing to be before 'L' but was: 'L' expected: < 'L' "] @@ -251,7 +251,7 @@ fn verify_char_is_after_other_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is after 'L' + &[r"assertion failed: expected my_thing to be after 'L' but was: 'L' expected: > 'L' "] @@ -278,10 +278,12 @@ fn verify_char_is_between_a_min_char_and_a_max_char_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is between 'M' and 'P' + &[ + r"assertion failed: expected my_thing to be between 'M' and 'P' but was: 'L' expected: 'M' <= x <= 'P' -"] +" + ] ); } @@ -300,10 +302,12 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is less than 3.779\n \ + &[ + "assertion failed: expected subject to be less than 3.779\n \ but was: \u{1b}[31m3.781\u{1b}[0m\n \ expected: < \u{1b}[32m3.779\u{1b}[0m\n\ - "] + " + ] ); } @@ -318,10 +322,12 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is at most 3.779\n \ + &[ + "assertion failed: expected subject to be at most 3.779\n \ but was: \u{1b}[31m3.781\u{1b}[0m\n \ expected: <= \u{1b}[34m3.779\u{1b}[0m\n\ - "] + " + ] ); } @@ -337,7 +343,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is greater than 3.782\n \ + "assertion failed: expected subject to be greater than 3.782\n \ but was: \u{1b}[31m3.781\u{1b}[0m\n \ expected: > \u{1b}[33m3.782\u{1b}[0m\n\ " @@ -356,10 +362,12 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is at least 3.782\n \ + &[ + "assertion failed: expected subject to be at least 3.782\n \ but was: \u{1b}[31m3.781\u{1b}[0m\n \ expected: >= \u{1b}[34m3.782\u{1b}[0m\n\ - "] + " + ] ); } @@ -375,7 +383,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is between 'M' and 'P'\n \ + "assertion failed: expected subject to be between 'M' and 'P'\n \ but was: \u{1b}[31m'L'\u{1b}[0m\n \ expected: \u{1b}[33m'M'\u{1b}[0m <= x <= 'P'\n\ " @@ -395,7 +403,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is between 'H' and 'K'\n \ + "assertion failed: expected subject to be between 'H' and 'K'\n \ but was: \u{1b}[31m'L'\u{1b}[0m\n \ expected: 'H' <= x <= \u{1b}[33m'K'\u{1b}[0m\n\ " diff --git a/src/panic/mod.rs b/src/panic/mod.rs index fd7fc5a..64d4a29 100644 --- a/src/panic/mod.rs +++ b/src/panic/mod.rs @@ -54,6 +54,7 @@ where &self, expression: &Expression<'_>, _actual: &Code, + _inverted: bool, format: &DiffFormat, ) -> String { let panic_message = read_panic_message(self.actual_message.as_ref()) @@ -103,6 +104,7 @@ where &self, expression: &Expression<'_>, _actual: &Code, + _inverted: bool, format: &DiffFormat, ) -> String { if let Some(actual_message) = self.actual_message.as_ref() { diff --git a/src/panic/tests.rs b/src/panic/tests.rs index c498cbb..fb9d033 100644 --- a/src/panic/tests.rs +++ b/src/panic/tests.rs @@ -53,7 +53,7 @@ fn code_does_panic_with_message_from_assertion() { .is_equal_to(4); }) .panics_with_message( - "assertion failed: expected subject is equal to 4\n but was: 5\n expected: 4\n", + "assertion failed: expected subject to be equal to 4\n but was: 5\n expected: 4\n", ); } @@ -117,7 +117,7 @@ fn verify_code_does_panic_with_message_fails_because_unexpected_panic_message() failures, &[ "assertion failed: expected my_closure to panic with message \"lobortis lorem aliquam ex\"\n \ - but was: \"assertion failed: expected subject is equal to 4\n but was: 5\n expected: 4\n\"\n \ + but was: \"assertion failed: expected subject to be equal to 4\n but was: 5\n expected: 4\n\"\n \ expected: \"lobortis lorem aliquam ex\"\n\ " ] diff --git a/src/predicate/mod.rs b/src/predicate/mod.rs index 6ef377d..e4aee09 100644 --- a/src/predicate/mod.rs +++ b/src/predicate/mod.rs @@ -1,7 +1,7 @@ //! Implementation of the predicate assertion. use crate::expectations::Predicate; -use crate::spec::{DiffFormat, Expectation, Expression}; +use crate::spec::{DiffFormat, Expectation, Expression, Invertible}; use crate::std::{format, string::String}; impl Expectation for Predicate

@@ -12,12 +12,20 @@ where (self.predicate)(subject) } - fn message(&self, expression: &Expression<'_>, _actual: &S, _format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + _actual: &S, + inverted: bool, + _format: &DiffFormat, + ) -> String { self.message.clone().unwrap_or_else(|| { - format!("expected {expression} to satisfy the given predicate, but returned false") + format!("expected {expression} to satisfy the given predicate, but returned {inverted}") }) } } +impl

Invertible for Predicate

{} + #[cfg(test)] mod tests; diff --git a/src/prelude.rs b/src/prelude.rs index 4257ddb..e4eda76 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -18,6 +18,7 @@ pub use super::{ assert_that, assertions::*, colored::{DEFAULT_DIFF_FORMAT, DIFF_FORMAT_NO_HIGHLIGHT}, + expectations::Not, properties::*, spec::{assert_that, verify_that, CollectFailures, Location, PanicOnFail}, verify_that, diff --git a/src/range/mod.rs b/src/range/mod.rs index 23ca489..04427c4 100644 --- a/src/range/mod.rs +++ b/src/range/mod.rs @@ -2,9 +2,9 @@ use crate::assertions::AssertInRange; use crate::colored::{mark_missing, mark_missing_substr, mark_unexpected}; -use crate::expectations::{IsInRange, IsNotInRange}; +use crate::expectations::{IsInRange, Not}; use crate::properties::IsEmptyProperty; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::format; use crate::std::ops::{Bound, Range, RangeBounds, RangeInclusive}; @@ -45,7 +45,7 @@ where where U: RangeBounds + Debug, { - self.expecting(IsNotInRange::new(range)) + self.expecting(Not(IsInRange::new(range))) } } @@ -59,77 +59,80 @@ where self.expected_range.contains(subject) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { let marked_actual = mark_unexpected(actual, format); - let marked_expected_start = match self.expected_range.start_bound() { - Bound::Included(start) => { - if actual < start { - format!("{} <=", mark_missing(start, format)) - } else { - format!("{start:?} <=") - } - }, - Bound::Excluded(start) => { - if actual <= start { - format!("{} <", mark_missing(start, format)) - } else { - format!("{start:?} <") - } - }, - Bound::Unbounded => format!("{} <", mark_missing_substr("..", format)), - }; - let marked_expected_end = match self.expected_range.end_bound() { - Bound::Included(end) => { - if actual > end { - format!("<= {}", mark_missing(end, format)) - } else { - format!("<= {end:?}") - } - }, - Bound::Excluded(end) => { - if actual >= end { - format!("< {}", mark_missing(end, format)) - } else { - format!("< {end:?}") - } - }, - Bound::Unbounded => format!("< {}", mark_missing_substr("..", format)), - }; - format!( - "expected {expression} is within range of {:?}\n but was: {marked_actual}\n expected: {marked_expected_start} x {marked_expected_end}", - self.expected_range, - ) - } -} + let (not, marked_expected) = if inverted { + let marked_expected_start = match self.expected_range.start_bound() { + Bound::Included(start) => format!("< {}", mark_missing(start, format)), + Bound::Excluded(start) => format!("<= {}", mark_missing(start, format)), + Bound::Unbounded => format!("< {}", mark_missing_substr("..", format)), + }; + let marked_expected_end = match self.expected_range.end_bound() { + Bound::Included(end) => format!("> {}", mark_missing(end, format)), + Bound::Excluded(end) => format!(">= {}", mark_missing(end, format)), + Bound::Unbounded => format!("> {}", mark_missing_substr("..", format)), + }; -impl Expectation for IsNotInRange -where - S: PartialOrd + Debug, - E: PartialOrd + Debug, - R: RangeBounds + Debug, -{ - fn test(&mut self, subject: &S) -> bool { - !self.expected_range.contains(subject) - } + ( + "not ", + format!("x {marked_expected_start} || x {marked_expected_end}"), + ) + } else { + let marked_expected_start = match self.expected_range.start_bound() { + Bound::Included(start) => { + if actual < start { + format!("{} <=", mark_missing(start, format)) + } else { + format!("{start:?} <=") + } + }, + Bound::Excluded(start) => { + if actual <= start { + format!("{} <", mark_missing(start, format)) + } else { + format!("{start:?} <") + } + }, + Bound::Unbounded => format!("{} <", mark_missing_substr("..", format)), + }; + let marked_expected_end = match self.expected_range.end_bound() { + Bound::Included(end) => { + if actual > end { + format!("<= {}", mark_missing(end, format)) + } else { + format!("<= {end:?}") + } + }, + Bound::Excluded(end) => { + if actual >= end { + format!("< {}", mark_missing(end, format)) + } else { + format!("< {end:?}") + } + }, + Bound::Unbounded => format!("< {}", mark_missing_substr("..", format)), + }; - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { - let marked_actual = mark_unexpected(actual, format); - let marked_expected_start = match self.expected_range.start_bound() { - Bound::Included(start) => format!("< {}", mark_missing(start, format)), - Bound::Excluded(start) => format!("<= {}", mark_missing(start, format)), - Bound::Unbounded => format!("< {}", mark_missing_substr("..", format)), - }; - let marked_expected_end = match self.expected_range.end_bound() { - Bound::Included(end) => format!("> {}", mark_missing(end, format)), - Bound::Excluded(end) => format!(">= {}", mark_missing(end, format)), - Bound::Unbounded => format!("> {}", mark_missing_substr("..", format)), + ( + "", + format!("{marked_expected_start} x {marked_expected_end}"), + ) }; + format!( - "expected {expression} is not within range of {:?}\n but was: {marked_actual}\n expected: x {marked_expected_start} || x {marked_expected_end}", + "expected {expression} to be {not}within range of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", self.expected_range, ) } } +impl Invertible for IsInRange {} + #[cfg(test)] mod tests; diff --git a/src/range/tests.rs b/src/range/tests.rs index 9ec0e24..bc5a72d 100644 --- a/src/range/tests.rs +++ b/src/range/tests.rs @@ -23,7 +23,7 @@ fn verify_i32_is_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of 43..51 + r"assertion failed: expected my_thing to be within range of 43..51 but was: 42 expected: 43 <= x < 51 " @@ -50,7 +50,7 @@ fn verify_i32_is_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of 43..=51 + r"assertion failed: expected my_thing to be within range of 43..=51 but was: 42 expected: 43 <= x <= 51 " @@ -77,7 +77,7 @@ fn verify_i32_is_in_range_from_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of 43.. + r"assertion failed: expected my_thing to be within range of 43.. but was: 42 expected: 43 <= x < .. " @@ -104,7 +104,7 @@ fn verify_i32_is_in_range_to_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of ..42 + r"assertion failed: expected my_thing to be within range of ..42 but was: 42 expected: .. < x < 42 " @@ -131,7 +131,7 @@ fn verify_i32_is_in_range_to_inclusive_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of ..=41 + r"assertion failed: expected my_thing to be within range of ..=41 but was: 42 expected: .. < x <= 41 " @@ -158,7 +158,7 @@ fn verify_i32_is_not_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of 41..43 + r"assertion failed: expected my_thing to be not within range of 41..43 but was: 42 expected: x < 41 || x >= 43 " @@ -185,7 +185,7 @@ fn verify_i32_is_not_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of 41..=42 + r"assertion failed: expected my_thing to be not within range of 41..=42 but was: 42 expected: x < 41 || x > 42 " @@ -212,7 +212,7 @@ fn verify_i32_is_not_in_range_from_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of 42.. + r"assertion failed: expected my_thing to be not within range of 42.. but was: 42 expected: x < 42 || x > .. " @@ -239,7 +239,7 @@ fn verify_i32_is_not_in_range_to_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of ..43 + r"assertion failed: expected my_thing to be not within range of ..43 but was: 42 expected: x < .. || x >= 43 " @@ -266,7 +266,7 @@ fn verify_i32_is_not_in_range_to_inclusive_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of ..=42 + r"assertion failed: expected my_thing to be not within range of ..=42 but was: 42 expected: x < .. || x > 42 " @@ -297,7 +297,7 @@ fn verify_char_is_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of 'L'..'Z' + r"assertion failed: expected my_thing to be within range of 'L'..'Z' but was: 'K' expected: 'L' <= x < 'Z' " @@ -324,7 +324,7 @@ fn verify_char_is_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is within range of 'L'..='Z' + r"assertion failed: expected my_thing to be within range of 'L'..='Z' but was: 'K' expected: 'L' <= x <= 'Z' " @@ -351,7 +351,7 @@ fn verify_char_is_not_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of 'J'..'L' + r"assertion failed: expected my_thing to be not within range of 'J'..'L' but was: 'K' expected: x < 'J' || x >= 'L' " @@ -378,7 +378,7 @@ fn verify_char_is_not_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is not within range of 'J'..='K' + r"assertion failed: expected my_thing to be not within range of 'J'..='K' but was: 'K' expected: x < 'J' || x > 'K' " @@ -435,7 +435,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is within range of -4321..4322\n \ + "assertion failed: expected subject to be within range of -4321..4322\n \ but was: \u{1b}[31m29834\u{1b}[0m\n \ expected: -4321 <= x < \u{1b}[34m4322\u{1b}[0m\n\ " @@ -455,7 +455,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is within range of -4321..4322\n \ + "assertion failed: expected subject to be within range of -4321..4322\n \ but was: \u{1b}[31m-29834\u{1b}[0m\n \ expected: \u{1b}[34m-4321\u{1b}[0m <= x < 4322\n\ " @@ -475,7 +475,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is within range of -4321..=4321\n \ + "assertion failed: expected subject to be within range of -4321..=4321\n \ but was: \u{1b}[31m29834\u{1b}[0m\n \ expected: -4321 <= x <= \u{1b}[34m4321\u{1b}[0m\n\ " @@ -495,7 +495,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is within range of -4321..=4321\n \ + "assertion failed: expected subject to be within range of -4321..=4321\n \ but was: \u{1b}[31m-29834\u{1b}[0m\n \ expected: \u{1b}[34m-4321\u{1b}[0m <= x <= 4321\n\ " @@ -515,7 +515,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is not within range of 'a'..'p'\n \ + "assertion failed: expected subject to be not within range of 'a'..'p'\n \ but was: \u{1b}[31m'm'\u{1b}[0m\n \ expected: x < \u{1b}[32m'a'\u{1b}[0m || x >= \u{1b}[32m'p'\u{1b}[0m\n\ " @@ -535,7 +535,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is not within range of 'a'..='z'\n \ + "assertion failed: expected subject to be not within range of 'a'..='z'\n \ but was: \u{1b}[31m'm'\u{1b}[0m\n \ expected: x < \u{1b}[32m'a'\u{1b}[0m || x > \u{1b}[32m'z'\u{1b}[0m\n\ " diff --git a/src/result/mod.rs b/src/result/mod.rs index b337725..c88e94a 100644 --- a/src/result/mod.rs +++ b/src/result/mod.rs @@ -6,7 +6,9 @@ use crate::assertions::{ }; use crate::colored::{mark_missing, mark_unexpected}; use crate::expectations::{HasError, HasValue, IsEqualTo, IsErr, IsOk}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec, Unknown}; +use crate::spec::{ + DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec, Unknown, +}; use crate::std::fmt::{Debug, Display}; use crate::std::{ format, @@ -192,13 +194,14 @@ where &self, expression: &Expression<'_>, actual: &Result, + _inverted: bool, format: &DiffFormat, ) -> String { let expected = Ok::<_, Unknown>(Unknown); let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&expected, format); format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" ) } } @@ -216,13 +219,14 @@ where &self, expression: &Expression<'_>, actual: &Result, + _inverted: bool, format: &DiffFormat, ) -> String { let expected = Err::(Unknown); let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&expected, format); format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" ) } } @@ -233,21 +237,17 @@ where E: Debug, { fn test(&mut self, subject: &&Result) -> bool { - subject.is_ok() + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Result, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = Ok::<_, Unknown>(Unknown); - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&expected, format); - format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } @@ -257,21 +257,17 @@ where E: Debug, { fn test(&mut self, subject: &&Result) -> bool { - subject.is_err() + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Result, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = Err::(Unknown); - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&expected, format); - format!( - "expected {expression} is {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } @@ -289,13 +285,15 @@ where &self, expression: &Expression<'_>, actual: &Result, + inverted: bool, format: &DiffFormat, ) -> String { + let not = if inverted { "not " } else { "" }; let expected = &self.expected; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&Ok::<_, E>(expected), format); format!( - "expected {expression} is ok containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be ok {not}containing {expected:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}" ) } } @@ -307,21 +305,17 @@ where X: Debug, { fn test(&mut self, subject: &&Result) -> bool { - subject.as_ref().is_ok_and(|value| value == &self.expected) + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Result, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = &self.expected; - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&Ok::<_, E>(expected), format); - format!( - "expected {expression} is ok containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } @@ -339,17 +333,21 @@ where &self, expression: &Expression<'_>, actual: &Result, + inverted: bool, format: &DiffFormat, ) -> String { + let not = if inverted { "not " } else { "" }; let expected = &self.expected; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&Err::(expected), format); format!( - "expected {expression} is error containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" + "expected {expression} to be an error {not}containing {expected:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}" ) } } +impl Invertible for HasError {} + impl Expectation<&Result> for HasError where T: Debug, @@ -357,21 +355,17 @@ where X: Debug, { fn test(&mut self, subject: &&Result) -> bool { - subject.as_ref().is_err_and(|err| err == &self.expected) + >>::test(self, subject) } fn message( &self, expression: &Expression<'_>, actual: &&Result, + inverted: bool, format: &DiffFormat, ) -> String { - let expected = &self.expected; - let marked_actual = mark_unexpected(actual, format); - let marked_expected = mark_missing(&Err::(expected), format); - format!( - "expected {expression} is error containing {expected:?}\n but was: {marked_actual}\n expected: {marked_expected}" - ) + >>::message(self, expression, actual, inverted, format) } } diff --git a/src/result/tests.rs b/src/result/tests.rs index f12c367..af67edf 100644 --- a/src/result/tests.rs +++ b/src/result/tests.rs @@ -58,7 +58,7 @@ fn verify_result_of_custom_types_is_ok_fails() { assert_eq!( failures, - &[r#"assertion failed: expected my_thing is Ok(_) + &[r#"assertion failed: expected my_thing to be Ok(_) but was: Err(MyError("aute nam ad amet")) expected: Ok(_) "#] @@ -83,7 +83,7 @@ fn verify_result_of_custom_types_is_err_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is Err(_) + &[r"assertion failed: expected my_thing to be Err(_) but was: Ok(MyValue(42)) expected: Err(_) "] @@ -135,7 +135,7 @@ fn verify_result_of_custom_types_has_value_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing is ok containing MyValue("sea non obcaecat nostrud") + r#"assertion failed: expected my_thing to be ok containing MyValue("sea non obcaecat nostrud") but was: Err(MyError("amet esse rebum feugait")) expected: Ok(MyValue("sea non obcaecat nostrud")) "# @@ -162,7 +162,7 @@ fn verify_result_of_custom_types_has_error_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is error containing MyError(-1) + r"assertion failed: expected my_thing to be an error containing MyError(-1) but was: Ok(MyValue(42)) expected: Err(MyError(-1)) " @@ -214,7 +214,7 @@ fn verify_borrowed_result_of_custom_types_is_ok_fails() { assert_eq!( failures, - &[r#"assertion failed: expected my_thing is Ok(_) + &[r#"assertion failed: expected my_thing to be Ok(_) but was: Err(MyError("aute nam ad amet")) expected: Ok(_) "#] @@ -239,7 +239,7 @@ fn verify_borrowed_result_of_custom_types_is_err_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing is Err(_) + &[r"assertion failed: expected my_thing to be Err(_) but was: Ok(MyValue(42)) expected: Err(_) "] @@ -291,7 +291,7 @@ fn verify_borrowed_result_of_custom_types_has_value_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing is ok containing MyValue("sea non obcaecat nostrud") + r#"assertion failed: expected my_thing to be ok containing MyValue("sea non obcaecat nostrud") but was: Err(MyError("amet esse rebum feugait")) expected: Ok(MyValue("sea non obcaecat nostrud")) "# @@ -318,7 +318,7 @@ fn verify_borrowed_result_of_custom_types_has_error_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is error containing MyError(-1) + r"assertion failed: expected my_thing to be an error containing MyError(-1) but was: Ok(MyValue(42)) expected: Err(MyError(-1)) " @@ -494,7 +494,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is Ok(_)\n \ + &["assertion failed: expected subject to be Ok(_)\n \ but was: \u{1b}[31mErr(\"esse augue id esse\")\u{1b}[0m\n \ expected: \u{1b}[34mOk(_)\u{1b}[0m\n\ "] @@ -512,7 +512,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is Err(_)\n \ + &["assertion failed: expected subject to be Err(_)\n \ but was: \u{1b}[31mOk(3500)\u{1b}[0m\n \ expected: \u{1b}[32mErr(_)\u{1b}[0m\n\ "] @@ -531,7 +531,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is ok containing [1, 2, 3, 5, 7]\n \ + "assertion failed: expected subject to be ok containing [1, 2, 3, 5, 7]\n \ but was: \u{1b}[31mErr(\"minim facer liber kasd\")\u{1b}[0m\n \ expected: \u{1b}[33mOk([1, 2, 3, 5, 7])\u{1b}[0m\n\ " @@ -551,7 +551,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is error containing \"at feugait nihil qui\"\n \ + "assertion failed: expected subject to be an error containing \"at feugait nihil qui\"\n \ but was: \u{1b}[31mOk([1, 2, 3, 5, 7])\u{1b}[0m\n \ expected: \u{1b}[33mErr(\"at feugait nihil qui\")\u{1b}[0m\n\ " diff --git a/src/rust_decimal/tests.rs b/src/rust_decimal/tests.rs index 57faf97..dca5cc1 100644 --- a/src/rust_decimal/tests.rs +++ b/src/rust_decimal/tests.rs @@ -22,7 +22,7 @@ fn verify_decimal_is_equal_to_other_fails() { assert_eq!( failures, - &[r"assertion failed: expected subject is equal to -42.831 + &[r"assertion failed: expected subject to be equal to -42.831 but was: 42.831 expected: -42.831 "] diff --git a/src/slice/tests.rs b/src/slice/tests.rs index e894c05..707c96d 100644 --- a/src/slice/tests.rs +++ b/src/slice/tests.rs @@ -32,7 +32,7 @@ fn verify_slice_is_equal_to_another_slice_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is equal to [2, 4, 6, 8] + r"assertion failed: expected my_thing to be equal to [2, 4, 6, 8] but was: [1, 3, 5, 7] expected: [2, 4, 6, 8] " @@ -94,7 +94,7 @@ fn verify_slice_has_length_less_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a length less than 6 + r"assertion failed: expected my_thing to have a length less than 6 but was: 6 expected: < 6 " @@ -121,7 +121,7 @@ fn verify_slice_has_length_greater_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a length greater than 6 + r"assertion failed: expected my_thing to have a length greater than 6 but was: 6 expected: > 6 " @@ -149,7 +149,7 @@ fn verify_slice_has_at_most_length_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at most a length of 5 + r"assertion failed: expected my_thing to have at most a length of 5 but was: 6 expected: <= 5 " @@ -177,7 +177,7 @@ fn verify_slice_has_at_least_length_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at least a length of 7 + r"assertion failed: expected my_thing to have at least a length of 7 but was: 6 expected: >= 7 " @@ -262,7 +262,7 @@ fn verify_slice_contains_exactly_in_any_order_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains exactly in any order [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] + r"assertion failed: expected my_thing to contain exactly in any order [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] missing: [0, 19] @@ -291,7 +291,7 @@ fn verify_slice_contains_any_of_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains any of [0, 2, 4, 8, 16, 32, 64] + r"assertion failed: expected my_thing to contain any of [0, 2, 4, 8, 16, 32, 64] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [0, 2, 4, 8, 16, 32, 64] " @@ -318,7 +318,7 @@ fn verify_slice_contains_all_of_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains all of [5, 18, 3, 17, 45, 1, 1, 29, 0] + r"assertion failed: expected my_thing to contain all of [5, 18, 3, 17, 45, 1, 1, 29, 0] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [5, 18, 3, 17, 45, 1, 1, 29, 0] missing: [18, 45, 0] @@ -346,7 +346,7 @@ fn verify_slice_contains_only_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains only [1, 3, 7, 11, 19] + r"assertion failed: expected my_thing to contain only [1, 3, 7, 11, 19] but was: [5, 11, 1, 3, 19, 17, 11, 43] expected: [1, 3, 7, 11, 19] extra: [5, 17, 43] @@ -374,7 +374,7 @@ fn verify_slice_contains_only_once_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains only once [1, 3, 7, 11, 19] + r"assertion failed: expected my_thing to contain only once [1, 3, 7, 11, 19] but was: [5, 11, 1, 3, 3, 19, 17, 11, 3, 43] expected: [1, 3, 7, 11, 19] extra: [5, 17, 43] @@ -431,7 +431,7 @@ fn verify_slice_contains_exactly_fails_out_of_order() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] + r#"assertion failed: expected my_thing to contain exactly in order ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine"] expected: ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] missing: [] @@ -471,7 +471,7 @@ fn verify_slice_contains_exactly_fails_missing_and_extra() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] + r#"assertion failed: expected my_thing to contain exactly in order ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] but was: ["one", "two", "six", "three", "four", "five", "six", "six", "seven", "eleven", "eight", "nine", "ten"] expected: ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] missing: ["two", "four"] @@ -509,7 +509,7 @@ fn verify_slice_contains_exactly_fails_expected_longer_than_vec() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] + r#"assertion failed: expected my_thing to contain exactly in order ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine"] expected: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] missing: ["ten"] @@ -572,7 +572,7 @@ fn verify_slice_contains_sequence_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains sequence ["two", "three", "four", "five", "six", "six", "four"] + r#"assertion failed: expected my_thing to contain the sequence ["two", "three", "four", "five", "six", "six", "four"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "two", "seven", "two", "three", "five", "four", "six", "four", "eight", "nine", "ten"] expected: ["two", "three", "four", "five", "six", "six", "four"] missing: ["six", "four"] @@ -601,7 +601,7 @@ fn verify_slice_contains_sequence_fails_expected_longer_than_vec() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains sequence ["one", "two", "three", "four", "five", "six", "seven"] + r#"assertion failed: expected my_thing to contain the sequence ["one", "two", "three", "four", "five", "six", "seven"] but was: ["one", "two", "three", "four", "five", "six"] expected: ["one", "two", "three", "four", "five", "six", "seven"] missing: ["seven"] @@ -666,7 +666,7 @@ fn verify_slice_contains_all_in_order_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains all of ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] in order + r#"assertion failed: expected my_thing to contain all of ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] in order but was: ["one", "two", "two", "three", "four", "five", "six", "four", "two", "seven", "two", "three", "five", "four", "six", "four", "eight", "nine", "ten"] expected: ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] missing: ["six"] @@ -715,7 +715,7 @@ fn verify_vec_starts_with_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing starts with [13, 5, 7, 1, 19] + r"assertion failed: expected my_thing to start with [13, 5, 7, 1, 19] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] expected: [13, 5, 7, 1, 19] missing: [1, 19] @@ -737,7 +737,7 @@ fn verify_empty_vec_starts_with_expected_sequence_longer_than_vec_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing starts with [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] + r"assertion failed: expected my_thing to start with [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31] expected: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] missing: [37] @@ -787,7 +787,7 @@ fn verify_vec_ends_with_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing ends with [11, 23, 23, 31, 73] + r"assertion failed: expected my_thing to end with [11, 23, 23, 31, 73] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] expected: [11, 23, 23, 31, 73] missing: [23, 73] @@ -809,7 +809,7 @@ fn verify_empty_vec_ends_with_expected_sequence_longer_than_vec_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing ends with [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] + r"assertion failed: expected my_thing to end with [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31] expected: [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] missing: [41] @@ -851,7 +851,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject contains exactly in any order [1, 2, 3, 13, 8, 7, 12, 15, 31, 19, 20, 11, 31]\n \ + "assertion failed: expected subject to contain exactly in any order [1, 2, 3, 13, 8, 7, 12, 15, 31, 19, 20, 11, 31]\n \ but was: [13, \u{1b}[31m5\u{1b}[0m, 7, 19, 1, 3, 11, \u{1b}[31m29\u{1b}[0m, \u{1b}[31m23\u{1b}[0m, 31, \u{1b}[31m37\u{1b}[0m]\n \ expected: [1, \u{1b}[34m2\u{1b}[0m, 3, 13, \u{1b}[34m8\u{1b}[0m, 7, \u{1b}[34m12\u{1b}[0m, \u{1b}[34m15\u{1b}[0m, 31, 19, \u{1b}[34m20\u{1b}[0m, 11, \u{1b}[34m31\u{1b}[0m]\n \ missing: [2, 8, 12, 15, 20, 31]\n \ @@ -870,7 +870,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject contains any of [2, 4, 6, 8, 9, 10, 12, 15, 32, 20, 18]\n \ + "assertion failed: expected subject to contain any of [2, 4, 6, 8, 9, 10, 12, 15, 32, 20, 18]\n \ but was: [\u{1b}[31m13\u{1b}[0m, \u{1b}[31m5\u{1b}[0m, \u{1b}[31m7\u{1b}[0m, \u{1b}[31m19\u{1b}[0m, \u{1b}[31m1\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, \u{1b}[31m11\u{1b}[0m, \u{1b}[31m29\u{1b}[0m, \u{1b}[31m23\u{1b}[0m, \u{1b}[31m31\u{1b}[0m, \u{1b}[31m37\u{1b}[0m]\n \ expected: [\u{1b}[34m2\u{1b}[0m, \u{1b}[34m4\u{1b}[0m, \u{1b}[34m6\u{1b}[0m, \u{1b}[34m8\u{1b}[0m, \u{1b}[34m9\u{1b}[0m, \u{1b}[34m10\u{1b}[0m, \u{1b}[34m12\u{1b}[0m, \u{1b}[34m15\u{1b}[0m, \u{1b}[34m32\u{1b}[0m, \u{1b}[34m20\u{1b}[0m, \u{1b}[34m18\u{1b}[0m]\n\ " @@ -887,7 +887,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject contains all of [2, 3, 5, 20, 11, 13, 19, 37, 22]\n \ + "assertion failed: expected subject to contain all of [2, 3, 5, 20, 11, 13, 19, 37, 22]\n \ but was: [13, 5, \u{1b}[31m7\u{1b}[0m, 19, \u{1b}[31m1\u{1b}[0m, 3, 11, \u{1b}[31m29\u{1b}[0m, \u{1b}[31m23\u{1b}[0m, \u{1b}[31m31\u{1b}[0m, 37]\n \ expected: [\u{1b}[34m2\u{1b}[0m, 3, 5, \u{1b}[34m20\u{1b}[0m, 11, 13, 19, 37, \u{1b}[34m22\u{1b}[0m]\n \ missing: [2, 20, 22]\n\ @@ -905,7 +905,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject contains only [13, 3, 5, 20, 11, 13, 19, 37, 22]\n \ + "assertion failed: expected subject to contain only [13, 3, 5, 20, 11, 13, 19, 37, 22]\n \ but was: [13, 5, \u{1b}[31m7\u{1b}[0m, 19, \u{1b}[31m1\u{1b}[0m, 3, 11, \u{1b}[31m29\u{1b}[0m, \u{1b}[31m23\u{1b}[0m, \u{1b}[31m31\u{1b}[0m, 37]\n \ expected: [13, 3, 5, \u{1b}[34m20\u{1b}[0m, 11, 13, 19, 37, \u{1b}[34m22\u{1b}[0m]\n \ extra: [7, 1, 29, 23, 31]\n\ @@ -925,7 +925,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject contains only once [1, 3, 7, 11, 19]\n \ + "assertion failed: expected subject to contain only once [1, 3, 7, 11, 19]\n \ but was: [\u{1b}[31m5\u{1b}[0m, \u{1b}[31m11\u{1b}[0m, 1, \u{1b}[31m3\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, 19, \u{1b}[31m17\u{1b}[0m, \u{1b}[31m11\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, \u{1b}[31m43\u{1b}[0m]\n \ expected: [1, \u{1b}[34m3\u{1b}[0m, \u{1b}[34m7\u{1b}[0m, \u{1b}[34m11\u{1b}[0m, 19]\n \ extra: [5, 17, 43]\n \ @@ -945,7 +945,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject contains exactly in order [13, 20, 5, 19, 11, 29, 8, 1, 23, 31, 41]\n \ + "assertion failed: expected subject to contain exactly in order [13, 20, 5, 19, 11, 29, 8, 1, 23, 31, 41]\n \ but was: [13, \u{1b}[31m5\u{1b}[0m, \u{1b}[31m7\u{1b}[0m, 19, \u{1b}[31m1\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, \u{1b}[31m11\u{1b}[0m, \u{1b}[31m29\u{1b}[0m, 23, 31, \u{1b}[31m37\u{1b}[0m]\n \ expected: [13, \u{1b}[33m20\u{1b}[0m, \u{1b}[33m5\u{1b}[0m, 19, \u{1b}[33m11\u{1b}[0m, \u{1b}[33m29\u{1b}[0m, \u{1b}[33m8\u{1b}[0m, \u{1b}[33m1\u{1b}[0m, 23, 31, \u{1b}[33m41\u{1b}[0m]\n \ missing: [20, 8, 41]\n \ @@ -967,7 +967,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject contains sequence [19, 3, 7, 11, 29]\n \ + "assertion failed: expected subject to contain the sequence [19, 3, 7, 11, 29]\n \ but was: [13, 5, 7, 19, \u{1b}[31m1\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, 11, 29, 23, 31, 37]\n \ expected: [19, \u{1b}[33m3\u{1b}[0m, \u{1b}[33m7\u{1b}[0m, 11, 29]\n \ missing: [3, 7]\n \ @@ -989,7 +989,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject contains all of [13, 3, 7, 22, 11, 20, 29, 37] in order\n \ + "assertion failed: expected subject to contain all of [13, 3, 7, 22, 11, 20, 29, 37] in order\n \ but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37]\n \ expected: [13, 3, \u{1b}[33m7\u{1b}[0m, \u{1b}[33m22\u{1b}[0m, 11, \u{1b}[33m20\u{1b}[0m, 29, 37]\n \ missing: [7, 22, 20]\n\ @@ -1010,7 +1010,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject starts with [13, 5, 8, 19, 4]\n \ + "assertion failed: expected subject to start with [13, 5, 8, 19, 4]\n \ but was: [13, 5, \u{1b}[31m7\u{1b}[0m, 19, \u{1b}[31m1\u{1b}[0m, 3, 11, 29, 23, 31, 37]\n \ expected: [13, 5, \u{1b}[33m8\u{1b}[0m, 19, \u{1b}[33m4\u{1b}[0m]\n \ missing: [8, 4]\n \ @@ -1032,7 +1032,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject ends with [3, 11, 28, 29, 30, 37]\n \ + "assertion failed: expected subject to end with [3, 11, 28, 29, 30, 37]\n \ but was: [13, 5, 7, 19, 1, 3, 11, \u{1b}[31m29\u{1b}[0m, \u{1b}[31m23\u{1b}[0m, \u{1b}[31m31\u{1b}[0m, 37]\n \ expected: [3, 11, \u{1b}[33m28\u{1b}[0m, \u{1b}[33m29\u{1b}[0m, \u{1b}[33m30\u{1b}[0m, 37]\n \ missing: [28, 29, 30]\n \ diff --git a/src/spec/mod.rs b/src/spec/mod.rs index 1cb1f06..d561420 100644 --- a/src/spec/mod.rs +++ b/src/spec/mod.rs @@ -430,9 +430,28 @@ pub trait Expectation { fn test(&mut self, subject: &S) -> bool; /// Forms a failure message for this expectation. - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String; + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String; } +/// Marks an expectation that it can be inverted by using the [`Not`] +/// combinator. +/// +/// An expectation is any type that implements the [`Expectation`] trait. +/// +/// This trait is meant to be implemented in combination with the +/// [`Expectation`] trait. It should only be implemented for an expectation if +/// the inverted test is unmistakably meaningful, and if the failure message +/// clearly states whether the expectation has been inverted or not. +/// +/// [`Not`]: crate::expectations::Not +pub trait Invertible {} + /// A textual representation of the expression or subject that is being /// asserted. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -861,7 +880,7 @@ where if !expectation.test(&self.subject) { let default_expression = Expression::default(); let expression = self.expression.as_ref().unwrap_or(&default_expression); - let message = expectation.message(expression, &self.subject, &self.diff_format); + let message = expectation.message(expression, &self.subject, false, &self.diff_format); self.do_fail_with_message(message); } self @@ -1007,7 +1026,7 @@ impl Spec<'_, S, CollectFailures> { /// but was: "the answer to all important questions is 42" /// expected: "unimportant" /// - /// assertion failed: expected subject has at most a length of 41 + /// assertion failed: expected subject to have at most a length of 41 /// but was: 43 /// expected: <= 41 /// ``` @@ -1066,15 +1085,15 @@ impl<'a, I, R> Spec<'a, I, R> { /// will print: /// /// ```console - /// assertion failed: expected numbers 1. item is greater than 2 + /// assertion failed: expected numbers 1. item to be greater than 2 /// but was: 2 /// expected: > 2 /// - /// assertion failed: expected numbers 4. item is at most 7 + /// assertion failed: expected numbers 4. item to be at most 7 /// but was: 8 /// expected: <= 7 /// - /// assertion failed: expected numbers 5. item is at most 7 + /// assertion failed: expected numbers 5. item to be at most 7 /// but was: 10 /// expected: <= 7 /// ``` @@ -1257,7 +1276,7 @@ impl FailingStrategy for CollectFailures { /// subject.is_ok() /// } /// -/// fn message(&self, expression: &Expression<'_>, actual: &Result, _format: &DiffFormat) -> String { +/// fn message(&self, expression: &Expression<'_>, actual: &Result, _inverted: bool, _format: &DiffFormat) -> String { /// format!( /// "expected {expression} is {:?}\n but was: {actual:?}\n expected: {:?}", /// Ok::<_, Unknown>(Unknown), diff --git a/src/spec/tests.rs b/src/spec/tests.rs index cc7e717..3abbbe1 100644 --- a/src/spec/tests.rs +++ b/src/spec/tests.rs @@ -120,7 +120,7 @@ fn assert_that_macro_with_borrowed_str_subject() { #[test] #[should_panic( - expected = "assertion failed: expected ultimate_answer is equal to 42\n but was: 51\n expected: 42\n" + expected = "assertion failed: expected ultimate_answer to be equal to 42\n but was: 51\n expected: 42\n" )] fn assert_that_macro_is_equal_to_with_integers_fails() { let ultimate_answer = 51; @@ -149,11 +149,11 @@ fn verify_that_option_is_some_chained_with_has_value_fails_as_none() { assert_eq!( failures, &[ - r"assertion failed: expected my_variable is Some(_) + r"assertion failed: expected my_variable to be Some(_) but was: None expected: Some(_) ", - r"assertion failed: expected my_variable is some containing 42 + r"assertion failed: expected my_variable to be some containing 42 but was: None expected: Some(42) ", @@ -174,7 +174,7 @@ fn verify_that_a_subject_with_custom_description_is_equal_to_fails() { failures, &[ r"assertion failed: the answer to all important questions is 42 -expected subject is equal to 42 +expected subject to be equal to 42 but was: 51 expected: 42 " @@ -196,7 +196,7 @@ fn verify_that_a_subject_with_custom_name_and_custom_description_is_equal_to_fai failures, &[ r"assertion failed: the answer to all important questions is 42 -expected answer is equal to 42 +expected answer to be equal to 42 but was: 51 expected: 42 " @@ -219,7 +219,7 @@ fn soft_assertions_with_chained_assertion_methods() { but was: \"the answer to all important questions is 42\"\n \ expected: \"unimportant\"\n\ \n\ - assertion failed: expected subject has at most a length of 41\n \ + assertion failed: expected subject to have at most a length of 41\n \ but was: 43\n \ expected: <= 41\n\ "] @@ -251,7 +251,7 @@ fn assert_each_item_of_a_borrowed_iterator() { } #[test] -#[should_panic = "assertion failed: expected numbers 2. item is not equal to 4\n but was: 4\n expected: not 4\n"] +#[should_panic = "assertion failed: expected numbers 2. item to be not equal to 4\n but was: 4\n expected: not 4\n"] fn assert_each_item_of_an_iterator_panics_if_one_assertion_fails() { let subject = [2, 4, 6, 8, 10]; @@ -273,15 +273,15 @@ fn verify_assert_each_item_of_an_iterator_fails() { assert_eq!( failures, &[ - r"assertion failed: expected numbers 1. item is greater than 2 + r"assertion failed: expected numbers 1. item to be greater than 2 but was: 2 expected: > 2 ", - r"assertion failed: expected numbers 4. item is at most 7 + r"assertion failed: expected numbers 4. item to be at most 7 but was: 8 expected: <= 7 ", - r"assertion failed: expected numbers 5. item is at most 7 + r"assertion failed: expected numbers 5. item to be at most 7 but was: 10 expected: <= 7 ", @@ -298,7 +298,7 @@ mod colored { but was: \"\u{1b}[31mthe answer to all important questions is 42\u{1b}[0m\"\n \ expected: \"\u{1b}[32munimportant\u{1b}[0m\"\n\ \n\ - assertion failed: expected subject has at most a length of 41\n \ + assertion failed: expected subject to have at most a length of 41\n \ but was: \u{1b}[31m43\u{1b}[0m\n \ expected: <= \u{1b}[32m41\u{1b}[0m\n\ "] diff --git a/src/string/mod.rs b/src/string/mod.rs index 325d654..07a87fb 100644 --- a/src/string/mod.rs +++ b/src/string/mod.rs @@ -6,7 +6,7 @@ use crate::colored::{ }; use crate::expectations::{StringContains, StringContainsAnyOf, StringEndsWith, StringStartWith}; use crate::properties::{CharCountProperty, DefinedOrderProperty, IsEmptyProperty, LengthProperty}; -use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Spec}; +use crate::spec::{DiffFormat, Expectation, Expression, FailingStrategy, Invertible, Spec}; use crate::std::fmt::Debug; use crate::std::str::Chars; use crate::std::{ @@ -119,16 +119,25 @@ where subject.as_ref().contains(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_substr(actual.as_ref(), format); let marked_expected = mark_missing_substr(self.expected, format); format!( - "expected {expression} to contain {:?}\n but was: \"{marked_actual}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}contain {:?}\n but was: \"{marked_actual}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringContains<&str> {} + impl Expectation for StringContains where S: AsRef + Debug, @@ -137,16 +146,25 @@ where subject.as_ref().contains(&self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_substr(actual.as_ref(), format); let marked_expected = mark_missing_substr(self.expected.as_ref(), format); format!( - "expected {expression} to contain {:?}\n but was: \"{marked_actual}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}contain {:?}\n but was: \"{marked_actual}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringContains {} + impl Expectation for StringContains where S: AsRef + Debug, @@ -155,16 +173,25 @@ where subject.as_ref().contains(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected_substr(actual.as_ref(), format); let marked_expected = mark_missing_char(self.expected, format); format!( - "expected {expression} to contain {:?}\n but was: \"{marked_actual}\"\n expected: '{marked_expected}'", + "expected {expression} to {not}contain {:?}\n but was: \"{marked_actual}\"\n expected: {not}'{marked_expected}'", self.expected, ) } } +impl Invertible for StringContains {} + impl Expectation for StringStartWith<&str> where S: AsRef + Debug, @@ -173,7 +200,14 @@ where subject.as_ref().starts_with(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected_char_len = self.expected.chars().count(); let actual_start = actual .as_ref() @@ -188,12 +222,14 @@ where let marked_actual_start = mark_unexpected_substr(&actual_start, format); let marked_expected = mark_missing_substr(self.expected, format); format!( - "expected {expression} to start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringStartWith<&str> {} + impl Expectation for StringStartWith where S: AsRef + Debug, @@ -202,7 +238,14 @@ where subject.as_ref().starts_with(&self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let expected_char_len = self.expected.chars().count(); let actual_start = actual .as_ref() @@ -217,12 +260,14 @@ where let marked_actual_start = mark_unexpected_substr(&actual_start, format); let marked_expected = mark_missing_substr(&self.expected, format); format!( - "expected {expression} to start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringStartWith {} + impl Expectation for StringStartWith where S: AsRef + Debug, @@ -231,18 +276,27 @@ where subject.as_ref().starts_with(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let actual_first_char = actual.as_ref().chars().take(1).collect::(); let actual_rest = actual.as_ref().chars().skip(1).collect::(); let marked_actual_start = mark_unexpected_substr(&actual_first_char, format); let marked_expected = mark_missing_char(self.expected, format); format!( - "expected {expression} to start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: '{marked_expected}'", + "expected {expression} to {not}start with {:?}\n but was: \"{marked_actual_start}{actual_rest}\"\n expected: {not}'{marked_expected}'", self.expected, ) } } +impl Invertible for StringStartWith {} + impl Expectation for StringEndsWith<&str> where S: AsRef + Debug, @@ -251,7 +305,14 @@ where subject.as_ref().ends_with(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let actual_char_len = actual.as_ref().chars().count(); let expected_char_len = self.expected.chars().count(); let split_point = actual_char_len.saturating_sub(expected_char_len); @@ -268,12 +329,14 @@ where let marked_actual_end = mark_unexpected_substr(&actual_end, format); let marked_expected = mark_missing_substr(self.expected, format); format!( - "expected {expression} to end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringEndsWith<&str> {} + impl Expectation for StringEndsWith where S: AsRef + Debug, @@ -282,7 +345,14 @@ where subject.as_ref().ends_with(&self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let actual_char_len = actual.as_ref().chars().count(); let expected_char_len = self.expected.chars().count(); let split_point = actual_char_len.saturating_sub(expected_char_len); @@ -299,12 +369,14 @@ where let marked_actual_end = mark_unexpected_substr(&actual_end, format); let marked_expected = mark_missing_substr(&self.expected, format); format!( - "expected {expression} to end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: \"{marked_expected}\"", + "expected {expression} to {not}end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: {not}\"{marked_expected}\"", self.expected, ) } } +impl Invertible for StringEndsWith {} + impl Expectation for StringEndsWith where S: AsRef + Debug, @@ -313,7 +385,14 @@ where subject.as_ref().ends_with(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let actual_last_char = actual .as_ref() .chars() @@ -325,14 +404,16 @@ where let marked_actual_end = mark_unexpected_substr(&actual_last_char, format); let marked_expected = mark_missing_char(self.expected, format); format!( - "expected {expression} to end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: '{marked_expected}'", + "expected {expression} to {not}end with {:?}\n but was: \"{actual_start}{marked_actual_end}\"\n expected: {not}'{marked_expected}'", self.expected, ) } } +impl Invertible for StringEndsWith {} + // When string slices' `contains` function is used with an array of chars or -// slice of chars it checks if any of the chars in the array/slice is contained +// slice of chars, it checks if any of the chars in the array/slice is contained // in the string slice. Therefore, we implement the [`AssertContainsAnyOf`] // assertion for array/slice of chars as expected value, but not the // [`AssertContains`] assertion. @@ -375,16 +456,25 @@ where subject.as_ref().contains(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} to contain any of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}contain any of {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected, ) } } +impl Invertible for StringContainsAnyOf<&[char]> {} + impl Expectation for StringContainsAnyOf<[char; N]> where S: AsRef + Debug, @@ -393,16 +483,25 @@ where subject.as_ref().contains(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} to contain any of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}contain any of {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected, ) } } +impl Invertible for StringContainsAnyOf<[char; N]> {} + impl Expectation for StringContainsAnyOf<&[char; N]> where S: AsRef + Debug, @@ -411,16 +510,25 @@ where subject.as_ref().contains(self.expected) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let not = if inverted { "not " } else { "" }; let marked_actual = mark_unexpected(actual, format); let marked_expected = mark_missing(&self.expected, format); format!( - "expected {expression} to contain any of {:?}\n but was: {marked_actual}\n expected: {marked_expected}", + "expected {expression} to {not}contain any of {:?}\n but was: {marked_actual}\n expected: {not}{marked_expected}", self.expected, ) } } +impl Invertible for StringContainsAnyOf<&[char; N]> {} + #[cfg(feature = "regex")] mod regex { use crate::assertions::AssertStringMatches; @@ -449,28 +557,43 @@ mod regex { .is_ok_and(|regex| regex.is_match(subject.as_ref())) } - fn message(&self, expression: &Expression<'_>, actual: &S, format: &DiffFormat) -> String { + fn message( + &self, + expression: &Expression<'_>, + actual: &S, + inverted: bool, + format: &DiffFormat, + ) -> String { + let (not, does_not_match) = if inverted { + ("not ", " does match") + } else { + ("", "does not match") + }; let pattern = self.pattern; match self.regex.as_ref() { Ok(regex) => { let marked_actual = mark_unexpected_substr(actual.as_ref(), format); let marked_expected = mark_missing_substr(regex.as_str(), format); - format!("expected {expression} matches regex {pattern}\n but was: {marked_actual}\n does not match regex: {marked_expected}") + format!("expected {expression} to {not}match the regex {pattern}\n but was: {marked_actual}\n {does_not_match} regex: {marked_expected}") }, Err(regex::Error::Syntax(error)) => { let marked_error = mark_unexpected_substr(error, format); - format!("expected {expression} matches regex {pattern}\n but the regex can not be compiled: {marked_error}") + format!("expected {expression} to {not}match the regex {pattern}\n but the regex can not be compiled: {marked_error}") }, Err(regex::Error::CompiledTooBig(limit)) => { let marked_error = mark_unexpected_substr( &format!("the compiled regex exceeds the size limit of {limit} bytes"), format, ); - format!("expected {expression} matches regex {pattern}\n but {marked_error}") + format!( + "expected {expression} to {not}match the regex {pattern}\n but {marked_error}" + ) }, Err(err) => { let marked_error = mark_unexpected_substr(&err.to_string(), format); - format!("expected {expression} matches regex {pattern}\n but {marked_error}") + format!( + "expected {expression} to {not}match the regex {pattern}\n but {marked_error}" + ) }, } } diff --git a/src/string/tests.rs b/src/string/tests.rs index 7e694dc..e5195da 100644 --- a/src/string/tests.rs +++ b/src/string/tests.rs @@ -83,7 +83,7 @@ fn verify_string_is_equal_to_str_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing is equal to "aute duis eleifend molestie" + r#"assertion failed: expected my_thing to be equal to "aute duis eleifend molestie" but was: "" expected: "aute duis eleifend molestie" "# @@ -144,7 +144,7 @@ fn verify_str_is_empty_fails() { assert_eq!( failures, - &[r#"assertion failed: expected my_thing is empty + &[r#"assertion failed: expected my_thing to be empty but was: "ABC" expected: "#] @@ -162,7 +162,7 @@ fn verify_string_is_not_empty_fails() { assert_eq!( failures, - &[r#"assertion failed: expected my_thing is not empty + &[r#"assertion failed: expected my_thing to be not empty but was: "" expected: "#] @@ -201,7 +201,7 @@ fn verify_str_has_length_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing has length 29 + &[r"assertion failed: expected my_thing to have a length of 29 but was: 28 expected: 29 "] @@ -227,7 +227,7 @@ fn verify_has_length_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has length in range 1..25 + r"assertion failed: expected my_thing to have a length within range 1..25 but was: 25 expected: 1..25 " @@ -254,7 +254,7 @@ fn verify_has_length_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has length in range 1..=24 + r"assertion failed: expected my_thing to have a length within range 1..=24 but was: 25 expected: 1..=24 " @@ -281,7 +281,7 @@ fn verify_string_has_length_less_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a length less than 25 + r"assertion failed: expected my_thing to have a length less than 25 but was: 25 expected: < 25 " @@ -308,7 +308,7 @@ fn verify_string_has_length_greater_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a length greater than 28 + r"assertion failed: expected my_thing to have a length greater than 28 but was: 28 expected: > 28 " @@ -336,7 +336,7 @@ fn verify_string_has_at_most_length_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at most a length of 29 + r"assertion failed: expected my_thing to have at most a length of 29 but was: 30 expected: <= 29 " @@ -364,7 +364,7 @@ fn verify_string_has_at_least_length_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at least a length of 22 + r"assertion failed: expected my_thing to have at least a length of 22 but was: 21 expected: >= 22 " @@ -415,10 +415,12 @@ fn verify_str_has_char_count_fails() { assert_eq!( failures, - &[r"assertion failed: expected my_thing has a char count of 7 + &[ + r"assertion failed: expected my_thing to have a char count of 7 but was: 5 expected: 7 -"] +" + ] ); } @@ -462,7 +464,7 @@ fn verify_str_has_char_count_in_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a char count of 6..12 + r"assertion failed: expected my_thing to have a char count within 6..12 but was: 5 expected: 6..12 " @@ -489,7 +491,7 @@ fn verify_str_has_char_count_in_inclusive_range_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a char count of 6..=12 + r"assertion failed: expected my_thing to have a char count within 6..=12 but was: 5 expected: 6..=12 " @@ -516,7 +518,7 @@ fn verify_string_has_char_count_less_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a char count less than 7 + r"assertion failed: expected my_thing to have a char count less than 7 but was: 7 expected: < 7 " @@ -543,7 +545,7 @@ fn verify_string_has_char_count_greater_than_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has a char count greater than 7 + r"assertion failed: expected my_thing to have a char count greater than 7 but was: 7 expected: > 7 " @@ -571,7 +573,7 @@ fn verify_string_has_at_most_char_count_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at most a char count of 6 + r"assertion failed: expected my_thing to have at most a char count of 6 but was: 7 expected: <= 6 " @@ -599,7 +601,7 @@ fn verify_string_has_at_least_char_count_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing has at least a char count of 8 + r"assertion failed: expected my_thing to have at least a char count of 8 but was: 7 expected: >= 8 " @@ -1004,7 +1006,7 @@ mod regex { assert_eq!( failures, &[ - r"assertion failed: expected my_thing matches regex \b\w{12}\b + r"assertion failed: expected my_thing to match the regex \b\w{12}\b but was: volutpat lobortis aliquam diam does not match regex: \b\w{12}\b " @@ -1024,7 +1026,7 @@ mod regex { assert_eq!( failures, &[ - r"assertion failed: expected password matches regex ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,32}$ + r"assertion failed: expected password to match the regex ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,32}$ but the regex can not be compiled: regex parse error: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,32}$ ^^^ @@ -1046,7 +1048,7 @@ error: look-around, including look-ahead and look-behind, is not supported assert_eq!( failures, &[ - r"assertion failed: expected my_thing matches regex ^(\/[\w-]{1,255}){1,64}\/?$ + r"assertion failed: expected my_thing to match the regex ^(\/[\w-]{1,255}){1,64}\/?$ but the compiled regex exceeds the size limit of 10485760 bytes " ] @@ -1069,7 +1071,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject is equal to \"invi wisi exercitation anim placerat\"\n \ + "assertion failed: expected subject to be equal to \"invi wisi exercitation anim placerat\"\n \ but was: \"invi\u{1b}[31mdunt\u{1b}[0m wisi \u{1b}[31mfacilisis \u{1b}[0mexercitation\"\n \ expected: \"invi wisi exercitation\u{1b}[34m anim placerat\u{1b}[0m\"\n\ " @@ -1086,7 +1088,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is not equal to \"aute aliquip culpa blandit\"\n \ + &["assertion failed: expected subject to be not equal to \"aute aliquip culpa blandit\"\n \ but was: \"aute aliquip culpa blandit\"\n \ expected: not \"aute aliquip culpa blandit\"\n\ "] @@ -1104,7 +1106,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is empty\n \ + &["assertion failed: expected subject to be empty\n \ but was: \u{1b}[31m\"voluptua quod quis dignissim\"\u{1b}[0m\n \ expected: \n\ "] @@ -1122,7 +1124,7 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject is not empty\n \ + &["assertion failed: expected subject to be not empty\n \ but was: \u{1b}[31m\"\"\u{1b}[0m\n \ expected: \n\ "] @@ -1140,10 +1142,12 @@ mod colored { assert_eq!( failures, - &["assertion failed: expected subject has length 29\n \ + &[ + "assertion failed: expected subject to have a length of 29\n \ but was: \u{1b}[31m23\u{1b}[0m\n \ expected: \u{1b}[32m29\u{1b}[0m\n\ - "] + " + ] ); } @@ -1159,7 +1163,7 @@ mod colored { assert_eq!( failures, &[ - "assertion failed: expected subject has length in range 8..=20\n \ + "assertion failed: expected subject to have a length within range 8..=20\n \ but was: \u{1b}[31m26\u{1b}[0m\n \ expected: \u{1b}[32m8..=20\u{1b}[0m\n\ " @@ -1420,7 +1424,7 @@ mod colored_regex { assert_eq!( failures, &[ - "assertion failed: expected my_thing matches regex \\b\\w{12}\\b\n \ + "assertion failed: expected my_thing to match the regex \\b\\w{12}\\b\n \ but was: \u{1b}[31mvolutpat lobortis aliquam diam\u{1b}[0m\n \ does not match regex: \u{1b}[32m\\b\\w{12}\\b\u{1b}[0m\n\ " @@ -1441,7 +1445,7 @@ mod colored_regex { assert_eq!( failures, &[ - "assertion failed: expected password matches regex ^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,32}$\n \ + "assertion failed: expected password to match the regex ^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,32}$\n \ but the regex can not be compiled: \u{1b}[31mregex parse error:\n \ ^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,32}$\n \ ^^^\n\ @@ -1464,7 +1468,7 @@ mod colored_regex { assert_eq!( failures, &[ - "assertion failed: expected my_thing matches regex ^(\\/[\\w-]{1,255}){1,64}\\/?$\n \ + "assertion failed: expected my_thing to match the regex ^(\\/[\\w-]{1,255}){1,64}\\/?$\n \ but \u{1b}[31mthe compiled regex exceeds the size limit of 10485760 bytes\u{1b}[0m\n\ " ] diff --git a/src/vec/tests.rs b/src/vec/tests.rs index 5cee152..d51f7e1 100644 --- a/src/vec/tests.rs +++ b/src/vec/tests.rs @@ -31,7 +31,7 @@ fn verify_vec_is_equal_to_another_vec_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing is equal to [1, 3, 5, 7] + r"assertion failed: expected my_thing to be equal to [1, 3, 5, 7] but was: [2, 4, 6, 8] expected: [1, 3, 5, 7] " @@ -113,7 +113,7 @@ fn verify_vec_contains_exactly_in_any_order_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains exactly in any order [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] + r"assertion failed: expected my_thing to contain exactly in any order [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [0, 1, 3, 5, 7, 11, 11, 13, 17, 19, 23, 29, 31, 37, 41] missing: [0, 19] @@ -142,7 +142,7 @@ fn verify_vec_contains_any_of_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains any of [0, 2, 4, 8, 16, 32, 64] + r"assertion failed: expected my_thing to contain any of [0, 2, 4, 8, 16, 32, 64] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [0, 2, 4, 8, 16, 32, 64] " @@ -169,7 +169,7 @@ fn verify_vec_contains_all_of_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains all of [5, 18, 3, 17, 45, 1, 1, 29, 0] + r"assertion failed: expected my_thing to contain all of [5, 18, 3, 17, 45, 1, 1, 29, 0] but was: [5, 7, 11, 13, 1, 11, 3, 17, 23, 23, 29, 31, 41, 37, 43] expected: [5, 18, 3, 17, 45, 1, 1, 29, 0] missing: [18, 45, 0] @@ -197,7 +197,7 @@ fn verify_vec_contains_only_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains only [1, 3, 7, 11, 19] + r"assertion failed: expected my_thing to contain only [1, 3, 7, 11, 19] but was: [5, 11, 1, 3, 19, 17, 11, 43] expected: [1, 3, 7, 11, 19] extra: [5, 17, 43] @@ -225,7 +225,7 @@ fn verify_vec_contains_only_once_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing contains only once [1, 3, 7, 11, 19] + r"assertion failed: expected my_thing to contain only once [1, 3, 7, 11, 19] but was: [5, 11, 1, 3, 19, 17, 11, 43] expected: [1, 3, 7, 11, 19] extra: [5, 17, 43] @@ -282,7 +282,7 @@ fn verify_vec_contains_exactly_fails_out_of_order() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] + r#"assertion failed: expected my_thing to contain exactly in order ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine"] expected: ["two", "two", "one", "three", "four", "five", "six", "seven", "four", "eight", "nine"] missing: [] @@ -322,7 +322,7 @@ fn verify_vec_contains_exactly_fails_missing_and_extra() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] + r#"assertion failed: expected my_thing to contain exactly in order ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] but was: ["one", "two", "six", "three", "four", "five", "six", "six", "seven", "eleven", "eight", "nine", "ten"] expected: ["one", "two", "two", "three", "four", "five", "six", "six", "seven", "four", "eight", "nine"] missing: ["two", "four"] @@ -360,7 +360,7 @@ fn verify_vec_contains_exactly_fails_expected_longer_than_vec() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains exactly in order ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] + r#"assertion failed: expected my_thing to contain exactly in order ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine"] expected: ["one", "two", "two", "three", "four", "five", "six", "four", "seven", "eight", "nine", "ten"] missing: ["ten"] @@ -423,7 +423,7 @@ fn verify_vec_contains_sequence_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains sequence ["two", "three", "four", "five", "six", "six", "four"] + r#"assertion failed: expected my_thing to contain the sequence ["two", "three", "four", "five", "six", "six", "four"] but was: ["one", "two", "two", "three", "four", "five", "six", "four", "two", "seven", "two", "three", "five", "four", "six", "four", "eight", "nine", "ten"] expected: ["two", "three", "four", "five", "six", "six", "four"] missing: ["six", "four"] @@ -452,7 +452,7 @@ fn verify_vec_contains_sequence_fails_expected_longer_than_vec() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains sequence ["one", "two", "three", "four", "five", "six", "seven"] + r#"assertion failed: expected my_thing to contain the sequence ["one", "two", "three", "four", "five", "six", "seven"] but was: ["one", "two", "three", "four", "five", "six"] expected: ["one", "two", "three", "four", "five", "six", "seven"] missing: ["seven"] @@ -517,7 +517,7 @@ fn verify_vec_contains_all_in_order_fails() { assert_eq!( failures, &[ - r#"assertion failed: expected my_thing contains all of ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] in order + r#"assertion failed: expected my_thing to contain all of ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] in order but was: ["one", "two", "two", "three", "four", "five", "six", "four", "two", "seven", "two", "three", "five", "four", "six", "four", "eight", "nine", "ten"] expected: ["one", "two", "two", "seven", "two", "three", "six", "six", "ten"] missing: ["six"] @@ -566,7 +566,7 @@ fn verify_vec_starts_with_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing starts with [13, 5, 7, 1, 19] + r"assertion failed: expected my_thing to start with [13, 5, 7, 1, 19] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] expected: [13, 5, 7, 1, 19] missing: [1, 19] @@ -588,7 +588,7 @@ fn verify_empty_vec_starts_with_expected_sequence_longer_than_vec_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing starts with [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] + r"assertion failed: expected my_thing to start with [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31] expected: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] missing: [37] @@ -638,7 +638,7 @@ fn verify_vec_ends_with_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing ends with [11, 23, 23, 31, 73] + r"assertion failed: expected my_thing to end with [11, 23, 23, 31, 73] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31, 37] expected: [11, 23, 23, 31, 73] missing: [23, 73] @@ -660,7 +660,7 @@ fn verify_empty_vec_ends_with_expected_sequence_longer_than_vec_fails() { assert_eq!( failures, &[ - r"assertion failed: expected my_thing ends with [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] + r"assertion failed: expected my_thing to end with [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] but was: [13, 5, 7, 19, 1, 3, 11, 29, 23, 31] expected: [41, 13, 5, 7, 19, 1, 3, 11, 29, 23, 31] missing: [41] @@ -685,7 +685,7 @@ mod colored { .display_failures(); assert_eq!(failures, &[ - "assertion failed: expected subject is equal to [1, 3, 5, 7, 11, 13, 19, 23, 29, 31, 37]\n \ + "assertion failed: expected subject to be equal to [1, 3, 5, 7, 11, 13, 19, 23, 29, 31, 37]\n \ but was: [\u{1b}[31m13\u{1b}[0m, 5, 7, \u{1b}[31m19\u{1b}[0m, \u{1b}[31m1\u{1b}[0m, \u{1b}[31m3\u{1b}[0m, 11, \u{1b}[31m29\u{1b}[0m, 23, 31, 37] expected: [\u{1b}[34m1\u{1b}[0m, \u{1b}[34m3\u{1b}[0m, 5, 7, 11, \u{1b}[34m13\u{1b}[0m, \u{1b}[34m19\u{1b}[0m, 23, \u{1b}[34m29\u{1b}[0m, 31, 37] "