| // Copyright 2022 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| // There are no visible documentation elements in this module; the declarative |
| // macros are documented at the top level. |
| #![doc(hidden)] |
| |
| /// Checks whether the `Matcher` given by the second argument matches the first |
| /// argument. |
| /// |
| /// Evaluates to `Result::Ok(())` if the matcher matches and |
| /// `Result::Err(TestAssertionFailure)` if it does not. The caller must then |
| /// decide how to handle the `Err` variant. It has a few options: |
| /// |
| /// * Abort the current function with the `?` operator. This requires that the |
| /// function return a suitable `Result`. |
| /// * Log the test failure and continue by calling the method |
| /// `and_log_failure`. |
| /// |
| /// Of course, one can also use all other standard methods on `Result`. |
| /// |
| /// **Invoking this macro by itself does not cause a test failure to be recorded |
| /// or output.** The resulting `Result` must be handled as described above to |
| /// cause the test to be recorded as a failure. |
| /// |
| /// Example: |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// # fn should_pass() -> Result<()> { |
| /// verify_that!(42, eq(42))?; // This will pass. |
| /// # Ok(()) |
| /// # } |
| /// # should_pass().unwrap(); |
| /// # fn should_fail() -> Result<()> { |
| /// # googletest::internal::test_outcome::TestOutcome::init_current_test_outcome(); |
| /// verify_that!(42, eq(123)).and_log_failure(); |
| /// // This will log a test failure and allow execution to continue. |
| /// let _ = verify_that!(42, eq(123)); // This will do nothing. |
| /// verify_that!(42, eq(123))?; // This will fail, returning immediately. |
| /// verify_that!(42, eq(0))?; // This will not run. |
| /// # googletest::internal::test_outcome::TestOutcome::close_current_test_outcome::<&str>(Ok(())) |
| /// # .unwrap_err(); |
| /// # Ok(()) |
| /// # } |
| /// # verify_that!(should_fail(), err(displays_as(contains_substring("Expected: is equal to 123")))) |
| /// # .unwrap(); |
| /// ``` |
| /// |
| /// This macro has special support for matching against container. Namely: |
| /// * `verify_that!(actual, [m1, m2, ...])` is equivalent to |
| /// `verify_that!(actual, elements_are![m1, m2, ...])` |
| /// * `verify_that!(actual, {m1, m2, ...})` is equivalent to |
| /// `verify_that!(actual, unordered_elements_are![m1, m2, ...])` |
| /// |
| /// ## Matching against tuples |
| /// |
| /// One can match against a tuple by constructing a tuple of matchers as |
| /// follows: |
| /// |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// # fn should_pass() -> Result<()> { |
| /// verify_that!((123, 456), (eq(123), eq(456)))?; // Passes |
| /// # Ok(()) |
| /// # } |
| /// # fn should_fail() -> Result<()> { |
| /// verify_that!((123, 456), (eq(123), eq(0)))?; // Fails: second matcher does not match |
| /// # Ok(()) |
| /// # } |
| /// # should_pass().unwrap(); |
| /// # should_fail().unwrap_err(); |
| /// ``` |
| /// |
| /// This also works with composed matchers: |
| /// |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// # fn should_pass() -> Result<()> { |
| /// verify_that!((123, 456), not((eq(456), eq(123))))?; // Passes |
| /// # Ok(()) |
| /// # } |
| /// # should_pass().unwrap(); |
| /// ``` |
| /// |
| /// Matchers must correspond to the actual tuple in count and type. Otherwise |
| /// the test will fail to compile. |
| /// |
| /// ```compile_fail |
| /// # use googletest::prelude::*; |
| /// # fn should_not_compile() -> Result<()> { |
| /// verify_that!((123, 456), (eq(123),))?; // Does not compile: wrong tuple size |
| /// verify_that!((123, "A string"), (eq(123), eq(456)))?; // Does not compile: wrong type |
| /// # Ok(()) |
| /// # } |
| /// ``` |
| /// |
| /// All fields must be covered by matchers. Use |
| /// [`anything`][crate::matchers::anything] for fields which are not relevant |
| /// for the test. |
| /// |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// verify_that!((123, 456), (eq(123), anything())) |
| /// # .unwrap(); |
| /// ``` |
| /// |
| /// This supports tuples of up to 12 elements. Tuples longer than that do not |
| /// automatically inherit the `Debug` trait from their members, so are generally |
| /// not supported; see [Rust by Example](https://doc.rust-lang.org/rust-by-example/primitives/tuples.html#tuples). |
| #[macro_export] |
| macro_rules! verify_that { |
| ($actual:expr, [$($expecteds:expr),+ $(,)?]) => { |
| $crate::assertions::internal::check_matcher( |
| &$actual, |
| $crate::matchers::elements_are![$($expecteds),+], |
| stringify!($actual), |
| $crate::internal::source_location::SourceLocation::new(file!(), line!(), column!()), |
| ) |
| }; |
| ($actual:expr, {$($expecteds:expr),+ $(,)?}) => { |
| $crate::assertions::internal::check_matcher( |
| &$actual, |
| $crate::matchers::unordered_elements_are![$($expecteds),+], |
| stringify!($actual), |
| $crate::internal::source_location::SourceLocation::new(file!(), line!(), column!()), |
| ) |
| }; |
| ($actual:expr, $expected:expr $(,)?) => { |
| $crate::assertions::internal::check_matcher( |
| &$actual, |
| $expected, |
| stringify!($actual), |
| $crate::internal::source_location::SourceLocation::new(file!(), line!(), column!()), |
| ) |
| }; |
| } |
| |
| /// Asserts that the given predicate applied to the given arguments returns |
| /// true. |
| /// |
| /// Similarly to [`verify_that`], this evaluates to a `Result` whose `Ok` |
| /// variant indicates that the given predicate returned true and whose `Err` |
| /// variant indicates that it returned false. |
| /// |
| /// The failure message contains detailed information about the arguments. For |
| /// example: |
| /// |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// fn equals_modulo(a: i32, b: i32, n: i32) -> bool { a % n == b % n } |
| /// |
| /// # /* The attribute macro would prevent the function from being compiled in a doctest. |
| /// #[test] |
| /// # */ |
| /// fn test() -> Result<()> { |
| /// let a = 1; |
| /// let b = 7; |
| /// let n = 5; |
| /// verify_pred!(equals_modulo(a, b, n))?; |
| /// Ok(()) |
| /// } |
| /// # verify_that!( |
| /// # test(), |
| /// # err(displays_as(contains_substring("equals_modulo(a, b, n) was false with"))) |
| /// # ).unwrap(); |
| /// ``` |
| /// |
| /// This results in the following message: |
| /// |
| /// ```text |
| /// equals_modulo(a, b, n) was false with |
| /// a = 1, |
| /// b = 7, |
| /// n = 5 |
| /// ``` |
| /// |
| /// The function passed to this macro must return `bool`. Each of the arguments |
| /// must evaluate to a type implementing [`std::fmt::Debug`]. The debug output |
| /// is used to construct the failure message. |
| /// |
| /// The predicate can also be a method on a struct, e.g.: |
| /// |
| /// ```ignore |
| /// struct AStruct {}; |
| /// |
| /// impl AStruct { |
| /// fn equals_modulo(...) {...} |
| /// } |
| /// |
| /// verify_pred!((AStruct {}).equals_modulo(a, b, n))?; |
| /// ``` |
| /// |
| /// **Warning:** This macro assumes that the arguments passed to the predicate |
| /// are either *variables* or *calls to pure functions*. If two subsequent |
| /// invocations to any of the expresssions passed as arguments result in |
| /// different values, then the output message of a test failure will deviate |
| /// from the values actually passed to the predicate. For this reason, *always |
| /// assign the outputs of non-pure functions to variables before using them in |
| /// this macro. For example: |
| /// |
| /// ```ignore |
| /// let output = generate_random_number(); // Assigned outside of verify_pred. |
| /// verify_pred!(is_sufficiently_random(output))?; |
| /// ``` |
| #[macro_export] |
| macro_rules! verify_pred { |
| ([$($predicate:tt)*]($($arg:tt),* $(,)?)) => { |
| if !$($predicate)*($($arg),*) { |
| $crate::assertions::internal::report_failed_predicate( |
| concat!(stringify!($($predicate)*), stringify!(($($arg),*))), |
| vec![$((format!(concat!(stringify!($arg), " = {:?}"), $arg))),*], |
| $crate::internal::source_location::SourceLocation::new( |
| file!(), |
| line!(), |
| column!(), |
| ), |
| ) |
| } else { |
| Ok(()) |
| } |
| }; |
| |
| ([$($predicate:tt)*] $first:tt $($rest:tt)*) => { |
| $crate::verify_pred!([$($predicate)* $first] $($rest)*) |
| }; |
| |
| ($first:tt $($rest:tt)*) => { |
| $crate::verify_pred!([$first] $($rest)*) |
| }; |
| } |
| |
| /// Evaluates to a `Result` which contains an `Err` variant with the given test |
| /// failure message. |
| /// |
| /// This can be used to force the test to fail if its execution reaches a |
| /// particular point. For example: |
| /// |
| /// ```ignore |
| /// match some_value { |
| /// ExpectedVariant => {...} |
| /// UnwantedVaraint => { |
| /// fail!("This thing which should not happen happened anyway")?; |
| /// } |
| /// } |
| /// ``` |
| /// |
| /// One may include formatted arguments in the failure message: |
| /// |
| /// ```ignore |
| /// match some_value { |
| /// ExpectedVariant => {...} |
| /// UnwantedVaraint => { |
| /// fail!("This thing which should not happen happened anyway: {}", some_value)?; |
| /// } |
| /// } |
| /// ``` |
| /// |
| /// One may also omit the message, in which case the test failure message will |
| /// be generic: |
| /// |
| /// ```ignore |
| /// match some_value { |
| /// ExpectedVariant => {...} |
| /// UnwantedVaraint => { |
| /// fail!()?; |
| /// } |
| /// } |
| /// ``` |
| /// |
| /// Unlike `panic!` but analogously to [`verify_that`] and [`verify_pred`], this |
| /// macro has no effect on the flow of control but instead returns a `Result` |
| /// which must be handled by the invoking function. This can be done with the |
| /// question mark operator (as above) or the method |
| /// [`and_log_failure`](crate::GoogleTestSupport::and_log_failure). |
| #[macro_export] |
| macro_rules! fail { |
| ($($message:expr),+) => {{ |
| // We wrap this in a function so that we can annotate it with the must_use attribute. |
| // must_use on expressions is still experimental. |
| #[must_use = "The assertion result must be evaluated to affect the test result."] |
| fn create_fail_result(message: String) -> $crate::Result<()> { |
| Err($crate::internal::test_outcome::TestAssertionFailure::create(format!( |
| "{}\n{}", |
| message, |
| $crate::internal::source_location::SourceLocation::new( |
| file!(), |
| line!(), |
| column!(), |
| ), |
| ))) |
| } |
| create_fail_result(format!($($message),*)) |
| }}; |
| |
| () => { fail!("Test failed") }; |
| } |
| |
| /// Matches the given value against the given matcher, panicking if it does not |
| /// match. |
| /// |
| /// ```should_panic |
| /// # use googletest::prelude::*; |
| /// # fn should_fail() { |
| /// let value = 2; |
| /// assert_that!(value, eq(3)); // Fails and panics. |
| /// # } |
| /// # should_fail(); |
| /// ``` |
| /// |
| /// This is analogous to assertions in most Rust test libraries, where a failed |
| /// assertion causes a panic. |
| /// |
| /// One may optionally add arguments which will be formatted and appended to a |
| /// failure message. For example: |
| /// |
| /// ```should_panic |
| /// # use googletest::prelude::*; |
| /// # fn should_fail() { |
| /// let value = 2; |
| /// let extra_information = "Some additional information"; |
| /// assert_that!(value, eq(3), "Test failed. Extra information: {extra_information}."); |
| /// # } |
| /// # should_fail(); |
| /// ``` |
| /// |
| /// This is output as follows: |
| /// |
| /// ```text |
| /// Value of: value |
| /// Expected: is equal to 3 |
| /// Actual: 2, |
| /// which isn't equal to 3 |
| /// at ... |
| /// Test failed. Extra information: Some additional information. |
| /// ``` |
| /// |
| /// **Note for users of [GoogleTest for C++](http://google.github.io/googletest/):** |
| /// This differs from the `ASSERT_THAT` macro in that it panics rather |
| /// than triggering an early return from the invoking function. To get behaviour |
| /// equivalent to `ASSERT_THAT`, use [`verify_that!`] with the `?` operator. |
| #[macro_export] |
| macro_rules! assert_that { |
| ($actual:expr, $expected:expr $(,)?) => { |
| match $crate::verify_that!($actual, $expected) { |
| Ok(_) => {} |
| Err(e) => { |
| // The extra newline before the assertion failure message makes the failure a |
| // bit easier to read when there's some generic boilerplate from the panic. |
| panic!("\n{}", e); |
| } |
| } |
| }; |
| |
| ($actual:expr, $expected:expr, $($format_args:expr),* $(,)?) => { |
| match $crate::verify_that!($actual, $expected) |
| .with_failure_message(|| format!($($format_args),*)) |
| { |
| Ok(_) => {} |
| Err(e) => { |
| // The extra newline before the assertion failure message makes the failure a |
| // bit easier to read when there's some generic boilerplate from the panic. |
| panic!("\n{}", e); |
| } |
| } |
| }; |
| } |
| |
| /// Asserts that the given predicate applied to the given arguments returns |
| /// true, panicking if it does not. |
| /// |
| /// **Note for users of [GoogleTest for C++](http://google.github.io/googletest/):** |
| /// This differs from the `ASSERT_PRED*` family of macros in that it panics |
| /// rather than triggering an early return from the invoking function. To get |
| /// behaviour equivalent to `ASSERT_PRED*`, use [`verify_pred!`] with the `?` |
| /// operator. |
| #[macro_export] |
| macro_rules! assert_pred { |
| ($($content:tt)*) => { |
| match $crate::verify_pred!($($content)*) { |
| Ok(_) => {} |
| Err(e) => { |
| // The extra newline before the assertion failure message makes the failure a |
| // bit easier to read when there's some generic boilerplate from the panic. |
| panic!("\n{}", e); |
| } |
| } |
| }; |
| } |
| |
| /// Matches the given value against the given matcher, marking the test as |
| /// failed but continuing execution if it does not match. |
| /// |
| /// This is a *non-fatal* assertion: the test continues |
| /// execution in the event of assertion failure. |
| /// |
| /// This can only be invoked inside tests with the |
| /// [`googletest::test`][crate::test] attribute. The assertion must |
| /// occur in the same thread as that running the test itself. |
| /// |
| /// Invoking this macro is equivalent to using |
| /// [`and_log_failure`](crate::GoogleTestSupport::and_log_failure) as follows: |
| /// |
| /// ```ignore |
| /// verify_that!(actual, expected).and_log_failure() |
| /// ``` |
| /// |
| /// One may optionally add arguments which will be formatted and appended to a |
| /// failure message. For example: |
| /// |
| /// ``` |
| /// # use googletest::prelude::*; |
| /// # fn should_fail() -> std::result::Result<(), googletest::internal::test_outcome::TestFailure> { |
| /// # googletest::internal::test_outcome::TestOutcome::init_current_test_outcome(); |
| /// let value = 2; |
| /// let extra_information = "Some additional information"; |
| /// expect_that!(value, eq(3), "Test failed. Extra information: {extra_information}."); |
| /// # googletest::internal::test_outcome::TestOutcome::close_current_test_outcome::<&str>(Ok(())) |
| /// # } |
| /// # should_fail().unwrap_err(); |
| /// ``` |
| /// |
| /// This is output as follows: |
| /// |
| /// ```text |
| /// Value of: value |
| /// Expected: is equal to 3 |
| /// Actual: 2, |
| /// which isn't equal to 3 |
| /// at ... |
| /// Test failed. Extra information: Some additional information. |
| /// ``` |
| #[macro_export] |
| macro_rules! expect_that { |
| ($actual:expr, $expected:expr $(,)?) => {{ |
| use $crate::GoogleTestSupport; |
| $crate::verify_that!($actual, $expected).and_log_failure(); |
| }}; |
| |
| ($actual:expr, $expected:expr, $($format_args:expr),* $(,)?) => { |
| $crate::verify_that!($actual, $expected) |
| .with_failure_message(|| format!($($format_args),*)) |
| .and_log_failure() |
| }; |
| } |
| |
| /// Asserts that the given predicate applied to the given arguments returns |
| /// true, failing the test but continuing execution if not. |
| /// |
| /// This is a *non-fatal* predicate assertion: the test |
| /// continues execution in the event of assertion failure. |
| /// |
| /// This can only be invoked inside tests with the |
| /// [`googletest::test`][crate::test] attribute. The assertion must |
| /// occur in the same thread as that running the test itself. |
| /// |
| /// Invoking this macro is equivalent to using |
| /// [`and_log_failure`](crate::GoogleTestSupport::and_log_failure) as follows: |
| /// |
| /// ```ignore |
| /// verify_pred!(predicate(...)).and_log_failure() |
| /// ``` |
| #[macro_export] |
| macro_rules! expect_pred { |
| ($($content:tt)*) => {{ |
| use $crate::GoogleTestSupport; |
| $crate::verify_pred!($($content)*).and_log_failure(); |
| }}; |
| } |
| |
| /// Functions for use only by the procedural macros in this module. |
| /// |
| /// **For internal use only. API stablility is not guaranteed!** |
| #[doc(hidden)] |
| pub mod internal { |
| use crate::{ |
| internal::{source_location::SourceLocation, test_outcome::TestAssertionFailure}, |
| matcher::{create_assertion_failure, Matcher, MatcherResult}, |
| }; |
| use std::fmt::Debug; |
| |
| /// Checks whether the matcher `expected` matches the value `actual`, adding |
| /// a test failure report if it does not match. |
| /// |
| /// Returns `Ok(())` if the value matches and `Err(())` if it does not |
| /// match. |
| /// |
| /// **For internal use only. API stablility is not guaranteed!** |
| #[must_use = "The assertion result must be evaluated to affect the test result."] |
| pub fn check_matcher<T: Debug + ?Sized>( |
| actual: &T, |
| expected: impl Matcher<ActualT = T>, |
| actual_expr: &'static str, |
| source_location: SourceLocation, |
| ) -> Result<(), TestAssertionFailure> { |
| match expected.matches(actual) { |
| MatcherResult::Match => Ok(()), |
| MatcherResult::NoMatch => { |
| Err(create_assertion_failure(&expected, actual, actual_expr, source_location)) |
| } |
| } |
| } |
| |
| /// Constructs a `Result::Err(TestAssertionFailure)` for a predicate failure |
| /// as produced by the macro [`crate::verify_pred`]. |
| /// |
| /// This intended only for use by the macro [`crate::verify_pred`]. |
| /// |
| /// **For internal use only. API stablility is not guaranteed!** |
| #[must_use = "The assertion result must be evaluated to affect the test result."] |
| pub fn report_failed_predicate( |
| actual_expr: &'static str, |
| formatted_arguments: Vec<String>, |
| source_location: SourceLocation, |
| ) -> Result<(), TestAssertionFailure> { |
| Err(TestAssertionFailure::create(format!( |
| "{} was false with\n {}\n{}", |
| actual_expr, |
| formatted_arguments.join(",\n "), |
| source_location, |
| ))) |
| } |
| } |