11//! Integration tests for rustfmt.
22
33use std:: env;
4- use std:: fs:: remove_file;
4+ use std:: fs:: { File , remove_file} ;
55use std:: path:: Path ;
66use std:: process:: Command ;
77
88use rustfmt_config_proc_macro:: { nightly_only_test, rustfmt_only_ci_test} ;
99
10- /// Run the rustfmt executable and return its output.
11- fn rustfmt ( args : & [ & str ] ) -> ( String , String ) {
12- let cmd = env ! ( "CARGO_BIN_EXE_rustfmt" ) ;
13- let bin_dir = Path :: new ( cmd) . parent ( ) . unwrap ( ) ;
10+ /// Run the rustfmt executable with environment vars set and return its output.
11+ fn rustfmt_with_extra (
12+ args : & [ & str ] ,
13+ working_dir : Option < & str > ,
14+ envs : & [ ( & str , & str ) ] ,
15+ ) -> ( String , String ) {
16+ let rustfmt_exe = env ! ( "CARGO_BIN_EXE_rustfmt" ) ;
17+ let bin_dir = Path :: new ( rustfmt_exe) . parent ( ) . unwrap ( ) ;
1418
1519 // Ensure the rustfmt binary runs from the local target dir.
1620 let path = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
1721 let mut paths = env:: split_paths ( & path) . collect :: < Vec < _ > > ( ) ;
1822 paths. insert ( 0 , bin_dir. to_owned ( ) ) ;
1923 let new_path = env:: join_paths ( paths) . unwrap ( ) ;
20-
21- match Command :: new ( & cmd) . args ( args) . env ( "PATH" , new_path) . output ( ) {
24+ let mut cmd = Command :: new ( rustfmt_exe) ;
25+ cmd. args ( args)
26+ . env ( "PATH" , new_path)
27+ . envs ( envs. iter ( ) . copied ( ) ) ;
28+ if let Some ( working_dir) = working_dir {
29+ cmd. current_dir ( working_dir) ;
30+ }
31+ match cmd. output ( ) {
2232 Ok ( output) => (
2333 String :: from_utf8 ( output. stdout ) . expect ( "utf-8" ) ,
2434 String :: from_utf8 ( output. stderr ) . expect ( "utf-8" ) ,
@@ -27,6 +37,10 @@ fn rustfmt(args: &[&str]) -> (String, String) {
2737 }
2838}
2939
40+ fn rustfmt ( args : & [ & str ] ) -> ( String , String ) {
41+ rustfmt_with_extra ( args, None , & [ ] )
42+ }
43+
3044macro_rules! assert_that {
3145 ( $args: expr, $( $check: ident $check_args: tt) &&+) => {
3246 let ( stdout, stderr) = rustfmt( $args) ;
@@ -228,3 +242,34 @@ fn rustfmt_error_improvement_regarding_invalid_toml() {
228242
229243 assert ! ( stderr. contains( & expected_error_message) ) ;
230244}
245+
246+ #[ test]
247+ fn rustfmt_allow_not_a_dir_errors ( ) {
248+ // See also https://github.com/rust-lang/rustfmt/pull/6624
249+
250+ // To get a proper test, we need to make sure that neither the working dir
251+ // nor the input file have a "rustfmt.toml" file in any ancestor dirs. Since
252+ // this project has a "rustfmt.toml" in the root dir, we can't use a temp
253+ // dir in the target/ dir, which includes the directory given by
254+ // CARGO_TARGET_TMPDIR. Thus, we need the OS-specific temp dir which is
255+ // closer to the "root" directory which is less likely to have a
256+ // "rustfmt.toml".
257+ let fake_home = tempfile:: tempdir ( ) . unwrap ( ) ;
258+ let fake_home_str = fake_home. path ( ) . to_str ( ) . unwrap ( ) ;
259+
260+ // create .config file
261+ let dot_config_file = fake_home. path ( ) . join ( ".config" ) ;
262+ let _ = File :: create ( dot_config_file) . unwrap ( ) ;
263+
264+ // create empty.rs
265+ let empty_rs = fake_home. path ( ) . join ( "empty.rs" ) ;
266+ let _ = File :: create ( & empty_rs) . unwrap ( ) ;
267+
268+ let args = [ empty_rs. to_str ( ) . unwrap ( ) ] ;
269+ let envs = & [ ( "HOME" , fake_home_str) ] ;
270+ let ( stdout, stderr) = rustfmt_with_extra ( & args, Some ( fake_home_str) , envs) ;
271+
272+ // Should pass without any errors
273+ assert_eq ! ( stdout, "" ) ;
274+ assert_eq ! ( stderr, "" ) ;
275+ }
0 commit comments