@@ -123,46 +123,62 @@ impl From<Option<FixKind>> for ExpectFixKind {
123123}
124124
125125#[ derive( Debug , Clone ) ]
126- pub struct ExpectFix {
126+ pub struct ExpectFixTestCase {
127127 /// Source code being tested
128128 source : String ,
129+ expected : Vec < ExpectFix > ,
130+ rule_config : Option < Value > ,
131+ }
132+
133+ #[ derive( Debug , Clone ) ]
134+ struct ExpectFix {
129135 /// Expected source code after fix has been applied
130136 expected : String ,
131137 kind : ExpectFixKind ,
132- rule_config : Option < Value > ,
133138}
134139
135- impl < S : Into < String > > From < ( S , S , Option < Value > ) > for ExpectFix {
140+ impl < S : Into < String > > From < ( S , S , Option < Value > ) > for ExpectFixTestCase {
136141 fn from ( value : ( S , S , Option < Value > ) ) -> Self {
137142 Self {
138143 source : value. 0 . into ( ) ,
139- expected : value. 1 . into ( ) ,
140- kind : ExpectFixKind :: Any ,
144+ expected : vec ! [ ExpectFix { expected: value. 1 . into( ) , kind: ExpectFixKind :: Any } ] ,
141145 rule_config : value. 2 ,
142146 }
143147 }
144148}
145149
146- impl < S : Into < String > > From < ( S , S ) > for ExpectFix {
150+ impl < S : Into < String > > From < ( S , S ) > for ExpectFixTestCase {
147151 fn from ( value : ( S , S ) ) -> Self {
148152 Self {
149153 source : value. 0 . into ( ) ,
150- expected : value. 1 . into ( ) ,
151- kind : ExpectFixKind :: Any ,
154+ expected : vec ! [ ExpectFix { expected: value. 1 . into( ) , kind: ExpectFixKind :: Any } ] ,
152155 rule_config : None ,
153156 }
154157 }
155158}
156- impl < S , F > From < ( S , S , Option < Value > , F ) > for ExpectFix
159+
160+ impl < S : Into < String > > From < ( S , ( S , S ) ) > for ExpectFixTestCase {
161+ fn from ( value : ( S , ( S , S ) ) ) -> Self {
162+ Self {
163+ source : value. 0 . into ( ) ,
164+ expected : vec ! [
165+ ExpectFix { expected: value. 1.0 . into( ) , kind: ExpectFixKind :: Any } ,
166+ ExpectFix { expected: value. 1.1 . into( ) , kind: ExpectFixKind :: Any } ,
167+ ] ,
168+ rule_config : None ,
169+ }
170+ }
171+ }
172+
173+ impl < S , F > From < ( S , S , Option < Value > , F ) > for ExpectFixTestCase
157174where
158175 S : Into < String > ,
159176 F : Into < ExpectFixKind > ,
160177{
161178 fn from ( ( source, expected, config, kind) : ( S , S , Option < Value > , F ) ) -> Self {
162179 Self {
163180 source : source. into ( ) ,
164- expected : expected. into ( ) ,
165- kind : kind. into ( ) ,
181+ expected : vec ! [ ExpectFix { expected: expected. into( ) , kind: kind. into( ) } ] ,
166182 rule_config : config,
167183 }
168184 }
@@ -206,7 +222,7 @@ pub struct Tester {
206222 ///
207223 /// Note that disabling this check should be done as little as possible, and
208224 /// never in bad faith (e.g. no `#[test]` functions have fixer cases at all).
209- expect_fix : Option < Vec < ExpectFix > > ,
225+ expect_fix : Option < Vec < ExpectFixTestCase > > ,
210226 snapshot : String ,
211227 /// Suffix added to end of snapshot name.
212228 ///
@@ -345,7 +361,7 @@ impl Tester {
345361 /// Tester::new("no-undef", pass, fail).expect_fix(fix).test();
346362 /// ```
347363 #[ must_use]
348- pub fn expect_fix < F : Into < ExpectFix > > ( mut self , expect_fix : Vec < F > ) -> Self {
364+ pub fn expect_fix < F : Into < ExpectFixTestCase > > ( mut self , expect_fix : Vec < F > ) -> Self {
349365 // prevent `expect_fix` abuse
350366 assert ! (
351367 !expect_fix. is_empty( ) ,
@@ -398,8 +414,14 @@ impl Tester {
398414
399415 fn test_pass ( & mut self ) {
400416 for TestCase { source, rule_config, eslint_config, path } in self . expect_pass . clone ( ) {
401- let result =
402- self . run ( & source, rule_config. clone ( ) , & eslint_config, path, ExpectFixKind :: None ) ;
417+ let result = self . run (
418+ & source,
419+ rule_config. clone ( ) ,
420+ & eslint_config,
421+ path,
422+ ExpectFixKind :: None ,
423+ 0 ,
424+ ) ;
403425 let passed = result == TestResult :: Passed ;
404426 let config = rule_config. map_or_else (
405427 || "\n \n ------------------------\n " . to_string ( ) ,
@@ -420,8 +442,14 @@ impl Tester {
420442
421443 fn test_fail ( & mut self ) {
422444 for TestCase { source, rule_config, eslint_config, path } in self . expect_fail . clone ( ) {
423- let result =
424- self . run ( & source, rule_config. clone ( ) , & eslint_config, path, ExpectFixKind :: None ) ;
445+ let result = self . run (
446+ & source,
447+ rule_config. clone ( ) ,
448+ & eslint_config,
449+ path,
450+ ExpectFixKind :: None ,
451+ 0 ,
452+ ) ;
425453 let failed = result == TestResult :: Failed ;
426454 let config = rule_config. map_or_else (
427455 || "\n \n ------------------------" . to_string ( ) ,
@@ -439,6 +467,7 @@ impl Tester {
439467 }
440468 }
441469
470+ #[ expect( clippy:: cast_possible_truncation) ] // there are no rules with over 255 different possible fixes
442471 fn test_fix ( & mut self ) {
443472 // If auto-fixes are reported, make sure some fix test cases are provided
444473 let rule = self . find_rule ( ) ;
@@ -453,15 +482,19 @@ impl Tester {
453482 } ;
454483
455484 for fix in fix_test_cases {
456- let ExpectFix { source, expected, kind, rule_config : config } = fix;
457- let result = self . run ( & source, config, & None , None , kind) ;
458- match result {
459- TestResult :: Fixed ( fixed_str) => assert_eq ! (
460- expected, fixed_str,
461- r#"Expected "{source}" to be fixed into "{expected}""#
462- ) ,
463- TestResult :: Passed => panic ! ( "Expected a fix, but test passed: {source}" ) ,
464- TestResult :: Failed => panic ! ( "Expected a fix, but test failed: {source}" ) ,
485+ let ExpectFixTestCase { source, expected, rule_config : config } = fix;
486+ for ( index, expect) in expected. iter ( ) . enumerate ( ) {
487+ let result =
488+ self . run ( & source, config. clone ( ) , & None , None , expect. kind , index as u8 ) ;
489+ match result {
490+ TestResult :: Fixed ( fixed_str) => assert_eq ! (
491+ expect. expected, fixed_str,
492+ r#"Expected "{source}" to be fixed into "{}""# ,
493+ expect. expected
494+ ) ,
495+ TestResult :: Passed => panic ! ( "Expected a fix, but test passed: {source}" ) ,
496+ TestResult :: Failed => panic ! ( "Expected a fix, but test failed: {source}" ) ,
497+ }
465498 }
466499 }
467500 }
@@ -473,7 +506,8 @@ impl Tester {
473506 rule_config : Option < Value > ,
474507 eslint_config : & Option < Value > ,
475508 path : Option < PathBuf > ,
476- fix : ExpectFixKind ,
509+ fix_kind : ExpectFixKind ,
510+ fix_index : u8 ,
477511 ) -> TestResult {
478512 let allocator = Allocator :: default ( ) ;
479513 let rule = self . find_rule ( ) . read_json ( rule_config. unwrap_or_default ( ) ) ;
@@ -492,7 +526,7 @@ impl Tester {
492526 FxHashMap :: default ( ) ,
493527 ) ,
494528 )
495- . with_fix ( fix . into ( ) ) ;
529+ . with_fix ( fix_kind . into ( ) ) ;
496530
497531 let path_to_lint = if self . plugins . has_import ( ) {
498532 assert ! ( path. is_none( ) , "import plugin does not support path" ) ;
@@ -520,8 +554,8 @@ impl Tester {
520554 return TestResult :: Passed ;
521555 }
522556
523- if fix . is_some ( ) {
524- let fix_result = Fixer :: new ( source_text, result) . fix ( ) ;
557+ if fix_kind . is_some ( ) {
558+ let fix_result = Fixer :: new ( source_text, result) . with_fix_index ( fix_index ) . fix ( ) ;
525559 return TestResult :: Fixed ( fix_result. fixed_code . to_string ( ) ) ;
526560 }
527561
0 commit comments