Browse Source

chore: unify tests not agnostic of PHP version (#7581)

Kuba Werłos 1 year ago
parent
commit
ff9b6f458d

+ 1 - 1
phpstan.dist.neon

@@ -21,7 +21,7 @@ parameters:
         -
             message: '#^Method PhpCsFixer\\Tests\\.+::provide.+Cases\(\) return type has no value type specified in iterable type iterable\.$#'
             path: tests
-            count: 1094
+            count: 1046
 
         -
             message: '#Call to static method .+ with .+ will always evaluate to true.$#'

+ 11 - 1
tests/AutoReview/ProjectCodeTest.php

@@ -51,6 +51,11 @@ final class ProjectCodeTest extends TestCase
      */
     private static ?array $srcClassCases = null;
 
+    /**
+     * @var array<string, Tokens>
+     */
+    private static array $fileTokensCache = [];
+
     /**
      * This structure contains older classes that are not yet covered by tests.
      *
@@ -73,6 +78,7 @@ final class ProjectCodeTest extends TestCase
     {
         self::$srcClassCases = null;
         self::$testClassCases = null;
+        self::$fileTokensCache = [];
     }
 
     public function testThatClassesWithoutTestsVarIsProper(): void
@@ -768,7 +774,11 @@ final class ProjectCodeTest extends TestCase
         $file = preg_replace('#^PhpCsFixer\\\#', 'src\\', $file);
         $file = str_replace('\\', \DIRECTORY_SEPARATOR, $file).'.php';
 
-        return Tokens::fromCode(file_get_contents($file));
+        if (!isset(self::$fileTokensCache[$file])) {
+            self::$fileTokensCache[$file] = Tokens::fromCode(file_get_contents($file));
+        }
+
+        return self::$fileTokensCache[$file];
     }
 
     /**

+ 43 - 29
tests/Fixer/CastNotation/CastSpacesFixerTest.php

@@ -24,40 +24,50 @@ use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
  */
 final class CastSpacesFixerTest extends AbstractFixerTestCase
 {
-    public function testInvalidConfigMissingKey(): void
+    /**
+     * @param array<string, int|string> $config
+     *
+     * @dataProvider provideInvalidConfigurationCases
+     */
+    public function testInvalidConfiguration(array $config, string $expectedMessage): void
     {
         $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches('#^\[cast_spaces\] Invalid configuration: The option "a" does not exist\. Defined options are: "space"\.$#');
+        $this->expectExceptionMessageMatches($expectedMessage);
 
-        $this->fixer->configure(['a' => 1]);
+        $this->fixer->configure($config);
     }
 
-    public function testInvalidConfigValue(): void
+    /**
+     * @return iterable<array{array<string, int|string>, string}>
+     */
+    public static function provideInvalidConfigurationCases(): iterable
     {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches('#^\[cast_spaces\] Invalid configuration: The option "space" with value "double" is invalid\. Accepted values are: "none", "single"\.$#');
+        yield 'missing key' => [
+            ['a' => 1],
+            '#^\[cast_spaces\] Invalid configuration: The option "a" does not exist\. Defined options are: "space"\.$#',
+        ];
 
-        $this->fixer->configure(['space' => 'double']);
+        yield 'invalid value' => [
+            ['space' => 'double'],
+            '#^\[cast_spaces\] Invalid configuration: The option "space" with value "double" is invalid\. Accepted values are: "none", "single"\.$#',
+        ];
     }
 
     /**
-     * @dataProvider provideFixCastsCases
+     * @param array<string, string> $configuration
+     *
+     * @dataProvider provideFixCases
      */
-    public function testFixCastsWithDefaultConfiguration(string $expected, ?string $input = null): void
+    public function testFix(string $expected, ?string $input = null, array $configuration = []): void
     {
+        $this->fixer->configure($configuration);
         $this->doTest($expected, $input);
     }
 
     /**
-     * @dataProvider provideFixCastsCases
+     * @return iterable<array{string, 1?: null|string, 2?: array{space: string}}>
      */
-    public function testFixCastsSingleSpace(string $expected, ?string $input = null): void
-    {
-        $this->fixer->configure(['space' => 'single']);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixCastsCases(): iterable
+    public static function provideFixCases(): iterable
     {
         yield [
             '<?php echo "( int ) $foo";',
@@ -120,79 +130,83 @@ final class CastSpacesFixerTest extends AbstractFixerTestCase
         yield [
             "<?php \$bar = (int)\r\n \$foo;",
         ];
-    }
 
-    /**
-     * @dataProvider provideFixCastsNoneSpaceCases
-     */
-    public function testFixCastsNoneSpace(string $expected, ?string $input = null): void
-    {
-        $this->fixer->configure(['space' => 'none']);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixCastsNoneSpaceCases(): iterable
-    {
         yield [
             '<?php echo "( int ) $foo";',
+            null,
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (int)$foo;',
             '<?php $bar = ( int)$foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (int)$foo;',
             '<?php $bar = (	int)$foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (int)$foo;',
             '<?php $bar = (int)	$foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (string)(int)$foo;',
             '<?php $bar = ( string )( int )$foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (string)(int)$foo;',
+            null,
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (string)(int)$foo;',
             '<?php $bar = ( string   )    (   int )$foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (string)$foo;',
             '<?php $bar = ( string )   $foo;',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (float)Foo::bar();',
             '<?php $bar = (float )Foo::bar();',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = Foo::baz((float)Foo::bar());',
             '<?php $bar = Foo::baz((float )Foo::bar());',
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = $query["params"] = (array)$query["params"];',
+            null,
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (int)$foo;',
             "<?php \$bar = (int)\n \$foo;",
+            ['space' => 'none'],
         ];
 
         yield [
             '<?php $bar = (int)$foo;',
             "<?php \$bar = (int)\r\n \$foo;",
+            ['space' => 'none'],
         ];
     }
 }

+ 33 - 15
tests/Fixer/CastNotation/LowercaseCastFixerTest.php

@@ -31,6 +31,36 @@ final class LowercaseCastFixerTest extends AbstractFixerTestCase
         $this->doTest($expected, $input);
     }
 
+    /**
+     * @return iterable<array{0: non-empty-string, 1?: non-empty-string}>
+     */
+    public static function provideFixCases(): iterable
+    {
+        $types = ['boolean', 'bool', 'integer', 'int', 'double', 'float', 'float', 'string', 'array', 'object', 'binary'];
+
+        foreach ($types as $from) {
+            yield from self::createCasesFor($from);
+        }
+    }
+
+    /**
+     * @dataProvider provideFixPre80Cases
+     *
+     * @requires PHP <8.0
+     */
+    public function testFixPre80(string $expected, string $input = null): void
+    {
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{0: non-empty-string, 1?: non-empty-string}>
+     */
+    public static function provideFixPre80Cases(): iterable
+    {
+        yield from self::createCasesFor('unset');
+    }
+
     /**
      * @dataProvider provideFix74DeprecatedCases
      *
@@ -45,21 +75,9 @@ final class LowercaseCastFixerTest extends AbstractFixerTestCase
         $this->doTest($expected, $input);
     }
 
-    public static function provideFixCases(): iterable
-    {
-        $types = ['boolean', 'bool', 'integer', 'int', 'double', 'float', 'float', 'string', 'array', 'object', 'binary'];
-
-        if (\PHP_VERSION_ID < 8_00_00) {
-            $types[] = 'unset';
-        }
-
-        foreach ($types as $from) {
-            foreach (self::createCasesFor($from) as $case) {
-                yield $case;
-            }
-        }
-    }
-
+    /**
+     * @return iterable<array{0: non-empty-string, 1?: non-empty-string}>
+     */
     public static function provideFix74DeprecatedCases(): iterable
     {
         return self::createCasesFor('real');

+ 3 - 9
tests/Fixer/CastNotation/ModernizeTypesCastingFixerTest.php

@@ -226,14 +226,8 @@ final class ModernizeTypesCastingFixerTest extends AbstractFixerTestCase
             '<?php $foo = ((string) ($x + $y)){0};',
             '<?php $foo = strval($x + $y){0};',
         ];
-    }
 
-    /**
-     * @requires PHP <8.0
-     */
-    public function testFixPrePHP80(): void
-    {
-        $this->doTest(
+        yield [
             '<?php $a = #
 #
 #
@@ -252,8 +246,8 @@ intval#
 #
  $b#
  )#
- ;#'
-        );
+ ;#',
+        ];
     }
 
     /**

+ 45 - 35
tests/Fixer/CastNotation/ShortScalarCastFixerTest.php

@@ -31,59 +31,69 @@ final class ShortScalarCastFixerTest extends AbstractFixerTestCase
         $this->doTest($expected, $input);
     }
 
-    /**
-     * @dataProvider provideFix74DeprecatedCases
-     *
-     * @group legacy
-     *
-     * @requires PHP <8.0
-     */
-    public function testFix74Deprecated(string $expected, ?string $input = null): void
-    {
-        $this->expectDeprecation('%AThe (real) cast is deprecated, use (float) instead');
-
-        $this->doTest($expected, $input);
-    }
-
     public static function provideFixCases(): iterable
     {
         foreach (['boolean' => 'bool', 'integer' => 'int', 'double' => 'float', 'binary' => 'string'] as $from => $to) {
-            foreach (self::createCasesFor($from, $to) as $case) {
-                yield $case;
-            }
+            yield from self::createCasesFor($from, $to);
         }
-    }
 
-    public static function provideFix74DeprecatedCases(): iterable
-    {
-        return self::createCasesFor('real', 'float');
+        $types = ['string', 'array', 'object'];
+
+        foreach ($types as $cast) {
+            yield [sprintf('<?php $b=(%s) $d;', $cast)];
+
+            yield [sprintf('<?php $b=( %s ) $d;', $cast)];
+
+            yield [sprintf('<?php $b=(%s ) $d;', ucfirst($cast))];
+
+            yield [sprintf('<?php $b=(%s ) $d;', strtoupper($cast))];
+        }
     }
 
     /**
-     * @dataProvider provideNoFixCases
+     * @dataProvider provideFixPre80Cases
+     *
+     * @requires PHP <8.0
      */
-    public function testNoFix(string $expected): void
+    public function testFixPre80(string $expected, string $input = null): void
     {
-        $this->doTest($expected);
+        $this->doTest($expected, $input);
     }
 
-    public static function provideNoFixCases(): iterable
+    /**
+     * @return iterable<array{string}>
+     */
+    public static function provideFixPre80Cases(): iterable
     {
-        $types = ['string', 'array', 'object'];
+        yield ['<?php $b=(unset) $d;'];
 
-        if (\PHP_VERSION_ID < 8_00_00) {
-            $types[] = 'unset';
-        }
+        yield ['<?php $b=( unset ) $d;'];
 
-        foreach ($types as $cast) {
-            yield [sprintf('<?php $b=(%s) $d;', $cast)];
+        yield ['<?php $b=(Unset ) $d;'];
 
-            yield [sprintf('<?php $b=( %s ) $d;', $cast)];
+        yield ['<?php $b=(UNSET ) $d;'];
+    }
 
-            yield [sprintf('<?php $b=(%s ) $d;', ucfirst($cast))];
+    /**
+     * @dataProvider provideFix74DeprecatedCases
+     *
+     * @group legacy
+     *
+     * @requires PHP <8.0
+     */
+    public function testFix74Deprecated(string $expected, ?string $input = null): void
+    {
+        $this->expectDeprecation('The (real) cast is deprecated, use (float) instead');
 
-            yield [sprintf('<?php $b=(%s ) $d;', strtoupper($cast))];
-        }
+        $this->doTest($expected, $input);
+    }
+
+    /**
+     * @return iterable<array{0: non-empty-string, 1?: non-empty-string}>
+     */
+    public static function provideFix74DeprecatedCases(): iterable
+    {
+        yield from self::createCasesFor('real', 'float');
     }
 
     /**

+ 171 - 255
tests/Fixer/ClassNotation/ClassAttributesSeparationFixerTest.php

@@ -27,10 +27,13 @@ use PhpCsFixer\WhitespacesFixerConfig;
 final class ClassAttributesSeparationFixerTest extends AbstractFixerTestCase
 {
     /**
+     * @param array<string, bool> $configuration
+     *
      * @dataProvider provideFixCases
      */
-    public function testFix(string $expected, ?string $input = null): void
+    public function testFix(string $expected, ?string $input = null, array $configuration = []): void
     {
+        $this->fixer->configure($configuration);
         $this->doTest($expected, $input);
     }
 
@@ -246,138 +249,7 @@ private $d = 123;
                     }
                 ',
         ];
