Source code

Revision control

Copy as Markdown

Other Tools

#![allow(dead_code)]
#[macro_use]
extern crate error_chain;
#[test]
fn smoke_test_1() {
error_chain! {
types {
Error, ErrorKind, ResultExt, Result;
}
links { }
foreign_links { }
errors { }
};
}
#[test]
fn smoke_test_2() {
error_chain! {
types { }
links { }
foreign_links { }
errors { }
};
}
#[test]
fn smoke_test_3() {
error_chain! {
links { }
foreign_links { }
errors { }
};
}
#[test]
fn smoke_test_4() {
error_chain! {
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code")
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn smoke_test_5() {
error_chain! {
types { }
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code")
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn smoke_test_6() {
error_chain! {
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code")
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn smoke_test_7() {
error_chain! {
types { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code")
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn smoke_test_8() {
error_chain! {
types { }
links { }
links { }
foreign_links { }
foreign_links { }
errors {
FileNotFound
AccessDenied
}
};
}
#[test]
fn order_test_1() {
error_chain! { types { } links { } foreign_links { } errors { } };
}
#[test]
fn order_test_2() {
error_chain! { links { } types { } foreign_links { } errors { } };
}
#[test]
fn order_test_3() {
error_chain! { foreign_links { } links { } errors { } types { } };
}
#[test]
fn order_test_4() {
error_chain! { errors { } types { } foreign_links { } };
}
#[test]
fn order_test_5() {
error_chain! { foreign_links { } types { } };
}
#[test]
fn order_test_6() {
error_chain! {
links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code")
display("http request returned an unsuccessful status code: {}", e)
}
}
foreign_links { }
};
}
#[test]
fn order_test_7() {
error_chain! {
links { }
foreign_links { }
types {
Error, ErrorKind, ResultExt, Result;
}
};
}
#[test]
fn order_test_8() {
error_chain! {
links { }
foreign_links { }
foreign_links { }
types {
Error, ErrorKind, ResultExt, Result;
}
};
}
#[test]
fn empty() {
error_chain! {};
}
#[test]
#[cfg(feature = "backtrace")]
fn has_backtrace_depending_on_env() {
use std::path::PathBuf;
use std::process::Command;
let cmd_folder = if cfg!(build = "debug") {
"debug"
} else if cfg!(build = "release") {
"release"
} else {
panic!("Unknown build config");
};
let cmd_path = if cfg!(windows) {
PathBuf::from(format!(
"./target/{}/examples/has_backtrace.exe",
cmd_folder
))
} else {
PathBuf::from(format!("./target/{}/examples/has_backtrace", cmd_folder))
};
let mut cmd = Command::new(cmd_path);
// missing RUST_BACKTRACE and RUST_BACKTRACE=0
cmd.env_remove("RUST_BACKTRACE");
assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
cmd.env("RUST_BACKTRACE", "0");
assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
// RUST_BACKTRACE set to anything but 0
cmd.env("RUST_BACKTRACE", "yes");
assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
cmd.env("RUST_BACKTRACE", "1");
assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
}
#[test]
fn chain_err() {
use std::fmt;
error_chain! {
foreign_links {
Fmt(fmt::Error);
}
errors {
Test
}
}
let _: Result<()> = Err(fmt::Error).chain_err(|| "");
let _: Result<()> = Err(Error::from_kind(ErrorKind::Test)).chain_err(|| "");
}
/// Verify that an error chain is extended one by `Error::chain_err`, with
/// the new error added to the end.
#[test]
fn error_chain_err() {
error_chain! {
errors {
Test
}
}
let base = Error::from(ErrorKind::Test);
let ext = base.chain_err(|| "Test passes");
if let Error(ErrorKind::Msg(_), _) = ext {
// pass
} else {
panic!("The error should be wrapped. {:?}", ext);
}
}
#[test]
fn links() {
mod test {
error_chain! {}
}
error_chain! {
links {
Test(test::Error, test::ErrorKind);
}
}
}
#[cfg(test)]
mod foreign_link_test {
use std::fmt;
// Note: foreign errors must be `pub` because they appear in the
// signature of the public foreign_link_error_path
#[derive(Debug)]
pub struct ForeignError {
cause: ForeignErrorCause,
}
impl ::std::error::Error for ForeignError {
fn description(&self) -> &'static str {
"Foreign error description"
}
#[cfg(not(has_error_source))]
fn cause(&self) -> Option<&::std::error::Error> {
Some(&self.cause)
}
#[cfg(has_error_source)]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.cause)
}
}
impl fmt::Display for ForeignError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Foreign error display")
}
}
#[derive(Debug)]
pub struct ForeignErrorCause {}
impl ::std::error::Error for ForeignErrorCause {
fn description(&self) -> &'static str {
"Foreign error cause description"
}
#[cfg(not(has_error_source))]
fn cause(&self) -> Option<&::std::error::Error> {
None
}
#[cfg(has_error_source)]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
None
}
}
impl fmt::Display for ForeignErrorCause {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Foreign error cause display")
}
}
error_chain! {
types{
Error, ErrorKind, ResultExt, Result;
}
links {}
foreign_links {
Foreign(ForeignError);
Io(::std::io::Error);
}
errors {}
}
#[test]
fn display_underlying_error() {
let chained_error = try_foreign_error().err().unwrap();
assert_eq!(
format!(
"{}",
ForeignError {
cause: ForeignErrorCause {}
}
),
format!("{}", chained_error)
);
}
#[test]
#[cfg(not(has_error_source))]
fn finds_cause() {
let chained_error = try_foreign_error().err().unwrap();
assert_eq!(
format!("{}", ForeignErrorCause {}),
format!("{}", ::std::error::Error::cause(&chained_error).unwrap())
);
}
#[test]
#[cfg(has_error_source)]
fn finds_source() {
let chained_error = try_foreign_error().err().unwrap();
assert_eq!(
format!("{}", ForeignErrorCause {}),
format!("{}", ::std::error::Error::source(&chained_error).unwrap())
);
}
#[test]
#[allow(unknown_lints, bare_trait_objects)]
fn iterates() {
let chained_error = try_foreign_error().err().unwrap();
let mut error_iter = chained_error.iter();
assert!(!format!("{:?}", error_iter).is_empty());
assert_eq!(
format!(
"{}",
ForeignError {
cause: ForeignErrorCause {}
}
),
format!("{}", error_iter.next().unwrap())
);
assert_eq!(
format!("{}", ForeignErrorCause {}),
format!("{}", error_iter.next().unwrap())
);
assert_eq!(
format!("{:?}", None as Option<&::std::error::Error>),
format!("{:?}", error_iter.next())
);
}
fn try_foreign_error() -> Result<()> {
Err(ForeignError {
cause: ForeignErrorCause {},
})?;
Ok(())
}
}
#[cfg(test)]
mod attributes_test {
#[allow(unused_imports)]
use std::io;
#[cfg(not(test))]
mod inner {
error_chain! {}
}
error_chain! {
types {
Error, ErrorKind, ResultExt, Result;
}
links {
Inner(inner::Error, inner::ErrorKind) #[cfg(not(test))];
}
foreign_links {
Io(io::Error) #[cfg(not(test))];
}
errors {
#[cfg(not(test))]
AnError {
}
}
}
}
#[test]
fn with_result() {
error_chain! {
types {
Error, ErrorKind, ResultExt, Result;
}
}
let _: Result<()> = Ok(());
}
#[test]
fn without_result() {
error_chain! {
types {
Error, ErrorKind, ResultExt;
}
}
let _: Result<(), ()> = Ok(());
}
#[test]
fn documentation() {
mod inner {
error_chain! {}
}
error_chain! {
links {
Inner(inner::Error, inner::ErrorKind) #[doc = "Doc"];
}
foreign_links {
Io(::std::io::Error) #[doc = "Doc"];
}
errors {
/// Doc
Variant
}
}
}
#[cfg(test)]
mod multiple_error_same_mod {
error_chain! {
types {
MyError, MyErrorKind, MyResultExt, MyResult;
}
}
error_chain! {}
}
#[doc(test)]
#[deny(dead_code)]
mod allow_dead_code {
error_chain! {}
}
// Make sure links actually work!
#[test]
fn rustup_regression() {
error_chain! {
links {
Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
}
foreign_links { }
errors {
LocatingWorkingDir {
description("could not locate working directory")
}
}
}
}
#[test]
fn error_patterns() {
error_chain! {
links { }
foreign_links { }
errors { }
}
// Tuples look nice when matching errors
match Error::from("Test") {
Error(ErrorKind::Msg(_), _) => {}
_ => {}
}
}
#[test]
fn result_match() {
error_chain! {}
fn ok() -> Result<()> {
Ok(())
}
match ok() {
Ok(()) => {}
Err(Error(ErrorKind::Msg(_), _)) => {}
Err(..) => {}
}
}
#[test]
fn error_first() {
error_chain! {
errors {
LocatingWorkingDir {
description("could not locate working directory")
}
}
links {
Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
}
foreign_links { }
}
}
#[test]
fn bail() {
error_chain! {
errors { Foo }
}
fn foo() -> Result<()> {
bail!(ErrorKind::Foo)
}
fn bar() -> Result<()> {
bail!("bar")
}
fn baz() -> Result<()> {
bail!("{}", "baz")
}
}
#[test]
fn ensure() {
error_chain! {
errors { Bar }
}
fn foo(x: u8) -> Result<()> {
ensure!(x == 42, ErrorKind::Bar);
Ok(())
}
assert!(foo(42).is_ok());
assert!(foo(0).is_err());
}
/// Since the `types` declaration is a list of symbols, check if we
/// don't change their meaning or order.
#[test]
fn types_declarations() {
error_chain! {
types {
MyError, MyErrorKind, MyResultExt, MyResult;
}
}
MyError::from_kind(MyErrorKind::Msg("".into()));
let err: Result<(), ::std::io::Error> = Ok(());
MyResultExt::chain_err(err, || "").unwrap();
let _: MyResult<()> = Ok(());
}
#[test]
/// Calling chain_err over a `Result` containing an error to get a chained error
/// and constructing a MyError directly, passing it an error should be equivalent.
fn rewrapping() {
use std::env::VarError::{self, NotPresent, NotUnicode};
error_chain! {
foreign_links {
VarErr(VarError);
}
types {
MyError, MyErrorKind, MyResultExt, MyResult;
}
}
let result_a_from_func: Result<String, _> = Err(VarError::NotPresent);
let result_b_from_func: Result<String, _> = Err(VarError::NotPresent);
let our_error_a = result_a_from_func.map_err(|e| match e {
NotPresent => MyError::with_chain(e, "env var wasn't provided"),
NotUnicode(_) => MyError::with_chain(e, "env var was bork文字化ã"),
});
let our_error_b = result_b_from_func.or_else(|e| match e {
NotPresent => Err(e).chain_err(|| "env var wasn't provided"),
NotUnicode(_) => Err(e).chain_err(|| "env var was bork文字化ã"),
});
assert_eq!(
format!("{}", our_error_a.unwrap_err()),
format!("{}", our_error_b.unwrap_err())
);
}
#[test]
fn comma_in_errors_impl() {
error_chain! {
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code"),
display("http request returned an unsuccessful status code: {}", e)
}
}
};
}
#[test]
fn trailing_comma_in_errors_impl() {
error_chain! {
links { }
foreign_links { }
errors {
HttpStatus(e: u32) {
description("http request returned an unsuccessful status code"),
display("http request returned an unsuccessful status code: {}", e),
}
}
};
}
#[test]
fn skipping_msg_variant() {
error_chain! {
skip_msg_variant
errors {
MyMsg(s: String) {
description(&s)
display("{}", s)
}
}
}
let x = Error::from_kind(ErrorKind::MyMsg("some string".into()));
// This would fail to compile if we generate a `Msg` variant
match *x.kind() {
ErrorKind::MyMsg(_) => {}
ErrorKind::__Nonexhaustive {} => {}
}
}