Skip to content

Commit c0c06e4

Browse files
authored
Unrolled build for #144908
Rollup merge of #144908 - GuillaumeGomez:fix-doctest-output-json, r=fmease Fix doctest output json Fixes #144798. Hopefully it will work with the new changes in `libtest` without needing to do both at once. This PR moves the `rustdoc` merged doctest extra information directly into `libtest` to ensure they share the same rendering to prevent the bug uncovered in #144798. cc `@lolbinary` (as you reviewed the first PR) And since we're making changes to `libtest`: r? `@Amanieu`
2 parents e2c96cc + 99c7959 commit c0c06e4

File tree

3 files changed

+99
-17
lines changed

3 files changed

+99
-17
lines changed

src/librustdoc/doctest.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::process::{self, Command, Stdio};
1212
use std::sync::atomic::{AtomicUsize, Ordering};
1313
use std::sync::{Arc, Mutex};
1414
use std::time::{Duration, Instant};
15-
use std::{fmt, panic, str};
15+
use std::{panic, str};
1616

1717
pub(crate) use make::{BuildDocTestBuilder, DocTestBuilder};
1818
pub(crate) use markdown::test as test_markdown;
@@ -60,24 +60,15 @@ impl MergedDoctestTimes {
6060
self.added_compilation_times += 1;
6161
}
6262

63-
fn display_times(&self) {
63+
/// Returns `(total_time, compilation_time)`.
64+
fn times_in_secs(&self) -> Option<(f64, f64)> {
6465
// If no merged doctest was compiled, then there is nothing to display since the numbers
6566
// displayed by `libtest` for standalone tests are already accurate (they include both
6667
// compilation and runtime).
67-
if self.added_compilation_times > 0 {
68-
println!("{self}");
68+
if self.added_compilation_times == 0 {
69+
return None;
6970
}
70-
}
71-
}
72-
73-
impl fmt::Display for MergedDoctestTimes {
74-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75-
write!(
76-
f,
77-
"all doctests ran in {:.2}s; merged doctests compilation took {:.2}s",
78-
self.total_time.elapsed().as_secs_f64(),
79-
self.compilation_time.as_secs_f64(),
80-
)
71+
Some((self.total_time.elapsed().as_secs_f64(), self.compilation_time.as_secs_f64()))
8172
}
8273
}
8374

@@ -402,15 +393,20 @@ pub(crate) fn run_tests(
402393
if ran_edition_tests == 0 || !standalone_tests.is_empty() {
403394
standalone_tests.sort_by(|a, b| a.desc.name.as_slice().cmp(b.desc.name.as_slice()));
404395
test::test_main_with_exit_callback(&test_args, standalone_tests, None, || {
396+
let times = times.times_in_secs();
405397
// We ensure temp dir destructor is called.
406398
std::mem::drop(temp_dir.take());
407-
times.display_times();
399+
if let Some((total_time, compilation_time)) = times {
400+
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
401+
}
408402
});
409403
} else {
410404
// If the first condition branch exited successfully, `test_main_with_exit_callback` will
411405
// not exit the process. So to prevent displaying the times twice, we put it behind an
412406
// `else` condition.
413-
times.display_times();
407+
if let Some((total_time, compilation_time)) = times.times_in_secs() {
408+
test::print_merged_doctests_times(&test_args, total_time, compilation_time);
409+
}
414410
}
415411
// We ensure temp dir destructor is called.
416412
std::mem::drop(temp_dir);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//! ```
2+
//! let x = 12;
3+
//! ```
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//! Regression test to ensure that the output format is respected for doctests.
2+
//!
3+
//! Regression test for <https://github.com/rust-lang/rust/issues/144798>.
4+
5+
//@ ignore-cross-compile
6+
7+
use run_make_support::{rustdoc, serde_json};
8+
9+
fn run_test(edition: &str, format: Option<&str>) -> String {
10+
let mut r = rustdoc();
11+
r.input("file.rs").edition(edition).arg("--test");
12+
if let Some(format) = format {
13+
r.args(&[
14+
"--test-args",
15+
"-Zunstable-options",
16+
"--test-args",
17+
"--format",
18+
"--test-args",
19+
format,
20+
]);
21+
}
22+
r.run().stdout_utf8()
23+
}
24+
25+
fn check_json_output(edition: &str, expected_reports: usize) {
26+
let out = run_test(edition, Some("json"));
27+
let mut found_report = 0;
28+
for (line_nb, line) in out.lines().enumerate() {
29+
match serde_json::from_str::<serde_json::Value>(&line) {
30+
Ok(value) => {
31+
if value.get("type") == Some(&serde_json::json!("report")) {
32+
found_report += 1;
33+
}
34+
}
35+
Err(error) => panic!(
36+
"failed for {edition} edition (json format) at line {}: non-JSON value: {error}\n\
37+
====== output ======\n{out}",
38+
line_nb + 1,
39+
),
40+
}
41+
}
42+
if found_report != expected_reports {
43+
panic!(
44+
"failed for {edition} edition (json format): expected {expected_reports} doctest \
45+
time `report`, found {found_report}\n====== output ======\n{out}",
46+
);
47+
}
48+
}
49+
50+
fn check_non_json_output(edition: &str, expected_reports: usize) {
51+
let out = run_test(edition, None);
52+
let mut found_report = 0;
53+
for (line_nb, line) in out.lines().enumerate() {
54+
if line.starts_with('{') && serde_json::from_str::<serde_json::Value>(&line).is_ok() {
55+
panic!(
56+
"failed for {edition} edition: unexpected json at line {}: `{line}`\n\
57+
====== output ======\n{out}",
58+
line_nb + 1
59+
);
60+
}
61+
if line.starts_with("all doctests ran in")
62+
&& line.contains("; merged doctests compilation took ")
63+
{
64+
found_report += 1;
65+
}
66+
}
67+
if found_report != expected_reports {
68+
panic!(
69+
"failed for {edition} edition: expected {expected_reports} doctest time `report`, \
70+
found {found_report}\n====== output ======\n{out}",
71+
);
72+
}
73+
}
74+
75+
fn main() {
76+
// Only the merged doctests generate the "times report".
77+
check_json_output("2021", 0);
78+
check_json_output("2024", 1);
79+
80+
// Only the merged doctests generate the "times report".
81+
check_non_json_output("2021", 0);
82+
check_non_json_output("2024", 1);
83+
}

0 commit comments

Comments
 (0)