Skip to content

Commit e42b8bb

Browse files
committed
Add support for Error Types that Don't Implement std::error::Error.
1 parent 1b119bf commit e42b8bb

File tree

3 files changed

+99
-20
lines changed

3 files changed

+99
-20
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ structmeta = "0.3.0"
2727
proptest = "1.6.0"
2828
trybuild = "1.0.96"
2929
tokio = { version = "1.38.0", features = ["rt-multi-thread"] }
30+
anyhow = "1.0.97"

src/proptest_fn.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ pub fn build_proptest(attr: TokenStream, mut item_fn: ItemFn) -> Result<TokenStr
5050
let #f = move || -> #ty {
5151
#block
5252
};
53-
::std::result::Result::map_err(#f(), ::std::convert::Into::<TestCaseError>::into)?;
53+
::std::result::Result::map_err(#f(),
54+
|e| ::proptest::test_runner::TestCaseError::fail(::std::string::ToString::to_string(&e)))?;
5455
})
5556
}
5657
}
@@ -168,7 +169,8 @@ impl Async {
168169
body = quote! { #block };
169170
output_type = quote!(#ty);
170171
ret_expr = quote! {
171-
::std::result::Result::map_err(ret, ::std::convert::Into::<TestCaseError>::into)?
172+
::std::result::Result::map_err(ret,
173+
|e| ::proptest::test_runner::TestCaseError::fail(::std::string::ToString::to_string(&e)))?
172174
};
173175
}
174176
}

tests/proptest_fn.rs

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ struct NotImplError1;
123123
#[derive(Debug)]
124124
struct CustomError(#[allow(dead_code)] TestCaseError);
125125

126+
impl CustomError {
127+
fn new() -> Self {
128+
CustomError(TestCaseError::fail("Custom"))
129+
}
130+
}
131+
126132
impl std::error::Error for CustomError {}
127133
impl std::fmt::Display for CustomError {
128134
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -145,9 +151,9 @@ impl From<NotImplError1> for CustomError {
145151
}
146152
}
147153

148-
macro_rules! prop_assert2 {
154+
macro_rules! prop_assert_custom {
149155
($cond:expr) => {
150-
prop_assert2!($cond, concat!("assertion failed: ", stringify!($cond)))
156+
prop_assert_custom!($cond, concat!("assertion failed: ", stringify!($cond)))
151157
};
152158
($cond:expr, $($fmt:tt)*) => {
153159
if !$cond {
@@ -160,58 +166,128 @@ macro_rules! prop_assert2 {
160166

161167
#[proptest]
162168
fn custom_error_ok(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
163-
prop_assert2!(x < 10);
169+
prop_assert_custom!(x < 10);
164170
not_impl_error_ok()?;
165171
Ok(())
166172
}
173+
#[proptest(async = "tokio")]
174+
async fn custom_error_ok_async(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
175+
prop_assert_custom!(x < 10);
176+
not_impl_error_ok()?;
177+
yield_now().await;
178+
Ok(())
179+
}
167180

168181
#[should_panic]
169182
#[proptest]
170-
fn custom_error_ok_prop_assesrt_fail(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
171-
prop_assert2!(x >= 10);
183+
fn custom_error_prop_assesrt_fail(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
184+
prop_assert_custom!(x >= 10);
172185
Ok(())
173186
}
174187

175188
#[proptest]
176189
#[should_panic]
177190
fn custom_error_err(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
178-
prop_assert2!(x < 10);
191+
prop_assert_custom!(x < 10);
179192
not_impl_error_err()?;
180193
Ok(())
181194
}
182195

196+
#[proptest(async = "tokio")]
197+
#[should_panic]
198+
async fn custom_error_err_async(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
199+
prop_assert_custom!(x < 10);
200+
not_impl_error_err()?;
201+
yield_now().await;
202+
Ok(())
203+
}
204+
183205
#[proptest]
184206
fn custom_error_ok_2(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
185-
prop_assert2!(x < 10);
207+
prop_assert_custom!(x < 10);
186208
not_impl_error_ok()?;
187209
not_impl_error_ok_1()?;
188210
Ok(())
189211
}
190212

213+
fn not_impl_error_ok() -> Result<(), NotImplError0> {
214+
Ok(())
215+
}
216+
fn not_impl_error_err() -> Result<(), NotImplError0> {
217+
Err(NotImplError0)
218+
}
219+
220+
fn not_impl_error_ok_1() -> Result<(), NotImplError1> {
221+
Ok(())
222+
}
223+
224+
macro_rules! prop_assert_anyhow {
225+
($cond:expr) => {
226+
prop_assert_anyhow!($cond, concat!("assertion failed: ", stringify!($cond)))
227+
};
228+
($cond:expr, $($fmt:tt)*) => {
229+
if !$cond {
230+
anyhow::bail!("{} at {}:{}", format!($($fmt)*), file!(), line!());
231+
}
232+
};
233+
}
234+
235+
#[proptest]
236+
fn anyhow_result_ok(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
237+
prop_assert_anyhow!(x < 10);
238+
Ok(())
239+
}
240+
191241
#[proptest(async = "tokio")]
192-
async fn custom_error_async_ok(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
193-
prop_assert2!(x < 10);
194-
not_impl_error_ok()?;
242+
async fn anyhow_result_ok_async(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
243+
prop_assert_anyhow!(x < 10);
195244
yield_now().await;
196245
Ok(())
197246
}
198247

248+
#[proptest]
249+
#[should_panic]
250+
fn anyhow_result_prop_assert_fail(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
251+
prop_assert_anyhow!(x >= 10);
252+
Ok(())
253+
}
254+
199255
#[proptest(async = "tokio")]
200256
#[should_panic]
201-
async fn custom_error_async_err(#[strategy(1..10u8)] x: u8) -> Result<(), CustomError> {
202-
prop_assert2!(x < 10);
203-
not_impl_error_err()?;
257+
async fn anyhow_result_prop_assert_fail_async(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
258+
prop_assert_anyhow!(x >= 10);
204259
yield_now().await;
205260
Ok(())
206261
}
207262

208-
fn not_impl_error_ok() -> Result<(), NotImplError0> {
263+
#[proptest]
264+
#[should_panic]
265+
fn anyhow_result_err(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
266+
prop_assert_anyhow!(x < 10);
267+
Err(CustomError::new())?;
209268
Ok(())
210269
}
211-
fn not_impl_error_err() -> Result<(), NotImplError0> {
212-
Err(NotImplError0)
213-
}
214270

215-
fn not_impl_error_ok_1() -> Result<(), NotImplError1> {
271+
#[proptest(async = "tokio")]
272+
#[should_panic]
273+
async fn anyhow_result_err_async(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
274+
prop_assert_anyhow!(x < 10);
275+
Err(CustomError::new())?;
276+
yield_now().await;
216277
Ok(())
217278
}
279+
280+
#[proptest]
281+
#[should_panic]
282+
fn anyhow_result_bail(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
283+
prop_assert_anyhow!(x < 10);
284+
anyhow::bail!("error");
285+
}
286+
287+
#[proptest(async = "tokio")]
288+
#[should_panic]
289+
async fn anyhow_result_bail_async(#[strategy(1..10u8)] x: u8) -> anyhow::Result<()> {
290+
prop_assert_anyhow!(x < 10);
291+
yield_now().await;
292+
anyhow::bail!("error");
293+
}

0 commit comments

Comments
 (0)