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 ) {
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 ) {
1216 let mut bin_dir = env:: current_exe ( ) . unwrap ( ) ;
1317 bin_dir. pop ( ) ; // chop off test exe name
1418 if bin_dir. ends_with ( "deps" ) {
1519 bin_dir. pop ( ) ;
1620 }
17- let cmd = bin_dir. join ( format ! ( "rustfmt{}" , env:: consts:: EXE_SUFFIX ) ) ;
21+ let rustfmt_exe = bin_dir. join ( format ! ( "rustfmt{}" , env:: consts:: EXE_SUFFIX ) ) ;
1822
1923 // Ensure the rustfmt binary runs from the local target dir.
2024 let path = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
2125 let mut paths = env:: split_paths ( & path) . collect :: < Vec < _ > > ( ) ;
2226 paths. insert ( 0 , bin_dir) ;
2327 let new_path = env:: join_paths ( paths) . unwrap ( ) ;
24-
25- match Command :: new ( & cmd) . args ( args) . env ( "PATH" , new_path) . output ( ) {
28+ let mut cmd = Command :: new ( rustfmt_exe) ;
29+ cmd. args ( args)
30+ . env ( "PATH" , new_path)
31+ . envs ( envs. iter ( ) . copied ( ) ) ;
32+ if let Some ( working_dir) = working_dir {
33+ cmd. current_dir ( working_dir) ;
34+ }
35+ match cmd. output ( ) {
2636 Ok ( output) => (
2737 String :: from_utf8 ( output. stdout ) . expect ( "utf-8" ) ,
2838 String :: from_utf8 ( output. stderr ) . expect ( "utf-8" ) ,
@@ -31,6 +41,10 @@ fn rustfmt(args: &[&str]) -> (String, String) {
3141 }
3242}
3343
44+ fn rustfmt ( args : & [ & str ] ) -> ( String , String ) {
45+ rustfmt_with_extra ( args, None , & [ ] )
46+ }
47+
3448macro_rules! assert_that {
3549 ( $args: expr, $( $check: ident $check_args: tt) &&+) => {
3650 let ( stdout, stderr) = rustfmt( $args) ;
@@ -232,3 +246,34 @@ fn rustfmt_error_improvement_regarding_invalid_toml() {
232246
233247 assert ! ( stderr. contains( & expected_error_message) ) ;
234248}
249+
250+ #[ test]
251+ fn rustfmt_allow_not_a_dir_errors ( ) {
252+ // See also https://github.com/rust-lang/rustfmt/pull/6624
253+
254+ // To get a proper test, we need to make sure that neither the working dir
255+ // nor the input file have a "rustfmt.toml" file in any ancestor dirs. Since
256+ // this project has a "rustfmt.toml" in the root dir, we can't use a temp
257+ // dir in the target/ dir, which includes the directory given by
258+ // CARGO_TARGET_TMPDIR. Thus, we need the OS-specific temp dir which is
259+ // closer to the "root" directory which is less likely to have a
260+ // "rustfmt.toml".
261+ let fake_home = tempfile:: tempdir ( ) . unwrap ( ) ;
262+ let fake_home_str = fake_home. path ( ) . to_str ( ) . unwrap ( ) ;
263+
264+ // create .config file
265+ let dot_config_file = fake_home. path ( ) . join ( ".config" ) ;
266+ let _ = File :: create ( dot_config_file) . unwrap ( ) ;
267+
268+ // create empty.rs
269+ let empty_rs = fake_home. path ( ) . join ( "empty.rs" ) ;
270+ let _ = File :: create ( & empty_rs) . unwrap ( ) ;
271+
272+ let args = [ empty_rs. to_str ( ) . unwrap ( ) ] ;
273+ let envs = & [ ( "HOME" , fake_home_str) ] ;
274+ let ( stdout, stderr) = rustfmt_with_extra ( & args, Some ( fake_home_str) , envs) ;
275+
276+ // Should pass without any errors
277+ assert_eq ! ( stdout, "" ) ;
278+ assert_eq ! ( stderr, "" ) ;
279+ }
0 commit comments