diff --git a/proptest/src/prelude.rs b/proptest/src/prelude.rs index 8bdfd5db..e0d7650d 100644 --- a/proptest/src/prelude.rs +++ b/proptest/src/prelude.rs @@ -23,7 +23,7 @@ pub use crate::arbitrary::{any, any_with, Arbitrary}; pub use crate::strategy::{BoxedStrategy, Just, SBoxedStrategy, Strategy}; pub use crate::test_runner::Config as ProptestConfig; -pub use crate::test_runner::TestCaseError; +pub use crate::test_runner::{TestCaseError, ResultExt}; pub use crate::{ prop_assert, prop_assert_eq, prop_assert_ne, prop_assume, prop_compose, prop_oneof, proptest, diff --git a/proptest/src/test_runner/errors.rs b/proptest/src/test_runner/errors.rs index bf17f201..de7e8729 100644 --- a/proptest/src/test_runner/errors.rs +++ b/proptest/src/test_runner/errors.rs @@ -132,3 +132,48 @@ impl ::std::error::Error for TestError { } } } + +/// Extension trait for `Result` to provide additional functionality +/// specifically for prop test cases. +pub trait ResultExt { + /// Converts a `Result` into a `Result`, where the + /// `Err` case is transformed into a `TestCaseError::Reject`. + /// + /// This is intended to be used like the [`prop_assume!`] macro, but for + /// fallible computations. If the result is `Err`, the test input is rejected + /// and a new input will be generated. + /// + /// ## Example + /// + /// ``` + /// use proptest::prelude::*; + /// proptest! { + /// #[test] + /// fn test_that_only_works_with_positive_integers(a in -10i32..10i32) { + /// // Reject the case if `a` cannot be converted to u8 (e.g., negative values) + /// let _unsigned: u8 = a.try_into().assume_ok()?; + /// // ...rest of test... + /// } + /// } + /// # + /// # fn main() { test_signed_to_unsigned(); } + /// ``` + /// + /// [`prop_assume!`]: crate::prop_assume + fn assume_ok(self) -> Result + where + E: fmt::Debug; +} + +impl ResultExt for Result { + #[track_caller] + fn assume_ok(self) -> Result + where + E: fmt::Debug, + { + let location = core::panic::Location::caller(); + self.map_err(|err| { + TestCaseError::reject(format!("{location}: {err:?}")) + }) + } +}