Skip to main content

compiletest/runtest/
pretty.rs

1use std::fs;
2
3use super::{ProcRes, ReadFrom, TestCx};
4
5impl TestCx<'_> {
6    pub(super) fn run_pretty_test(&self) {
7        if self.props.pp_exact.is_some() {
8            self.logv("testing for exact pretty-printing");
9        } else {
10            self.logv("testing for converging pretty-printing");
11        }
12
13        let rounds = match self.props.pp_exact {
14            Some(_) => 1,
15            None => 2,
16        };
17
18        let src = fs::read_to_string(&self.testpaths.file).unwrap();
19        let mut srcs = vec![src];
20
21        let mut round = 0;
22        while round < rounds {
23            self.logv(format_args!(
24                "pretty-printing round {round} revision {:?}",
25                self.variant.revision
26            ));
27            let read_from =
28                if round == 0 { ReadFrom::Path } else { ReadFrom::Stdin(srcs[round].to_owned()) };
29
30            let proc_res = self.print_source(read_from, &self.props.pretty_mode);
31            if !proc_res.status.success() {
32                self.fatal_proc_rec(
33                    &format!(
34                        "pretty-printing failed in round {} revision {:?}",
35                        round, self.variant.revision
36                    ),
37                    &proc_res,
38                );
39            }
40
41            let ProcRes { stdout, .. } = proc_res;
42            srcs.push(stdout);
43            round += 1;
44        }
45
46        let mut expected = match self.props.pp_exact {
47            Some(ref file) => {
48                let filepath = self.testpaths.file.parent().unwrap().join(file);
49                fs::read_to_string(&filepath).unwrap()
50            }
51            None => srcs[srcs.len() - 2].clone(),
52        };
53        let mut actual = srcs[srcs.len() - 1].clone();
54
55        if self.props.pp_exact.is_some() {
56            // Now we have to care about line endings
57            let cr = "\r".to_owned();
58            actual = actual.replace(&cr, "");
59            expected = expected.replace(&cr, "");
60        }
61
62        if !self.config.bless {
63            self.compare_source(&expected, &actual);
64        } else if expected != actual {
65            let filepath_buf;
66            let filepath = match &self.props.pp_exact {
67                Some(file) => {
68                    filepath_buf = self.testpaths.file.parent().unwrap().join(file);
69                    &filepath_buf
70                }
71                None => &self.testpaths.file,
72            };
73            fs::write(filepath, &actual).unwrap();
74        }
75
76        // If we're only making sure that the output matches then just stop here
77        if self.props.pretty_compare_only {
78            return;
79        }
80
81        // Finally, let's make sure it actually appears to remain valid code
82        let proc_res = self.typecheck_source(actual);
83        if !proc_res.status.success() {
84            self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
85        }
86    }
87}