-use super::*;
+use std::{
+ io,
+ io::prelude::Write,
+};
+
+use crate::{
+ types::TestDesc,
+ time,
+ test_result::TestResult,
+ console::{ConsoleTestState, OutputLocation},
+ bench::fmt_bench_samples,
+};
+use super::OutputFormatter;
pub(crate) struct PrettyFormatter<T> {
out: OutputLocation<T>,
use_color: bool,
+ time_options: Option<time::TestTimeOptions>,
/// Number of columns to fill when aligning names
max_name_len: usize,
use_color: bool,
max_name_len: usize,
is_multithreaded: bool,
+ time_options: Option<time::TestTimeOptions>,
) -> Self {
PrettyFormatter {
out,
use_color,
max_name_len,
is_multithreaded,
+ time_options
}
}
&self.out
}
- pub fn write_ok(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
- self.write_short_result("ok", term::color::GREEN, exec_time)
+ pub fn write_ok(&mut self) -> io::Result<()> {
+ self.write_short_result("ok", term::color::GREEN)
}
- pub fn write_failed(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
- self.write_short_result("FAILED", term::color::RED, exec_time)
+ pub fn write_failed(&mut self) -> io::Result<()> {
+ self.write_short_result("FAILED", term::color::RED)
}
- pub fn write_ignored(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
- self.write_short_result("ignored", term::color::YELLOW, exec_time)
+ pub fn write_ignored(&mut self) -> io::Result<()> {
+ self.write_short_result("ignored", term::color::YELLOW)
}
- pub fn write_allowed_fail(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> {
- self.write_short_result("FAILED (allowed)", term::color::YELLOW, exec_time)
+ pub fn write_allowed_fail(&mut self) -> io::Result<()> {
+ self.write_short_result("FAILED (allowed)", term::color::YELLOW)
+ }
+
+ pub fn write_time_failed(&mut self) -> io::Result<()> {
+ self.write_short_result("FAILED (time limit exceeded)", term::color::RED)
}
pub fn write_bench(&mut self) -> io::Result<()> {
&mut self,
result: &str,
color: term::color::Color,
- exec_time: Option<&TestExecTime>,
) -> io::Result<()> {
- self.write_pretty(result, color)?;
- if let Some(exec_time) = exec_time {
- self.write_plain(format!(" {}", exec_time))?;
- }
- self.write_plain("\n")
+ self.write_pretty(result, color)
}
pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> {
match self.out {
- Pretty(ref mut term) => {
+ OutputLocation::Pretty(ref mut term) => {
if self.use_color {
term.fg(color)?;
}
}
term.flush()
}
- Raw(ref mut stdout) => {
+ OutputLocation::Raw(ref mut stdout) => {
stdout.write_all(word.as_bytes())?;
stdout.flush()
}
self.out.flush()
}
- pub fn write_successes(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nsuccesses:\n")?;
- let mut successes = Vec::new();
+ fn write_time(
+ &mut self,
+ desc: &TestDesc,
+ exec_time: Option<&time::TestExecTime>
+ ) -> io::Result<()> {
+ if let (Some(opts), Some(time)) = (self.time_options, exec_time) {
+ let time_str = format!(" <{}>", time);
+
+ let color = if opts.colored {
+ if opts.is_critical(desc, time) {
+ Some(term::color::RED)
+ } else if opts.is_warn(desc, time) {
+ Some(term::color::YELLOW)
+ } else {
+ None
+ }
+ } else {
+ None
+ };
+
+ match color {
+ Some(color) => self.write_pretty(&time_str, color)?,
+ None => self.write_plain(&time_str)?
+ }
+ }
+
+ Ok(())
+ }
+
+ fn write_results(
+ &mut self,
+ inputs: &Vec<(TestDesc, Vec<u8>)>,
+ results_type: &str
+ ) -> io::Result<()> {
+ let results_out_str = format!("\n{}:\n", results_type);
+
+ self.write_plain(&results_out_str)?;
+
+ let mut results = Vec::new();
let mut stdouts = String::new();
- for &(ref f, ref stdout) in &state.not_failures {
- successes.push(f.name.to_string());
+ for &(ref f, ref stdout) in inputs {
+ results.push(f.name.to_string());
if !stdout.is_empty() {
stdouts.push_str(&format!("---- {} stdout ----\n", f.name));
let output = String::from_utf8_lossy(stdout);
self.write_plain(&stdouts)?;
}
- self.write_plain("\nsuccesses:\n")?;
- successes.sort();
- for name in &successes {
+ self.write_plain(&results_out_str)?;
+ results.sort();
+ for name in &results {
self.write_plain(&format!(" {}\n", name))?;
}
Ok(())
}
+ pub fn write_successes(&mut self, state: &ConsoleTestState) -> io::Result<()> {
+ self.write_results(&state.not_failures, "successes")
+ }
+
pub fn write_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nfailures:\n")?;
- let mut failures = Vec::new();
- let mut fail_out = String::new();
- for &(ref f, ref stdout) in &state.failures {
- failures.push(f.name.to_string());
- if !stdout.is_empty() {
- fail_out.push_str(&format!("---- {} stdout ----\n", f.name));
- let output = String::from_utf8_lossy(stdout);
- fail_out.push_str(&output);
- fail_out.push_str("\n");
- }
- }
- if !fail_out.is_empty() {
- self.write_plain("\n")?;
- self.write_plain(&fail_out)?;
- }
+ self.write_results(&state.failures, "failures")
+ }
- self.write_plain("\nfailures:\n")?;
- failures.sort();
- for name in &failures {
- self.write_plain(&format!(" {}\n", name))?;
- }
- Ok(())
+ pub fn write_time_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> {
+ self.write_results(&state.time_failures, "failures (time limit exceeded)")
}
fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> {
&mut self,
desc: &TestDesc,
result: &TestResult,
- exec_time: Option<&TestExecTime>,
+ exec_time: Option<&time::TestExecTime>,
_: &[u8],
_: &ConsoleTestState,
) -> io::Result<()> {
}
match *result {
- TrOk => self.write_ok(exec_time),
- TrFailed | TrFailedMsg(_) => self.write_failed(exec_time),
- TrIgnored => self.write_ignored(exec_time),
- TrAllowedFail => self.write_allowed_fail(exec_time),
- TrBench(ref bs) => {
+ TestResult::TrOk => self.write_ok()?,
+ TestResult::TrFailed | TestResult::TrFailedMsg(_) => self.write_failed()?,
+ TestResult::TrIgnored => self.write_ignored()?,
+ TestResult::TrAllowedFail => self.write_allowed_fail()?,
+ TestResult::TrBench(ref bs) => {
self.write_bench()?;
- self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
+ self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
}
+ TestResult::TrTimedFail => self.write_time_failed()?,
}
+
+ self.write_time(desc, exec_time)?;
+ self.write_plain("\n")
}
fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
self.write_plain(&format!(
"test {} has been running for over {} seconds\n",
- desc.name, TEST_WARN_TIMEOUT_S
+ desc.name, time::TEST_WARN_TIMEOUT_S
))
}
}
let success = state.failed == 0;
if !success {
- self.write_failures(state)?;
+ if !state.failures.is_empty() {
+ self.write_failures(state)?;
+ }
+
+ if !state.time_failures.is_empty() {
+ self.write_time_failures(state)?;
+ }
}
self.write_plain("\ntest result: ")?;