#[macro_export]
macro_rules! assert_diagnostic {
($output:expr, $level:expr, $msg:expr) => {{
let __output = &$output;
let __diag = __output.diagnostic();
let __level = $level;
let __msg = $msg;
let __check =
|d: &$crate::Diagnostic| d.level() == __level && d.to_string().contains(__msg);
let __found = __check(__diag) || __diag.walk().any(__check);
assert!(
__found,
"no {:?} diagnostic containing {:?}\n\ndiagnostics:\n{}",
__level, __msg, __diag,
);
}};
}
#[macro_export]
macro_rules! assert_compile_error {
($output:expr, $msg:expr) => {
$crate::assert_diagnostic!($output, $crate::mark::Level::Error, $msg)
};
}
#[macro_export]
macro_rules! assert_diagnostic_error {
($output:expr, $msg:expr) => {
$crate::assert_diagnostic!($output, $crate::mark::Level::Error, $msg)
};
}
#[macro_export]
macro_rules! assert_diagnostic_warning {
($output:expr, $msg:expr) => {
$crate::assert_diagnostic!($output, $crate::mark::Level::Warning, $msg)
};
}
#[macro_export]
macro_rules! assert_diagnostic_note {
($output:expr, $msg:expr) => {
$crate::assert_diagnostic!($output, $crate::mark::Level::Note, $msg)
};
}
#[macro_export]
macro_rules! assert_diagnostic_help {
($output:expr, $msg:expr) => {
$crate::assert_diagnostic!($output, $crate::mark::Level::Help, $msg)
};
}
#[cfg(test)]
mod tests {
use crate::Output;
use crate::mark;
#[test]
fn error_diagnostic() {
let output = Output::new()
.diagnostic(mark::error("field not found"))
.build();
assert_diagnostic_error!(output, "field not found");
assert_compile_error!(output, "field not found");
}
#[test]
fn warning_diagnostic() {
let output = Output::new()
.diagnostic(mark::new().add(mark::warning("unused field")))
.build();
assert_diagnostic_warning!(output, "unused field");
}
#[test]
fn note_diagnostic() {
let output = Output::new()
.diagnostic(mark::new().add(mark::note("derived from Foo")))
.build();
assert_diagnostic_note!(output, "derived from Foo");
}
#[test]
fn help_diagnostic() {
let output = Output::new()
.diagnostic(mark::new().add(mark::help("add #[zyn(skip)]")))
.build();
assert_diagnostic_help!(output, "add #[zyn(skip)]");
}
#[test]
#[should_panic(expected = "no")]
fn missing_diagnostic() {
let output = Output::default();
assert_diagnostic_error!(output, "does not exist");
}
#[test]
fn nested_diagnostic() {
let output = Output::new()
.diagnostic(mark::new().add(mark::error("outer").add(mark::help("inner hint"))))
.build();
assert_diagnostic_help!(output, "inner hint");
}
#[test]
#[should_panic(expected = "no")]
fn empty_output_has_no_diagnostics() {
let output = Output::default();
assert_diagnostic_warning!(output, "anything");
}
#[test]
fn multiple_errors_same_level() {
let output = Output::new()
.diagnostic(
mark::new()
.add(mark::error("first"))
.add(mark::error("second"))
.add(mark::error("third")),
)
.build();
assert_diagnostic_error!(output, "first");
assert_diagnostic_error!(output, "second");
assert_diagnostic_error!(output, "third");
}
#[test]
fn partial_message_match() {
let output = Output::new()
.diagnostic(mark::error("field `name` is required"))
.build();
assert_diagnostic_error!(output, "name");
assert_diagnostic_error!(output, "required");
}
#[test]
fn all_levels_in_one_output() {
let output = Output::new()
.diagnostic(
mark::new()
.add(mark::error("err"))
.add(mark::warning("warn"))
.add(mark::note("note"))
.add(mark::help("help")),
)
.build();
assert_diagnostic_error!(output, "err");
assert_diagnostic_warning!(output, "warn");
assert_diagnostic_note!(output, "note");
assert_diagnostic_help!(output, "help");
}
#[test]
#[should_panic(expected = "no")]
fn wrong_level_does_not_match() {
let output = Output::new()
.diagnostic(mark::warning("just a warning"))
.build();
assert_diagnostic_error!(output, "just a warning");
}
}