|  | 
|  | 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 | +use run_make_support::{rustdoc, serde_json}; | 
|  | 6 | + | 
|  | 7 | +fn run_test(edition: &str, format: Option<&str>) -> String { | 
|  | 8 | +    let mut r = rustdoc(); | 
|  | 9 | +    r.input("file.rs").edition(edition).arg("--test"); | 
|  | 10 | +    if let Some(format) = format { | 
|  | 11 | +        r.args(&["--test-args", "-Zunstable-options"]).args(&[ | 
|  | 12 | +            "--test-args", | 
|  | 13 | +            "--format", | 
|  | 14 | +            "--test-args", | 
|  | 15 | +            format, | 
|  | 16 | +        ]); | 
|  | 17 | +    } | 
|  | 18 | +    r.run().stdout_utf8() | 
|  | 19 | +} | 
|  | 20 | + | 
|  | 21 | +fn check_json_output(edition: &str, expected_reports: usize) { | 
|  | 22 | +    let out = run_test(edition, Some("json")); | 
|  | 23 | +    let mut found_report = 0; | 
|  | 24 | +    for (line_nb, line) in out.lines().enumerate() { | 
|  | 25 | +        match serde_json::from_str::<serde_json::Value>(&line) { | 
|  | 26 | +            Ok(value) => { | 
|  | 27 | +                if value.get("type") == Some(&serde_json::json!("report")) { | 
|  | 28 | +                    found_report += 1; | 
|  | 29 | +                } | 
|  | 30 | +            } | 
|  | 31 | +            Err(error) => panic!( | 
|  | 32 | +                "failed for {edition} edition (json format) at line {}: non-JSON value: {error}\n\ | 
|  | 33 | +                ====== output ======\n{out}", | 
|  | 34 | +                line_nb + 1, | 
|  | 35 | +            ), | 
|  | 36 | +        } | 
|  | 37 | +    } | 
|  | 38 | +    if found_report != expected_reports { | 
|  | 39 | +        panic!( | 
|  | 40 | +            "failed for {edition} edition (json format): expected {expected_reports} doctest \ | 
|  | 41 | +             time `report`, found {found_report}\n====== output ======\n{out}", | 
|  | 42 | +        ); | 
|  | 43 | +    } | 
|  | 44 | +} | 
|  | 45 | + | 
|  | 46 | +fn check_non_json_output(edition: &str, expected_reports: usize) { | 
|  | 47 | +    let out = run_test(edition, None); | 
|  | 48 | +    let mut found_report = 0; | 
|  | 49 | +    for (line_nb, line) in out.lines().enumerate() { | 
|  | 50 | +        if line.starts_with('{') && serde_json::from_str::<serde_json::Value>(&line).is_ok() { | 
|  | 51 | +            panic!( | 
|  | 52 | +                "failed for {edition} edition: unexpected json at line {}: `{line}`\n\ | 
|  | 53 | +                 ====== output ======\n{out}", | 
|  | 54 | +                line_nb + 1 | 
|  | 55 | +            ); | 
|  | 56 | +        } | 
|  | 57 | +        if line.starts_with("all doctests ran in") | 
|  | 58 | +            && line.contains("; merged doctests compilation took ") | 
|  | 59 | +        { | 
|  | 60 | +            found_report += 1; | 
|  | 61 | +        } | 
|  | 62 | +    } | 
|  | 63 | +    if found_report != expected_reports { | 
|  | 64 | +        panic!( | 
|  | 65 | +            "failed for {edition} edition: expected {expected_reports} doctest time `report`, \ | 
|  | 66 | +             found {found_report}\n====== output ======\n{out}", | 
|  | 67 | +        ); | 
|  | 68 | +    } | 
|  | 69 | +} | 
|  | 70 | + | 
|  | 71 | +fn main() { | 
|  | 72 | +    // Only the merged doctests generate the "times report". | 
|  | 73 | +    check_json_output("2021", 0); | 
|  | 74 | +    check_json_output("2024", 1); | 
|  | 75 | + | 
|  | 76 | +    // Only the merged doctests generate the "times report". | 
|  | 77 | +    check_non_json_output("2021", 0); | 
|  | 78 | +    check_non_json_output("2024", 1); | 
|  | 79 | +} | 
0 commit comments