| #![allow( | |
| clippy::assertions_on_result_states, | |
| clippy::eq_op, | |
| clippy::items_after_statements, | |
| clippy::needless_pass_by_value, | |
| clippy::shadow_unrelated, | |
| clippy::wildcard_imports | |
| )] | |
| mod common; | |
| use self::common::*; | |
| use anyhow::{anyhow, ensure}; | |
| use std::cell::Cell; | |
| use std::future; | |
| #[test] | |
| fn test_messages() { | |
| assert_eq!("oh no!", bail_literal().unwrap_err().to_string()); | |
| assert_eq!("oh no!", bail_fmt().unwrap_err().to_string()); | |
| assert_eq!("oh no!", bail_error().unwrap_err().to_string()); | |
| } | |
| #[test] | |
| fn test_ensure() { | |
| let f = || { | |
| ensure!(1 + 1 == 2, "This is correct"); | |
| Ok(()) | |
| }; | |
| assert!(f().is_ok()); | |
| let v = 1; | |
| let f = || { | |
| ensure!(v + v == 2, "This is correct, v: {}", v); | |
| Ok(()) | |
| }; | |
| assert!(f().is_ok()); | |
| let f = || { | |
| ensure!(v + v == 1, "This is not correct, v: {}", v); | |
| Ok(()) | |
| }; | |
| assert!(f().is_err()); | |
| let f = || { | |
| ensure!(v + v == 1); | |
| Ok(()) | |
| }; | |
| assert_eq!( | |
| f().unwrap_err().to_string(), | |
| "Condition failed: `v + v == 1` (2 vs 1)", | |
| ); | |
| } | |
| #[test] | |
| fn test_temporaries() { | |
| fn require_send_sync(_: impl Send + Sync) {} | |
| require_send_sync(async { | |
| // If anyhow hasn't dropped any temporary format_args it creates by the | |
| // time it's done evaluating, those will stick around until the | |
| // semicolon, which is on the other side of the await point, making the | |
| // enclosing future non-Send. | |
| future::ready(anyhow!("...")).await; | |
| }); | |
| fn message(cell: Cell<&str>) -> &str { | |
| cell.get() | |
| } | |
| require_send_sync(async { | |
| future::ready(anyhow!(message(Cell::new("...")))).await; | |
| }); | |
| } | |
| #[test] | |
| fn test_brace_escape() { | |
| let err = anyhow!("unterminated ${{..}} expression"); | |
| assert_eq!("unterminated ${..} expression", err.to_string()); | |
| } |