66//! rustfix and applies the recommended suggestions to the `.rs` file. It then 
77//! compares the result with the corresponding `.fixed.rs` file. If they don't 
88//! match, then the test fails. 
9- //! 
10- //! There are several debugging environment variables for this test that you can set: 
11- //! 
12- //! - `RUST_LOG=parse_and_replace=debug`: Print debug information. 
13- //! - `RUSTFIX_TEST_BLESS=test-name.rs`: When given the name of a test, this 
14- //!   will overwrite the `.json` and `.fixed.rs` files with the expected 
15- //!   values. This can be used when adding a new test. 
16- //! - `RUSTFIX_TEST_RECORD_JSON=1`:  Records the JSON output to 
17- //!   `*.recorded.json` files. You can then move that to `.json` or whatever 
18- //!   you need. 
19- //! - `RUSTFIX_TEST_RECORD_FIXED_RUST=1`: Records the fixed result to 
20- //!   `*.recorded.rs` files. You can then move that to `.rs` or whatever you 
21- //!   need. 
229
2310#![ allow( clippy:: disallowed_methods,  clippy:: print_stdout,  clippy:: print_stderr) ]  
2411
2512use  anyhow:: { anyhow,  Context ,  Error } ; 
2613use  cargo_test_macro:: cargo_test; 
2714use  rustfix:: apply_suggestions; 
15+ use  serde_json:: Value ; 
16+ use  snapbox:: data:: DataFormat ; 
17+ use  snapbox:: { Assert ,  Data } ; 
2818use  std:: collections:: HashSet ; 
2919use  std:: env; 
3020use  std:: ffi:: OsString ; 
@@ -38,14 +28,6 @@ mod fixmode {
3828    pub  const  EVERYTHING :  & str  = "yolo" ; 
3929} 
4030
41- mod  settings { 
42-     // can be set as env var to debug 
43-     pub  const  CHECK_JSON :  & str  = "RUSTFIX_TEST_CHECK_JSON" ; 
44-     pub  const  RECORD_JSON :  & str  = "RUSTFIX_TEST_RECORD_JSON" ; 
45-     pub  const  RECORD_FIXED_RUST :  & str  = "RUSTFIX_TEST_RECORD_FIXED_RUST" ; 
46-     pub  const  BLESS :  & str  = "RUSTFIX_TEST_BLESS" ; 
47- } 
48- 
4931fn  compile ( file :  & Path )  -> Result < Output ,  Error >  { 
5032    let  tmp = tempdir ( ) ?; 
5133
@@ -95,47 +77,15 @@ fn compiles_without_errors(file: &Path) -> Result<(), Error> {
9577                file, 
9678                String :: from_utf8( res. stderr) ?
9779            ) ; 
98-             Err ( anyhow ! ( 
99-                 "failed with status {:?} (`env RUST_LOG=parse_and_replace=info` for more info)" , 
100-                 res. status. code( ) , 
101-             ) ) 
102-         } 
103-     } 
104- } 
105- 
106- fn  diff ( expected :  & str ,  actual :  & str )  -> String  { 
107-     use  similar:: { ChangeTag ,  TextDiff } ; 
108-     use  std:: fmt:: Write ; 
109- 
110-     let  mut  res = String :: new ( ) ; 
111-     let  diff = TextDiff :: from_lines ( expected. trim ( ) ,  actual. trim ( ) ) ; 
112- 
113-     let  mut  different = false ; 
114-     for  op in  diff. ops ( )  { 
115-         for  change in  diff. iter_changes ( op)  { 
116-             let  prefix = match  change. tag ( )  { 
117-                 ChangeTag :: Equal  => continue , 
118-                 ChangeTag :: Insert  => "+" , 
119-                 ChangeTag :: Delete  => "-" , 
120-             } ; 
121-             if  !different { 
122-                 writeln ! ( & mut  res,  "differences found (+ == actual, - == expected):" ) . unwrap ( ) ; 
123-                 different = true ; 
124-             } 
125-             write ! ( & mut  res,  "{} {}" ,  prefix,  change. value( ) ) . unwrap ( ) ; 
80+             Err ( anyhow ! ( "failed with status {:?}" ,  res. status. code( ) ) ) 
12681        } 
12782    } 
128-     if  different { 
129-         write ! ( & mut  res,  "" ) . unwrap ( ) ; 
130-     } 
131- 
132-     res
13383} 
13484
13585fn  test_rustfix_with_file < P :  AsRef < Path > > ( file :  P ,  mode :  & str )  { 
13686    let  file:  & Path  = file. as_ref ( ) ; 
13787    let  json_file = file. with_extension ( "json" ) ; 
138-     let  fixed_file  = file. with_extension ( "fixed.rs" ) ; 
88+     let  expected_fixed_file  = file. with_extension ( "fixed.rs" ) ; 
13989
14090    let  filter_suggestions = if  mode == fixmode:: EVERYTHING  { 
14191        rustfix:: Filter :: Everything 
@@ -144,60 +94,51 @@ fn test_rustfix_with_file<P: AsRef<Path>>(file: P, mode: &str) {
14494    } ; 
14595
14696    let  code = fs:: read_to_string ( file) . unwrap ( ) ; 
147-     let  errors = compile_and_get_json_errors ( file) 
148-         . with_context ( || format ! ( "could not compile {}" ,  file. display( ) ) ) . unwrap ( ) ; 
149-     let  suggestions =
150-         rustfix:: get_suggestions_from_json ( & errors,  & HashSet :: new ( ) ,  filter_suggestions) 
151-             . context ( "could not load suggestions" ) . unwrap ( ) ; 
15297
153-     if  std :: env :: var ( settings :: RECORD_JSON ) . is_ok ( )   { 
154-         fs :: write ( file . with_extension ( "recorded.json" ) ,   & errors ) . unwrap ( ) ; 
155-     } 
98+     let  json =  compile_and_get_json_errors ( file ) 
99+         . with_context ( ||  format ! ( "could not compile {}" ,  file . display ( ) ) ) 
100+          . unwrap ( ) ; 
156101
157-     if  std:: env:: var ( settings:: CHECK_JSON ) . is_ok ( )  { 
158-         let  expected_json = fs:: read_to_string ( & json_file) 
159-             . with_context ( || format ! ( "could not load json fixtures for {}" ,  file. display( ) ) ) . unwrap ( ) ; 
160-         let  expected_suggestions =
161-             rustfix:: get_suggestions_from_json ( & expected_json,  & HashSet :: new ( ) ,  filter_suggestions) 
162-                 . context ( "could not load expected suggestions" ) . unwrap ( ) ; 
163- 
164-         assert ! ( 
165-             expected_suggestions == suggestions, 
166-             "got unexpected suggestions from clippy:\n {}" , 
167-             diff( 
168-                 & format!( "{:?}" ,  expected_suggestions) , 
169-                 & format!( "{:?}" ,  suggestions) 
170-             ) 
171-         ) ; 
172-     } 
102+     let  suggestions =
103+         rustfix:: get_suggestions_from_json ( & json,  & HashSet :: new ( ) ,  filter_suggestions) 
104+             . context ( "could not load suggestions" ) 
105+             . unwrap ( ) ; 
173106
174107    let  fixed = apply_suggestions ( & code,  & suggestions) 
175-         . with_context ( || format ! ( "could not apply suggestions to {}" ,  file. display( ) ) ) . unwrap ( ) 
108+         . with_context ( || format ! ( "could not apply suggestions to {}" ,  file. display( ) ) ) 
109+         . unwrap ( ) 
176110        . replace ( '\r' ,  "" ) ; 
177111
178-     if  std:: env:: var ( settings:: RECORD_FIXED_RUST ) . is_ok ( )  { 
179-         fs:: write ( file. with_extension ( "recorded.rs" ) ,  & fixed) . unwrap ( ) ; 
180-     } 
181- 
182-     if  let  Some ( bless_name)  = std:: env:: var_os ( settings:: BLESS )  { 
183-         if  bless_name == file. file_name ( ) . unwrap ( )  { 
184-             std:: fs:: write ( & json_file,  & errors) . unwrap ( ) ; 
185-             std:: fs:: write ( & fixed_file,  & fixed) . unwrap ( ) ; 
186-         } 
187-     } 
188- 
189-     let  expected_fixed = fs:: read_to_string ( & fixed_file) 
190-         . with_context ( || format ! ( "could read fixed file for {}" ,  file. display( ) ) ) . unwrap ( ) 
191-         . replace ( '\r' ,  "" ) ; 
192-     assert ! ( 
193-         fixed. trim( )  == expected_fixed. trim( ) , 
194-         "file {} doesn't look fixed:\n {}" , 
195-         file. display( ) , 
196-         diff( fixed. trim( ) ,  expected_fixed. trim( ) ) 
112+     let  assert = Assert :: new ( ) . action_env ( snapbox:: assert:: DEFAULT_ACTION_ENV ) ; 
113+     let  ( actual_fix,  expected_fix)  = assert. normalize ( 
114+         Data :: text ( & fixed) , 
115+         Data :: read_from ( expected_fixed_file. as_path ( ) ,  Some ( DataFormat :: Text ) ) , 
197116    ) ; 
198117
199-     compiles_without_errors ( & fixed_file) . unwrap ( ) ; 
118+     if  actual_fix != expected_fix { 
119+         let  fixed_assert = assert. try_eq ( Some ( & "Current Fix" ) ,  actual_fix,  expected_fix) ; 
120+         assert ! ( fixed_assert. is_ok( ) ,  "{}" ,  fixed_assert. err( ) . unwrap( ) ) ; 
121+ 
122+         let  expected_json = Data :: read_from ( json_file. as_path ( ) ,  Some ( DataFormat :: Text ) ) ; 
123+ 
124+         let  pretty_json = json
125+             . split ( "\n " ) 
126+             . filter ( |j| !j. is_empty ( ) ) 
127+             . map ( |j| { 
128+                 serde_json:: to_string_pretty ( & serde_json:: from_str :: < Value > ( j) . unwrap ( ) ) . unwrap ( ) 
129+             } ) 
130+             . collect :: < Vec < String > > ( ) 
131+             . join ( "\n " ) ; 
132+ 
133+         let  json_assert = assert. try_eq ( 
134+             Some ( & "Compiler Error" ) , 
135+             Data :: text ( pretty_json) , 
136+             expected_json, 
137+         ) ; 
138+         assert ! ( json_assert. is_ok( ) ,  "{}" ,  json_assert. err( ) . unwrap( ) ) ; 
139+     } 
200140
141+     compiles_without_errors ( & expected_fixed_file) . unwrap ( ) ; 
201142} 
202143
203144macro_rules!  run_test { 
0 commit comments