| 
 | 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 | +//@ needs-target-std  | 
 | 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