]> git.lizzy.rs Git - rust.git/blob - src/tools/rustfmt/tests/rustfmt/main.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / src / tools / rustfmt / tests / rustfmt / main.rs
1 //! Integration tests for rustfmt.
2
3 use std::env;
4 use std::fs::remove_file;
5 use std::path::Path;
6 use std::process::Command;
7
8 use rustfmt_config_proc_macro::rustfmt_only_ci_test;
9
10 /// Run the rustfmt executable and return its output.
11 fn rustfmt(args: &[&str]) -> (String, String) {
12     let mut bin_dir = env::current_exe().unwrap();
13     bin_dir.pop(); // chop off test exe name
14     if bin_dir.ends_with("deps") {
15         bin_dir.pop();
16     }
17     let cmd = bin_dir.join(format!("rustfmt{}", env::consts::EXE_SUFFIX));
18
19     // Ensure the rustfmt binary runs from the local target dir.
20     let path = env::var_os("PATH").unwrap_or_default();
21     let mut paths = env::split_paths(&path).collect::<Vec<_>>();
22     paths.insert(0, bin_dir);
23     let new_path = env::join_paths(paths).unwrap();
24
25     match Command::new(&cmd).args(args).env("PATH", new_path).output() {
26         Ok(output) => (
27             String::from_utf8(output.stdout).expect("utf-8"),
28             String::from_utf8(output.stderr).expect("utf-8"),
29         ),
30         Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e),
31     }
32 }
33
34 macro_rules! assert_that {
35     ($args:expr, $($check:ident $check_args:tt)&&+) => {
36         let (stdout, stderr) = rustfmt($args);
37         if $(!stdout.$check$check_args && !stderr.$check$check_args)||* {
38             panic!(
39                 "Output not expected for rustfmt {:?}\n\
40                  expected: {}\n\
41                  actual stdout:\n{}\n\
42                  actual stderr:\n{}",
43                 $args,
44                 stringify!($( $check$check_args )&&*),
45                 stdout,
46                 stderr
47             );
48         }
49     };
50 }
51
52 #[rustfmt_only_ci_test]
53 #[test]
54 fn print_config() {
55     assert_that!(
56         &["--print-config", "unknown"],
57         starts_with("Unknown print-config option")
58     );
59     assert_that!(&["--print-config", "default"], contains("max_width = 100"));
60     assert_that!(&["--print-config", "minimal"], contains("PATH required"));
61     assert_that!(
62         &["--print-config", "minimal", "minimal-config"],
63         contains("doesn't work with standard input.")
64     );
65
66     let (stdout, stderr) = rustfmt(&[
67         "--print-config",
68         "minimal",
69         "minimal-config",
70         "src/shape.rs",
71     ]);
72     assert!(
73         Path::new("minimal-config").exists(),
74         "stdout:\n{}\nstderr:\n{}",
75         stdout,
76         stderr
77     );
78     remove_file("minimal-config").unwrap();
79 }
80
81 #[rustfmt_only_ci_test]
82 #[test]
83 fn inline_config() {
84     // single invocation
85     assert_that!(
86         &[
87             "--print-config",
88             "current",
89             ".",
90             "--config=color=Never,edition=2018"
91         ],
92         contains("color = \"Never\"") && contains("edition = \"2018\"")
93     );
94
95     // multiple overriding invocations
96     assert_that!(
97         &[
98             "--print-config",
99             "current",
100             ".",
101             "--config",
102             "color=never,edition=2018",
103             "--config",
104             "color=always,format_strings=true"
105         ],
106         contains("color = \"Always\"")
107             && contains("edition = \"2018\"")
108             && contains("format_strings = true")
109     );
110 }
111
112 #[test]
113 fn rustfmt_usage_text() {
114     let args = ["--help"];
115     let (stdout, _) = rustfmt(&args);
116     assert!(stdout.contains("Format Rust code\n\nusage: rustfmt [options] <file>..."));
117 }
118
119 #[test]
120 fn mod_resolution_error_multiple_candidate_files() {
121     // See also https://github.com/rust-lang/rustfmt/issues/5167
122     let default_path = Path::new("tests/mod-resolver/issue-5167/src/a.rs");
123     let secondary_path = Path::new("tests/mod-resolver/issue-5167/src/a/mod.rs");
124     let error_message = format!(
125         "file for module found at both {:?} and {:?}",
126         default_path.canonicalize().unwrap(),
127         secondary_path.canonicalize().unwrap(),
128     );
129
130     let args = ["tests/mod-resolver/issue-5167/src/lib.rs"];
131     let (_stdout, stderr) = rustfmt(&args);
132     assert!(stderr.contains(&error_message))
133 }
134
135 #[test]
136 fn mod_resolution_error_sibling_module_not_found() {
137     let args = ["tests/mod-resolver/module-not-found/sibling_module/lib.rs"];
138     let (_stdout, stderr) = rustfmt(&args);
139     // Module resolution fails because we're unable to find `a.rs` in the same directory as lib.rs
140     assert!(stderr.contains("a.rs does not exist"))
141 }
142
143 #[test]
144 fn mod_resolution_error_relative_module_not_found() {
145     let args = ["tests/mod-resolver/module-not-found/relative_module/lib.rs"];
146     let (_stdout, stderr) = rustfmt(&args);
147     // The file `./a.rs` and directory `./a` both exist.
148     // Module resolution fails because we're unable to find `./a/b.rs`
149     #[cfg(not(windows))]
150     assert!(stderr.contains("a/b.rs does not exist"));
151     #[cfg(windows)]
152     assert!(stderr.contains("a\\b.rs does not exist"));
153 }
154
155 #[test]
156 fn mod_resolution_error_path_attribute_does_not_exist() {
157     let args = ["tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs"];
158     let (_stdout, stderr) = rustfmt(&args);
159     // The path attribute points to a file that does not exist
160     assert!(stderr.contains("does_not_exist.rs does not exist"));
161 }
162
163 #[test]
164 fn rustfmt_emits_error_on_line_overflow_true() {
165     // See also https://github.com/rust-lang/rustfmt/issues/3164
166     let args = [
167         "--config",
168         "error_on_line_overflow=true",
169         "tests/cargo-fmt/source/issue_3164/src/main.rs",
170     ];
171
172     let (_stdout, stderr) = rustfmt(&args);
173     assert!(stderr.contains(
174         "line formatted, but exceeded maximum width (maximum: 100 (see `max_width` option)"
175     ))
176 }