#[cfg(test)]
mod tests;
use stilo::{style, stylize, writeln_styles, Style};
use super::Outcome;
use crate::{
outcome::{FailKind::*, Message::*, Note, PassStatus::*, TestOutcome},
DisplayLevel::{self, *},
};
fn _color(text: &str, style: Style, do_color: bool) -> String {
if do_color {
style.format(text)
} else {
text.into()
}
}
impl Outcome {
pub fn max_word_len(&self, display_level: DisplayLevel) -> usize {
self.messages
.iter()
.map(|msg| match msg {
Test(TestOutcome { word, status, .. }) => match display_level {
ShowAll => word.chars().count(),
IgnorePasses | OnlyFails if status.is_fail() => word.chars().count(),
_ => 0,
},
Info(_) => 0,
})
.max()
.unwrap_or(0)
}
pub fn test_count(&self) -> usize {
self.messages.iter().filter(|item| item.is_test()).count()
}
pub fn display(&self, display_level: DisplayLevel, do_color: bool) {
self.display_with(&mut std::io::stdout(), display_level, do_color)
.expect("Could not write to stdout");
}
pub fn display_with(
&self,
out: &mut dyn std::io::Write,
display_level: DisplayLevel,
do_color: bool,
) -> Result<(), std::io::Error> {
let test_count = self.test_count();
if self.test_count() == 0 {
writeln_styles!(out, "No tests ran": Yellow if do_color)?;
return Ok(());
}
writeln_styles!(
out,
"Running {} test{}...":
Yellow if do_color,
test_count, pluralize(test_count)
)?;
let max_word_len = self.max_word_len(display_level);
for msg in &self.messages {
match msg {
Info(Note(note)) => match display_level {
ShowAll | IgnorePasses => {
writeln_styles!(out, "{}": Blue if do_color, note)?;
}
_ => (),
},
Test(TestOutcome {
word,
intent,
status,
}) => {
match display_level {
ShowAll => (),
IgnorePasses | OnlyFails if status.is_fail() => (),
_ => continue,
};
let reason = match status {
Pass => String::new(),
Fail(ShouldBeInvalid) => {
stylize!("Valid, but should be invalid": Yellow if do_color)
}
Fail(NoReasonGiven) => stylize!("No reason given": + italic),
Fail(CustomReason(Note(reason))) => String::from(reason),
};
writeln!(
out,
" {intent} {word}{space} {status} {reason}",
intent = if *intent {
stylize!("✔": Cyan if do_color)
} else {
stylize!("✘": Magenta if do_color)
},
space = " ".repeat(max_word_len - word.chars().count()),
status = if status.is_pass() {
stylize!(
"pass":
{
if self.fail_count == 0 {
style!(Green)
} else {
style!(Green + dim)
}
}
if do_color
)
} else {
stylize!("FAIL": Red + bold if do_color)
},
)?;
}
}
}
if self.fail_count == 0 {
writeln_styles!(out, "All tests pass!": Green + bold if do_color)?;
} else {
writeln_styles!(out, "{} test{} failed": Red + bold if do_color, self.fail_count, pluralize(self.fail_count))?;
}
Ok(())
}
}
fn pluralize(number: usize) -> &'static str {
if number == 1 {
""
} else {
"s"
}
}