-    }
-
-    /**
-     * @param array<mixed> $elements
-     *
-     * @dataProvider provideInvalidElementsCases
-     */
-    public function testInvalidElements(array $elements): void
-    {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->fixer->configure(['elements' => $elements]);
-    }
-
-    public static function provideInvalidElementsCases(): iterable
-    {
-        yield 'numeric keys' => [['method', 'property']];
-
-        yield 'wrong key name' => [['methods' => 'one']];
-
-        yield 'wrong key value' => [['method' => 'two']];
-    }
-
-    /**
-     * @dataProvider provideCommentBlockStartDetectionCases
-     */
-    public function testCommentBlockStartDetection(int $expected, string $code, int $index): void
-    {
-        Tokens::clearCache();
-        $tokens = Tokens::fromCode($code);
-        $method = new \ReflectionMethod($this->fixer, 'findCommentBlockStart');
-        $method->setAccessible(true);
-
-        $result = $method->invoke($this->fixer, $tokens, $index, 0);
-        self::assertSame(
-            $expected,
-            $result,
-            sprintf('Expected index %d (%s) got index %d (%s).', $expected, $tokens[$expected]->toJson(), $result, $tokens[$result]->toJson())
-        );
-    }
-
-    public static function provideCommentBlockStartDetectionCases(): iterable
-    {
-        yield [
-            4,
-            '<?php
-                    //ui
-
-                    //j1
-                    //k2
-                ',
-            6,
-        ];
-
-        yield [
-            4,
-            '<?php
-                    //ui
-
-                    //j1
-                    //k2
-                ',
-            5,
-        ];
-
-        yield [
-            4,
-            '<?php
-                    /**/
-
-                    //j1
-                    //k2
-                ',
-            6,
-        ];
-
-        yield [
-            4,
-            '<?php
-                    $a;//j
-                    //k
-                ',
-            6,
-        ];
-
-        yield [
-            2,
-            '<?php
-                    //a
-                ',
-            2,
-        ];
-
-        yield [
-            2,
-            '<?php
-                    //b
-                    //c
-                ',
-            2,
-        ];
-
-        yield [
-            2,
-            '<?php
-                    //d
-                    //e
-                ',
-            4,
-        ];
-
-        yield [
-            2,
-            '<?php
-                    /**/
-                    //f
-                    //g
-                    //h
-                ',
-            8,
-        ];
-    }
 
