Skip to content

Commit

Permalink
Introduce a function verify_current_test_outcome.
Browse files Browse the repository at this point in the history
This allows a test to check whether the current test has passed or failed based on non-fatal assertions such as `expect_that!`. Its naming follows the pattern of `verify_that!` since it uses the same idiom of returning a `googletest::Result`.
  • Loading branch information
hovinen committed Jul 21, 2023
1 parent 5351320 commit 978f6d1
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
14 changes: 14 additions & 0 deletions googletest/src/internal/test_outcome.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ impl TestOutcome {
})
}

/// Returns a `Result` corresponding to the outcome of the currently running
/// test.
pub(crate) fn get_current_test_outcome() -> Result<(), TestAssertionFailure> {
TestOutcome::with_current_test_outcome(|mut outcome| {
let outcome = outcome
.as_mut()
.expect("No test context found. This indicates a bug in GoogleTest.");
match outcome {
TestOutcome::Success => Ok(()),
TestOutcome::Failure => Err(TestAssertionFailure::create("Test failed".into())),
}
})
}

/// Records that the currently running test has failed.
fn fail_current_test() {
TestOutcome::with_current_test_outcome(|mut outcome| {
Expand Down
34 changes: 34 additions & 0 deletions googletest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub mod matchers;
pub mod prelude {
pub use super::matcher::Matcher;
pub use super::matchers::*;
pub use super::verify_current_test_outcome;
pub use super::GoogleTestSupport;
pub use super::IntoTestResult;
pub use super::Result;
Expand Down Expand Up @@ -83,6 +84,39 @@ use internal::test_outcome::{TestAssertionFailure, TestOutcome};
/// failed but allow it to continue running, are not encoded in this type.
pub type Result<T> = std::result::Result<T, TestAssertionFailure>;

/// Returns a [`Result`] corresponding to the outcome of the currently running
/// test.
///
/// This returns `Result::Err` precisely if the current test has recorded at
/// least one test assertion failure via [`expect_that!`][crate::expect_that],
/// [`expect_pred!`][crate::expect_pred], or
/// [`GoogleTestSupport::and_log_failure`]. It can be used in concert with the
/// `?` operator to continue execution of the test conditionally on there not
/// having been any failure yet.
///
/// This requires the use of the [`#[googletest::test]`][crate::test] attribute
/// macro.
///
/// ```
/// # use googletest::prelude::*;
/// # /* Make sure this also compiles as a doctest.
/// #[googletest::test]
/// # */
/// # fn foo() -> u32 { 1 }
/// # fn bar() -> u32 { 2 }
/// fn should_fail_and_not_execute_last_assertion() -> Result<()> {
/// # googletest::internal::test_outcome::TestOutcome::init_current_test_outcome();
/// expect_that!(foo(), eq(2)); // May fail, but will not abort the test.
/// expect_that!(bar(), gt(1)); // May fail, but will not abort the test.
/// verify_current_test_outcome()?; // Aborts the test if one of the previous assertions failed.
/// verify_that!(foo(), gt(0)) // Does not execute.
/// }
/// # verify_that!(should_fail_and_not_execute_last_assertion(), err(displays_as(contains_substring("Test failed")))).unwrap();
/// ```
pub fn verify_current_test_outcome() -> Result<()> {
TestOutcome::get_current_test_outcome()
}

/// Adds to `Result` support for GoogleTest Rust functionality.
pub trait GoogleTestSupport {
/// If `self` is a `Result::Err`, writes to `stdout` a failure report
Expand Down

0 comments on commit 978f6d1

Please sign in to comment.