use stacked_errors::{Error, UnitError};
const FILE: &str = "tests/fmt.rs";
fn scrub(s: &str) -> String {
let file = convert(FILE);
let mut res = String::new();
let mut rest = s;
while let Some(i) = rest.find(&file) {
let (before, after) = rest.split_at(i + file.len());
res.push_str(before);
let end = after
.find(|c: char| !(c == ' ' || c == ':' || c.is_ascii_digit()))
.unwrap_or(after.len());
res.push_str(" L:C");
rest = &after[end..];
}
res.push_str(rest);
res
}
fn convert(s: &str) -> String {
let s = s.to_owned();
if cfg!(windows) {
s.replace("/", "\\")
} else {
s
}
}
#[test]
fn separators() {
let e = Error::from_err("root")
.add_err("middle")
.add_err_locationless("outer");
assert_eq!(
scrub(&format!("{e}")),
convert("\n outer\n middle at tests/fmt.rs L:C\n root at tests/fmt.rs L:C")
);
}
#[test]
fn unit_errors() {
let e = Error::from_err_locationless(UnitError {}).add_err("hello");
assert_eq!(
scrub(&format!("{e}")),
convert("\n hello at tests/fmt.rs L:C")
);
let e = Error::from_err("hello").add_err_locationless(UnitError {});
assert_eq!(
scrub(&format!("{e}")),
convert("\n hello at tests/fmt.rs L:C")
);
let e = Error::new().add_err("hello");
assert_eq!(
scrub(&format!("{e}")),
convert("\n hello at tests/fmt.rs L:C\n at tests/fmt.rs L:C")
);
assert_eq!(format!("{}", Error::empty()), "");
let e = Error::from_err_locationless(UnitError {}).add_err_locationless(UnitError {});
assert_eq!(format!("{e}"), "");
}
#[test]
fn location_splitting() {
let long = "_".repeat(75);
let e = Error::from_err(long.clone());
assert_eq!(
scrub(&format!("{e}")),
convert(&format!("\n {long}\n at tests/fmt.rs L:C"))
);
let e = Error::from_err("short").add_err_locationless(long.clone());
assert_eq!(
scrub(&format!("{e}")),
convert(&format!("\n {long}\n short at tests/fmt.rs L:C"))
);
let e = Error::new().add_err_locationless(long.clone());
assert_eq!(
scrub(&format!("{e}")),
convert(&format!("\n {long}\n at tests/fmt.rs L:C"))
);
}
#[test]
fn chained_errors() {
let inner = Error::from_err("inner root").add_err("inner mid");
let e = Error::from_err("outer root").add_err(inner);
assert_eq!(
scrub(&format!("{e}")),
convert(
"\n at tests/fmt.rs L:C\n inner mid at tests/fmt.rs L:C\n inner root at \
tests/fmt.rs L:C\n outer root at tests/fmt.rs L:C"
)
);
}
#[test]
fn styling() {
let e = Error::from_err("hello").add_err_locationless(UnitError {});
let debug = format!("{e:?}");
assert_eq!(debug.contains('\u{1b}'), stacked_errors::styling_enabled());
let mut plain = String::new();
let mut in_escape = false;
for c in debug.chars() {
if in_escape {
in_escape = c != 'm';
} else if c == '\u{1b}' {
in_escape = true;
} else {
plain.push(c);
}
}
assert_eq!(plain, format!("{e}"));
}