-    /**
-     * @dataProvider provideFixClassesCases
-     */
-    public function testFixClasses(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixClassesCases(): iterable
-    {
         yield ['<?php
 class SomeClass1
 {
@@ -962,18 +834,7 @@ public function B1(); // allowed comment
                 }
             ',
         ];
-    }
-
-    /**
-     * @dataProvider provideFixTraitsCases
-     */
-    public function testFixTraits(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
 
-    public static function provideFixTraitsCases(): iterable
-    {
         // do not touch well formatted traits
         yield [
             '<?php
@@ -1052,18 +913,7 @@ trait SomeReturnInfo {
     abstract public function getWorld();
 }',
         ];
-    }
-
-    /**
-     * @dataProvider provideFixInterfaceCases
-     */
-    public function testFixInterface(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
 
-    public static function provideFixInterfaceCases(): iterable
-    {
         yield [
             '<?php
 interface TestInterface
@@ -1132,44 +982,7 @@ class ezcReflectionMethod extends ReflectionMethod {
 
 }',
         ];
-    }
 
-    /**
-     * @dataProvider provideMessyWhitespacesCases
-     */
-    public function testMessyWhitespaces(string $expected, ?string $input = null): void
-    {
-        $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
-
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideMessyWhitespacesCases(): iterable
-    {
-        yield [
-            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\n\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
-            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\n\n\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
-        ];
-
-        yield [
-            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\r\n\r\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
-            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\r\n\r\n\r\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
-        ];
-    }
-
-    /**
-     * @param array<string, mixed> $config
-     *
-     * @dataProvider provideWithConfigCases
-     */
-    public function testWithConfig(string $expected, ?string $input, array $config): void
-    {
-        $this->fixer->configure($config);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideWithConfigCases(): iterable
-    {
         yield 'multi line property' => [
             '<?php class Foo
 {
@@ -1802,21 +1615,7 @@ abstract class Example
                 ',
             ['elements' => ['property' => 'none', 'trait_import' => 'none']],
         ];
-    }
 
-    /**
-     * @dataProvider provideFix71Cases
-     */
-    public function testFix71(string $expected, string $input): void
-    {
-        $this->fixer->configure([
-            'elements' => ['method' => 'one', 'const' => 'one'],
-        ]);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFix71Cases(): iterable
-    {
         yield [
             '<?php
                 class Foo {
@@ -1844,22 +1643,7 @@ abstract class Example
 
                 }',
         ];
-    }
-
-    /**
-     * @param array<string, mixed> $config
-     *
-     * @dataProvider provideFix74Cases
-     */
-    public function testFix74(string $expected, ?string $input = null, array $config = []): void
-    {
-        $this->fixer->configure($config);
-
-        $this->doTest($expected, $input);
-    }
 
-    public static function provideFix74Cases(): iterable
-    {
         yield [
             '<?php
             class Foo {
@@ -1931,23 +1715,44 @@ abstract class Example
             }',
             ['elements' => ['property' => 'only_if_meta']],
         ];
+
+        yield [
+            '<?php
+class Foo
+{
+    use SomeTrait1;
+    use SomeTrait2;
+
+    public function Bar(){}
+}
+',
+            '<?php
+class Foo
+{
+    use SomeTrait1;
+
+    use SomeTrait2;
+    public function Bar(){}
+}
+',
+        ];
     }
 
     /**
      * @param array<string, mixed> $config
      *
-     * @dataProvider provideFixPhp80Cases
+     * @dataProvider provideFix80Cases
      *
      * @requires PHP 8.0
      */
-    public function testFixPhp80(string $expected, ?string $input, array $config = []): void
+    public function testFix80(string $expected, ?string $input, array $config = []): void
     {
         $this->fixer->configure($config);
 
         $this->doTest($expected, $input);
     }
 
-    public static function provideFixPhp80Cases(): iterable
+    public static function provideFix80Cases(): iterable
     {
         yield 'attributes' => [
             '<?php
@@ -2162,38 +1967,6 @@ class Foo
         ];
     }
 
-    /**
-     * @dataProvider provideFixClassesWithTraitsCases
-     */
-    public function testFixClassesWithTraits(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixClassesWithTraitsCases(): iterable
-    {
-        yield [
-            '<?php
-class Foo
-{
-    use SomeTrait1;
-    use SomeTrait2;
-
-    public function Bar(){}
-}
-',
-            '<?php
-class Foo
-{
-    use SomeTrait1;
-
-    use SomeTrait2;
-    public function Bar(){}
-}
-',
-        ];
-    }
-
     /**
      * @param array<string, mixed> $config
      *
@@ -2405,4 +2178,147 @@ enum Cards: string
             }',
         ];
     }
+
+    /**
+     * @dataProvider provideWithWhitespacesConfigCases
+     */
+    public function testWithWhitespacesConfig(string $expected, ?string $input = null): void
+    {
+        $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
+
+        $this->doTest($expected, $input);
+    }
+
+    public static function provideWithWhitespacesConfigCases(): iterable
+    {
+        yield [
+            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\n\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
+            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\n\n\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
+        ];
+
+        yield [
+            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\r\n\r\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
+            "<?php\r\nclass SomeClass\r\n{\r\n    // comment\r\n\r\n\r\n    public function echoA()\r\n    {\r\n        echo 'a';\r\n    }\r\n}\r\n",
+        ];
+    }
+
+    /**
+     * @param array<mixed> $elements
+     *
+     * @dataProvider provideInvalidConfigurationCases
+     */
+    public function testInvalidConfiguration(array $elements): void
+    {
+        $this->expectException(InvalidFixerConfigurationException::class);
+        $this->fixer->configure(['elements' => $elements]);
+    }
+
+    public static function provideInvalidConfigurationCases(): iterable
+    {
+        yield 'numeric keys' => [['method', 'property']];
+
+        yield 'wrong key name' => [['methods' => 'one']];
+
+        yield 'wrong key value' => [['method' => 'two']];
+    }
+
+    /**
+     * @dataProvider provideCommentBlockStartDetectionCases
+     */
+    public function testCommentBlockStartDetection(int $expected, string $code, int $index): void
+    {
+        Tokens::clearCache();
+        $tokens = Tokens::fromCode($code);
+        $method = new \ReflectionMethod($this->fixer, 'findCommentBlockStart');
+        $method->setAccessible(true);
+
+        $result = $method->invoke($this->fixer, $tokens, $index, 0);
+        self::assertSame(
+            $expected,
+            $result,
+            sprintf('Expected index %d (%s) got index %d (%s).', $expected, $tokens[$expected]->toJson(), $result, $tokens[$result]->toJson())
+        );
+    }
+
+    public static function provideCommentBlockStartDetectionCases(): iterable
+    {
+        yield [
+            4,
+            '<?php
+                    //ui
+
+                    //j1
+                    //k2
+                ',
+            6,
+        ];
+
+        yield [
+            4,
+            '<?php
+                    //ui
+
+                    //j1
+                    //k2
+                ',
+            5,
+        ];
+
+        yield [
+            4,
+            '<?php
+                    /**/
+
+                    //j1
+                    //k2
+                ',
+            6,
+        ];
+
+        yield [
+            4,
+            '<?php
+                    $a;//j
+                    //k
+                ',
+            6,
+        ];
+
+        yield [
+            2,
+            '<?php
+                    //a
+                ',
+            2,
+        ];
+
+        yield [
+            2,
+            '<?php
+                    //b
+                    //c
+                ',
+            2,
+        ];
+
+        yield [
+            2,
+            '<?php
+                    //d
+                    //e
+                ',
+            4,
+        ];
+
+        yield [
+            2,
+            '<?php
+                    /**/
+                    //f
+                    //g
+                    //h
+                ',
+            8,
+        ];
+    }
 }

+ 92 - 151
tests/Fixer/ClassNotation/ClassDefinitionFixerTest.php

@@ -27,7 +27,7 @@ use PhpCsFixer\WhitespacesFixerConfig;
  */
 final class ClassDefinitionFixerTest extends AbstractFixerTestCase
 {
-    public function testConfigureDefaultToFalse(): void
+    public function testConfigure(): void
     {
         $defaultConfig = [
             'inline_constructor_arguments' => true,
@@ -46,79 +46,46 @@ final class ClassDefinitionFixerTest extends AbstractFixerTestCase
     }
 
     /**
-     * @param string              $expected PHP source code
-     * @param string              $input    PHP source code
-     * @param array<string, bool> $config
+     * @param array<mixed> $config
      *
-     * @dataProvider provideFixingAnonymousClassesCases
+     * @dataProvider provideInvalidConfigurationCases
      */
-    public function testFixingAnonymousClasses(string $expected, string $input, array $config = []): void
+    public function testInvalidConfiguration(array $config, string $exceptionExpression): void
     {
-        $this->fixer->configure($config);
-        $this->doTest($expected, $input);
-    }
-
-    /**
-     * @dataProvider provideFixingClassesCases
-     */
-    public function testFixingClasses(string $expected, string $input): void
-    {
-        $this->fixer->configure([]);
-        $this->doTest($expected, $input);
-    }
+        $this->expectException(InvalidFixerConfigurationException::class);
+        $this->expectExceptionMessageMatches($exceptionExpression);
 
-    /**
-     * @param array<string, mixed> $config
-     *
-     * @dataProvider provideFixingClassesWithConfigCases
-     */
-    public function testFixingClassesWithConfig(string $expected, string $input, array $config): void
-    {
         $this->fixer->configure($config);
-        $this->doTest($expected, $input);
     }
 
     /**
-     * @dataProvider provideFixingInterfacesCases
+     * @return iterable<array{array<mixed>, string}>
      */
-    public function testFixingInterfaces(string $expected, string $input): void
+    public static function provideInvalidConfigurationCases(): iterable
     {
-        $this->fixer->configure([]);
-        $this->doTest($expected, $input);
+        yield 'invalid configuration key' => [
+            ['a' => false],
+            '/^\[class_definition\] Invalid configuration: The option "a" does not exist\. Defined options are: "inline_constructor_arguments", "multi_line_extends_each_single_line", "single_item_single_line", "single_line", "space_before_parenthesis"\.$/',
+        ];
+
+        yield 'invalid configuration value' => [
+            ['single_line' => 'z'],
+            '/^\[class_definition\] Invalid configuration: The option "single_line" with value "z" is expected to be of type "bool", but is of type "string"\.$/',
+        ];
     }
 
     /**
-     * @dataProvider provideFixingTraitsCases
+     * @param array<string, bool> $configuration
+     *
+     * @dataProvider provideFixCases
      */
-    public function testFixingTraits(string $expected, string $input): void
+    public function testFix(string $expected, string $input, array $configuration = []): void
     {
-        $this->fixer->configure([]);
+        $this->fixer->configure($configuration);
         $this->doTest($expected, $input);
     }
 
-    public function testInvalidConfigurationKey(): void
-    {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches(
-            '/^\[class_definition\] Invalid configuration: The option "a" does not exist\. Defined options are: "inline_constructor_arguments", "multi_line_extends_each_single_line", "single_item_single_line", "single_line", "space_before_parenthesis"\.$/'
-        );
-
-        $fixer = new ClassDefinitionFixer();
-        $fixer->configure(['a' => false]);
-    }
-
-    public function testInvalidConfigurationValueType(): void
-    {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches(
-            '/^\[class_definition\] Invalid configuration: The option "single_line" with value "z" is expected to be of type "bool", but is of type "string"\.$/'
-        );
-
-        $fixer = new ClassDefinitionFixer();
-        $fixer->configure(['single_line' => 'z']);
-    }
-
-    public static function provideFixingAnonymousClassesCases(): iterable
+    public static function provideFixCases(): iterable
     {
         yield [
             '<?php $a = new class(0) extends SomeClass implements SomeInterface, D {};',
@@ -337,19 +304,13 @@ A#
             '<?php $z = new class   ( static::foo($this->bar())  ,baz() )  {};',
             ['space_before_parenthesis' => true, 'inline_constructor_arguments' => false],
         ];
-    }
 
-    public static function provideFixingClassesCases(): iterable
-    {
-        return array_merge(
-            self::provideClassyCases('class'),
-            self::provideClassyExtendingCases('class'),
-            self::provideClassyImplementsCases()
-        );
-    }
+        yield from self::provideClassyCases('class');
+
+        yield from self::provideClassyExtendingCases('class');
+
+        yield from self::provideClassyImplementsCases();
 
-    public static function provideFixingClassesWithConfigCases(): iterable
-    {
         yield [
             "<?php class configA implements B, C\n{}",
             "<?php class configA implements\nB, C{}",
@@ -401,14 +362,10 @@ A#
                 'multi_line_extends_each_single_line' => true,
             ],
         ];
-    }
 
-    public static function provideFixingInterfacesCases(): iterable
-    {
-        yield from array_merge(
-            self::provideClassyCases('interface'),
-            self::provideClassyExtendingCases('interface')
-        );
+        yield from self::provideClassyCases('interface');
+
+        yield from self::provideClassyExtendingCases('interface');
 
         yield [
             '<?php
@@ -436,11 +393,54 @@ TestInterface3, /**/     TestInterface4   ,
         /**/TestInterface65    {}
             ',
         ];
-    }
 
-    public static function provideFixingTraitsCases(): iterable
-    {
-        return self::provideClassyCases('trait');
+        yield from self::provideClassyCases('trait');
+
+        yield [
+            '<?php
+$a = new class implements
+    \RFb,
+    \Fcc,
+    \GFddZz
+{
+};',
+            '<?php
+$a = new class implements
+    \RFb,
+    \Fcc, \GFddZz
+{
+};',
+        ];
+
+        yield [
+            '<?php
+$a = new class implements
+    \RFb,
+    \Fcc,
+    \GFddZz
+{
+}?>',
+            '<?php
+$a = new class implements
+    \RFb,
+    \Fcc, \GFddZz
+{
+}?>',
+        ];
+
+        yield [
+            '<?php new class(1, 2, 3, ) {};',
+            '<?php new class(1, 2, 3,) {};',
+        ];
+
+        yield [
+            '<?php new class(1, 2, 3, ) {};',
+            '<?php new class(
+                    1,
+                    2,
+                    3,
+                ) {};',
+        ];
     }
 
     /**
@@ -669,74 +669,15 @@ namespace {
     }
 
     /**
-     * @dataProvider provideFixCases
-     */
-    public function testFix(string $expected, ?string $input = null): void
-    {
-        $this->fixer->configure([]);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixCases(): iterable
-    {
-        yield [
-            '<?php
-$a = new class implements
-    \RFb,
-    \Fcc,
-    \GFddZz
-{
-};',
-            '<?php
-$a = new class implements
-    \RFb,
-    \Fcc, \GFddZz
-{
-};',
-        ];
-
-        yield [
-            '<?php
-$a = new class implements
-    \RFb,
-    \Fcc,
-    \GFddZz
-{
-}?>',
-            '<?php
-$a = new class implements
-    \RFb,
-    \Fcc, \GFddZz
-{
-}?>',
-        ];
-
-        yield [
-            '<?php new class(1, 2, 3, ) {};',
-            '<?php new class(1, 2, 3,) {};',
-        ];
-
-        yield [
-            '<?php new class(1, 2, 3, ) {};',
-            '<?php new class(
-                    1,
-                    2,
-                    3,
-                ) {};',
-        ];
-    }
-
-    /**
-     * @dataProvider provideMessyWhitespacesCases
+     * @dataProvider provideWithWhitespacesConfigCases
      */
-    public function testMessyWhitespaces(string $expected, ?string $input = null): void
+    public function testWithWhitespacesConfig(string $expected, ?string $input = null): void
     {
         $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
-        $this->fixer->configure([]);
         $this->doTest($expected, $input);
     }
 
-    public static function provideMessyWhitespacesCases(): iterable
+    public static function provideWithWhitespacesConfigCases(): iterable
     {
         yield [
             "<?php\r\nclass Aaa implements\r\n\tBbb,\r\n\tCcc,\r\n\tDdd\r\n\t{\r\n\t}",
@@ -862,17 +803,6 @@ $a = new class implements
         ];
     }
 
-    /**
-     * @param array<string, mixed> $expected
-     */
-    private static function assertConfigurationSame(array $expected, ClassDefinitionFixer $fixer): void
-    {
-        $reflectionProperty = new \ReflectionProperty($fixer, 'configuration');
-        $reflectionProperty->setAccessible(true);
-
-        self::assertSame($expected, $reflectionProperty->getValue($fixer));
-    }
-
     /**
      * @param array<string, mixed> $expected
      */
@@ -889,6 +819,17 @@ $a = new class implements
         self::assertSame($expected, $result);
     }
 
+    /**
+     * @param array<string, mixed> $expected
+     */
+    private static function assertConfigurationSame(array $expected, ClassDefinitionFixer $fixer): void
+    {
+        $reflectionProperty = new \ReflectionProperty($fixer, 'configuration');
+        $reflectionProperty->setAccessible(true);
+
+        self::assertSame($expected, $reflectionProperty->getValue($fixer));
+    }
+
     private static function provideClassyCases(string $classy): iterable
     {
         return [

+ 39 - 63
tests/Fixer/ClassNotation/FinalInternalClassFixerTest.php

@@ -25,13 +25,13 @@ use PhpCsFixer\Tests\Test\AbstractFixerTestCase;
 final class FinalInternalClassFixerTest extends AbstractFixerTestCase
 {
     /**
-     * @param string      $expected PHP source code
-     * @param null|string $input    PHP source code
+     * @param array<string, string> $configuration
      *
      * @dataProvider provideFixCases
      */
-    public function testFix(string $expected, ?string $input = null): void
+    public function testFix(string $expected, ?string $input = null, array $configuration = []): void
     {
+        $this->fixer->configure($configuration);
         $this->doTest($expected, $input);
     }
 
@@ -186,21 +186,7 @@ class Foo {}
 class Bar {}
 ',
         ];
-    }
 
-    /**
-     * @param array<string, mixed> $config
-     *
-     * @dataProvider provideFixWithConfigCases
-     */
-    public function testFixWithConfig(string $expected, string $input, array $config): void
-    {
-        $this->fixer->configure($config);
-        $this->doTest($expected, $input);
-    }
-
-    public static function provideFixWithConfigCases(): iterable
-    {
         yield [
             "<?php\n/** @CUSTOM */final class A{}",
             "<?php\n/** @CUSTOM */class A{}",
@@ -338,24 +324,7 @@ class Foo {}
                 'exclude' => ['Hello'],
             ],
         ];
-    }
-
-    /**
-     * @param string      $expected PHP source code
-     * @param null|string $input    PHP source code
-     *
-     * @dataProvider provideAnonymousClassesCases
-     */
-    public function testAnonymousClasses(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
 
-    /**
-     * @return iterable<int|string, array{0: string, 1?: string}>
-     */
-    public static function provideAnonymousClassesCases(): iterable
-    {
         yield [
             '<?php
 /** @internal */
@@ -373,47 +342,54 @@ $a = new class{};',
         ];
     }
 
-    public function testConfigureSameAnnotationInBothLists(): void
-    {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches(
-            sprintf('#^%s$#', preg_quote('[final_internal_class] Annotation cannot be used in both "include" and "exclude" list, got duplicates: "internal123".', '#'))
-        );
-
-        $this->fixer->configure([
-            'include' => ['@internal123', 'a'],
-            'exclude' => ['@internal123', 'b'],
-        ]);
-    }
-
     /**
      * @group legacy
+     *
+     * @param array<mixed> $config
+     *
+     * @dataProvider provideInvalidConfigurationCases
      */
-    public function testConfigureBothNewAndOldIncludeSet(): void
+    public function testInvalidConfiguration(array $config, string $exceptionExpression, ?string $deprecationMessage = null): void
     {
         $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches(sprintf('#^%s$#', preg_quote('[final_internal_class] Configuration cannot contain deprecated option "annotation_include" and new option "include".', '#')));
-        $this->expectDeprecation('Option "annotation_include" for rule "final_internal_class" is deprecated and will be removed in version 4.0. Use "include" to configure PHPDoc annotations tags and attributes.');
+        $this->expectExceptionMessageMatches($exceptionExpression);
+        if (null !== $deprecationMessage) {
+            $this->expectDeprecation($deprecationMessage);
+        }
 
-        $this->fixer->configure([
-            'annotation_include' => ['@internal', 'a'],
-            'include' => ['@internal', 'b'],
-        ]);
+        $this->fixer->configure($config);
     }
 
     /**
-     * @group legacy
+     * @return iterable<array{array<mixed>, string, 2?: string}>
      */
-    public function testConfigureBothNewAndOldExcludeSet(): void
+    public static function provideInvalidConfigurationCases(): iterable
     {
-        $this->expectException(InvalidFixerConfigurationException::class);
-        $this->expectExceptionMessageMatches(sprintf('#^%s$#', preg_quote('[final_internal_class] Configuration cannot contain deprecated option "annotation_exclude" and new option "exclude".', '#')));
-        $this->expectDeprecation('Option "annotation_exclude" for rule "final_internal_class" is deprecated and will be removed in version 4.0. Use "exclude" to configure PHPDoc annotations tags and attributes.');
+        yield 'same annotation in both lists' => [
+            [
+                'include' => ['@internal123', 'a'],
+                'exclude' => ['@internal123', 'b'],
+            ],
+            sprintf('#^%s$#', preg_quote('[final_internal_class] Annotation cannot be used in both "include" and "exclude" list, got duplicates: "internal123".', '#')),
+        ];
+
+        yield 'both new and old include set' => [
+            [
+                'annotation_include' => ['@internal', 'a'],
+                'include' => ['@internal', 'b'],
+            ],
+            sprintf('#^%s$#', preg_quote('[final_internal_class] Configuration cannot contain deprecated option "annotation_include" and new option "include".', '#')),
+            'Option "annotation_include" for rule "final_internal_class" is deprecated and will be removed in version 4.0. Use "include" to configure PHPDoc annotations tags and attributes.',
+        ];
 
-        $this->fixer->configure([
-            'annotation_exclude' => ['@internal', 'a'],
-            'exclude' => ['@internal', 'b'],
-        ]);
+        yield 'both new and old exclude set' => [
+            [
+                'annotation_exclude' => ['@internal', 'a'],
+                'exclude' => ['@internal', 'b'],
+            ],
+            sprintf('#^%s$#', preg_quote('[final_internal_class] Configuration cannot contain deprecated option "annotation_exclude" and new option "exclude".', '#')),
+            'Option "annotation_exclude" for rule "final_internal_class" is deprecated and will be removed in version 4.0. Use "exclude" to configure PHPDoc annotations tags and attributes.',
+        ];
     }
 
     /**

+ 3 - 14
tests/Fixer/ClassNotation/NoBlankLinesAfterClassOpeningFixerTest.php

@@ -34,14 +34,6 @@ final class NoBlankLinesAfterClassOpeningFixerTest extends AbstractFixerTestCase
         $this->doTest($expected, $input);
     }
 
-    /**
-     * @dataProvider provideFixTraitsCases
-     */
-    public function testFixTraits(string $expected, ?string $input = null): void
-    {
-        $this->doTest($expected, $input);
-    }
-
     public static function provideFixCases(): iterable
     {
         yield [
@@ -158,10 +150,7 @@ function bar() {}
 }
 ',
         ];
-    }
 
-    public static function provideFixTraitsCases(): iterable
-    {
         yield [
             '<?php
 trait Good
@@ -184,16 +173,16 @@ trait Good
     }
 
     /**
-     * @dataProvider provideMessyWhitespacesCases
+     * @dataProvider provideWithWhitespacesConfigCases
      */
-    public function testMessyWhitespaces(string $expected, ?string $input = null): void
+    public function testWithWhitespacesConfig(string $expected, ?string $input = null): void
     {
         $this->fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n"));
 
         $this->doTest($expected, $input);
     }
 
-    public static function provideMessyWhitespacesCases(): iterable
+    public static function provideWithWhitespacesConfigCases(): iterable
     {
         yield [
             "<?php\nclass Foo\n{\r\n    public function bar() {}\n}",

Some files were not shown because too many files changed in this diff