23
23
#![ allow( clippy:: disallowed_methods, clippy:: print_stdout, clippy:: print_stderr) ]
24
24
25
25
use anyhow:: { anyhow, ensure, Context , Error } ;
26
- use rustfix:: apply_suggestions;
26
+ use rustfix:: { apply_suggestions, apply_suggestions_separately } ;
27
27
use std:: collections:: HashSet ;
28
28
use std:: env;
29
29
use std:: ffi:: OsString ;
@@ -33,8 +33,12 @@ use std::process::{Command, Output};
33
33
use tempfile:: tempdir;
34
34
use tracing:: { debug, info, warn} ;
35
35
36
- mod fixmode {
37
- pub const EVERYTHING : & str = "yolo" ;
36
+ #[ derive( Clone , Copy ) ]
37
+ enum ReplaceMode {
38
+ /// Combine suggestions into a single `.fixed` file with [`apply_suggestions`]
39
+ Combined ,
40
+ /// Create a separate `.fixed` file per suggestion with [`apply_suggestions_separately`]
41
+ Separate ,
38
42
}
39
43
40
44
mod settings {
@@ -151,23 +155,16 @@ fn diff(expected: &str, actual: &str) -> String {
151
155
res
152
156
}
153
157
154
- fn test_rustfix_with_file < P : AsRef < Path > > ( file : P , mode : & str ) -> Result < ( ) , Error > {
158
+ fn test_rustfix_with_file < P : AsRef < Path > > ( file : P , replace_mode : ReplaceMode ) -> Result < ( ) , Error > {
155
159
let file: & Path = file. as_ref ( ) ;
156
160
let json_file = file. with_extension ( "json" ) ;
157
- let fixed_file = file. with_extension ( "fixed.rs" ) ;
158
-
159
- let filter_suggestions = if mode == fixmode:: EVERYTHING {
160
- rustfix:: Filter :: Everything
161
- } else {
162
- rustfix:: Filter :: MachineApplicableOnly
163
- } ;
164
161
165
162
debug ! ( "next up: {:?}" , file) ;
166
163
let code = fs:: read_to_string ( file) ?;
167
164
let errors =
168
165
compile_and_get_json_errors ( file) . context ( format ! ( "could compile {}" , file. display( ) ) ) ?;
169
166
let suggestions =
170
- rustfix:: get_suggestions_from_json ( & errors, & HashSet :: new ( ) , filter_suggestions )
167
+ rustfix:: get_suggestions_from_json ( & errors, & HashSet :: new ( ) , rustfix :: Filter :: Everything )
171
168
. context ( "could not load suggestions" ) ?;
172
169
173
170
if std:: env:: var ( settings:: RECORD_JSON ) . is_ok ( ) {
@@ -179,9 +176,12 @@ fn test_rustfix_with_file<P: AsRef<Path>>(file: P, mode: &str) -> Result<(), Err
179
176
"could not load json fixtures for {}" ,
180
177
file. display( )
181
178
) ) ?;
182
- let expected_suggestions =
183
- rustfix:: get_suggestions_from_json ( & expected_json, & HashSet :: new ( ) , filter_suggestions)
184
- . context ( "could not load expected suggestions" ) ?;
179
+ let expected_suggestions = rustfix:: get_suggestions_from_json (
180
+ & expected_json,
181
+ & HashSet :: new ( ) ,
182
+ rustfix:: Filter :: Everything ,
183
+ )
184
+ . context ( "could not load expected suggestions" ) ?;
185
185
186
186
ensure ! (
187
187
expected_suggestions == suggestions,
@@ -193,28 +193,52 @@ fn test_rustfix_with_file<P: AsRef<Path>>(file: P, mode: &str) -> Result<(), Err
193
193
) ;
194
194
}
195
195
196
- let fixed = apply_suggestions ( & code, & suggestions)
197
- . context ( format ! ( "could not apply suggestions to {}" , file. display( ) ) ) ?
198
- . replace ( '\r' , "" ) ;
196
+ let bless = std:: env:: var_os ( settings:: BLESS )
197
+ . is_some_and ( |bless_name| bless_name == file. file_name ( ) . unwrap ( ) ) ;
199
198
200
- if std :: env :: var ( settings :: RECORD_FIXED_RUST ) . is_ok ( ) {
201
- fs:: write ( file . with_extension ( "recorded.rs" ) , & fixed ) ?;
199
+ if bless {
200
+ std :: fs:: write ( & json_file , & errors ) ?;
202
201
}
203
202
204
- if let Some ( bless_name) = std:: env:: var_os ( settings:: BLESS ) {
205
- if bless_name == file. file_name ( ) . unwrap ( ) {
206
- std:: fs:: write ( & json_file, & errors) ?;
207
- std:: fs:: write ( & fixed_file, & fixed) ?;
203
+ match replace_mode {
204
+ ReplaceMode :: Combined => {
205
+ let fixed = apply_suggestions ( & code, & suggestions)
206
+ . context ( format ! ( "could not apply suggestions to {}" , file. display( ) ) ) ?
207
+ . replace ( '\r' , "" ) ;
208
+ check_fixed_file ( fixed, file. with_extension ( "fixed.rs" ) , bless) ?;
208
209
}
210
+ ReplaceMode :: Separate => {
211
+ let fixes = apply_suggestions_separately ( & code, & suggestions)
212
+ . context ( format ! ( "could not apply suggestions to {}" , file. display( ) ) ) ?;
213
+ for ( i, fixed) in fixes. iter ( ) . enumerate ( ) {
214
+ check_fixed_file (
215
+ fixed. replace ( '\r' , "" ) ,
216
+ file. with_extension ( format ! ( "fixed.{i}.rs" ) ) ,
217
+ bless,
218
+ ) ?;
219
+ }
220
+ }
221
+ }
222
+
223
+ Ok ( ( ) )
224
+ }
225
+
226
+ fn check_fixed_file ( fixed : String , fixed_file : PathBuf , bless : bool ) -> Result < ( ) , Error > {
227
+ if std:: env:: var ( settings:: RECORD_FIXED_RUST ) . is_ok ( ) {
228
+ fs:: write ( fixed_file. with_extension ( "recorded.rs" ) , & fixed) ?;
229
+ }
230
+
231
+ if bless {
232
+ std:: fs:: write ( & fixed_file, & fixed) ?;
209
233
}
210
234
211
235
let expected_fixed = fs:: read_to_string ( & fixed_file)
212
- . context ( format ! ( "could read fixed file for {}" , file . display( ) ) ) ?
236
+ . context ( format ! ( "could read fixed file {}" , fixed_file . display( ) ) ) ?
213
237
. replace ( '\r' , "" ) ;
214
238
ensure ! (
215
239
fixed. trim( ) == expected_fixed. trim( ) ,
216
- "file {} doesn't look fixed :\n {}" ,
217
- file . display( ) ,
240
+ "file {} doesn't match expected fix :\n {}" ,
241
+ fixed_file . display( ) ,
218
242
diff( fixed. trim( ) , expected_fixed. trim( ) )
219
243
) ;
220
244
@@ -229,12 +253,12 @@ fn get_fixture_files(p: &str) -> Result<Vec<PathBuf>, Error> {
229
253
. filter ( |p| p. is_file ( ) )
230
254
. filter ( |p| {
231
255
let x = p. to_string_lossy ( ) ;
232
- x. ends_with ( ".rs" ) && !x. ends_with ( ".fixed.rs " ) && !x. ends_with ( ".recorded.rs" )
256
+ x. ends_with ( ".rs" ) && !x. contains ( ".fixed." ) && !x. ends_with ( ".recorded.rs" )
233
257
} )
234
258
. collect ( ) )
235
259
}
236
260
237
- fn assert_fixtures ( dir : & str , mode : & str ) {
261
+ fn assert_fixtures ( dir : & str , replace_mode : ReplaceMode ) {
238
262
let files = get_fixture_files ( dir)
239
263
. context ( format ! ( "couldn't load dir `{}`" , dir) )
240
264
. unwrap ( ) ;
@@ -254,7 +278,7 @@ fn assert_fixtures(dir: &str, mode: &str) {
254
278
info ! ( "skipped: {file:?}" ) ;
255
279
continue ;
256
280
}
257
- if let Err ( err) = test_rustfix_with_file ( file, mode ) {
281
+ if let Err ( err) = test_rustfix_with_file ( file, replace_mode ) {
258
282
println ! ( "failed: {}" , file. display( ) ) ;
259
283
warn ! ( "{:?}" , err) ;
260
284
failures += 1 ;
@@ -273,7 +297,8 @@ fn assert_fixtures(dir: &str, mode: &str) {
273
297
}
274
298
275
299
#[ test]
276
- fn everything ( ) {
300
+ fn fixtures ( ) {
277
301
tracing_subscriber:: fmt:: init ( ) ;
278
- assert_fixtures ( "./tests/everything" , fixmode:: EVERYTHING ) ;
302
+ assert_fixtures ( "./tests/everything" , ReplaceMode :: Combined ) ;
303
+ assert_fixtures ( "./tests/separate" , ReplaceMode :: Separate ) ;
279
304
}
0 commit comments