Add new test::print_merged_doctests_times used by rustdoc to display more detailed time information and add new OutputFormatter::write_merged_doctests_times method to handle it

This commit is contained in:
Guillaume Gomez
2025-08-04 16:06:56 +02:00
parent e1b9081e69
commit 75e20afb82
7 changed files with 76 additions and 11 deletions

View File

@@ -281,23 +281,15 @@ fn on_test_event(
Ok(())
}
/// A simple console test runner.
/// Runs provided tests reporting process and results to the stdout.
pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Result<bool> {
pub(crate) fn get_formatter(opts: &TestOpts, max_name_len: usize) -> Box<dyn OutputFormatter> {
let output = match term::stdout() {
None => OutputLocation::Raw(io::stdout()),
Some(t) => OutputLocation::Pretty(t),
};
let max_name_len = tests
.iter()
.max_by_key(|t| len_if_padded(t))
.map(|t| t.desc.name.as_slice().len())
.unwrap_or(0);
let is_multithreaded = opts.test_threads.unwrap_or_else(get_concurrency) > 1;
let mut out: Box<dyn OutputFormatter> = match opts.format {
match opts.format {
OutputFormat::Pretty => Box::new(PrettyFormatter::new(
output,
opts.use_color(),
@@ -310,7 +302,19 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
}
OutputFormat::Json => Box::new(JsonFormatter::new(output)),
OutputFormat::Junit => Box::new(JunitFormatter::new(output)),
};
}
}
/// A simple console test runner.
/// Runs provided tests reporting process and results to the stdout.
pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Result<bool> {
let max_name_len = tests
.iter()
.max_by_key(|t| len_if_padded(t))
.map(|t| t.desc.name.as_slice().len())
.unwrap_or(0);
let mut out = get_formatter(opts, max_name_len);
let mut st = ConsoleTestState::new(opts)?;
// Prevent the usage of `Instant` in some cases:

View File

@@ -215,6 +215,17 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
Ok(state.failed == 0)
}
fn write_merged_doctests_times(
&mut self,
total_time: f64,
compilation_time: f64,
) -> io::Result<()> {
let newline = "\n";
self.writeln_message(&format!(
r#"{{ "type": "report", "total_time": {total_time}, "compilation_time": {compilation_time} }}{newline}"#,
))
}
}
/// A formatting utility used to print strings with characters in need of escaping.

View File

@@ -182,6 +182,16 @@ impl<T: Write> OutputFormatter for JunitFormatter<T> {
Ok(state.failed == 0)
}
fn write_merged_doctests_times(
&mut self,
total_time: f64,
compilation_time: f64,
) -> io::Result<()> {
self.write_message(&format!(
"<report total_time=\"{total_time}\" compilation_time=\"{compilation_time}\"></report>\n",
))
}
}
fn parse_class_name(desc: &TestDesc) -> (String, String) {

View File

@@ -33,6 +33,11 @@ pub(crate) trait OutputFormatter {
state: &ConsoleTestState,
) -> io::Result<()>;
fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool>;
fn write_merged_doctests_times(
&mut self,
total_time: f64,
compilation_time: f64,
) -> io::Result<()>;
}
pub(crate) fn write_stderr_delimiter(test_output: &mut Vec<u8>, test_name: &TestName) {

View File

@@ -303,4 +303,14 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
Ok(success)
}
fn write_merged_doctests_times(
&mut self,
total_time: f64,
compilation_time: f64,
) -> io::Result<()> {
self.write_plain(format!(
"all doctests ran in {total_time:.2}s; merged doctests compilation took {compilation_time:.2}s\n",
))
}
}

View File

@@ -295,4 +295,14 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
Ok(success)
}
fn write_merged_doctests_times(
&mut self,
total_time: f64,
compilation_time: f64,
) -> io::Result<()> {
self.write_plain(format!(
"all doctests ran in {total_time:.2}s; merged doctests compilation took {compilation_time:.2}s\n",
))
}
}

View File

@@ -244,6 +244,21 @@ fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn {
}
}
/// Public API used by rustdoc to display the `total` and `compilation` times in the expected
/// format.
pub fn print_merged_doctests_times(args: &[String], total_time: f64, compilation_time: f64) {
let opts = match cli::parse_opts(args) {
Some(Ok(o)) => o,
Some(Err(msg)) => {
eprintln!("error: {msg}");
process::exit(ERROR_EXIT_CODE);
}
None => return,
};
let mut formatter = console::get_formatter(&opts, 0);
formatter.write_merged_doctests_times(total_time, compilation_time).unwrap();
}
/// Invoked when unit tests terminate. Returns `Result::Err` if the test is
/// considered a failure. By default, invokes `report()` and checks for a `0`
/// result.