* Dariusz RumiƄski * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\Tests\Fixer\ClassNotation; use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; use PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer; use PhpCsFixer\Tests\Test\AbstractFixerTestCase; /** * @author Gregor Harlan * * @internal * * @covers \PhpCsFixer\Fixer\ClassNotation\OrderedClassElementsFixer */ final class OrderedClassElementsFixerTest extends AbstractFixerTestCase { /** * @dataProvider provideFixCases */ public function testFix(string $expected, ?string $input = null): void { $this->doTest($expected, $input); } public static function provideFixCases(): iterable { yield [ <<<'EOT' foo1(1); } public static function foo3(self $foo) { return $foo->foo2(); } /* comment 1 */ /* comment 2 */ // comment /** * Docblock */ protected function foo4(\ArrayObject $object, array $array, $a = null) { bar(); if (!$a) { $a = function ($x) { var_dump($x); }; } } private function foo5() { } // end foo5 } EOT , <<<'EOT' foo1(1); } public static function setUpBeforeClass() {} public function __destruct() {} use Bar; public static function foo3(self $foo) { return $foo->foo2(); } /* comment 1 */ /* comment 2 */ // comment 3 protected $fooProtected = array(1, 2); public $fooPublic; /* comment for C2 */ const C2 = 2; public static function tearDownAfterclass() { } /* multiline comment */ protected function assertPostConditions() {} use Baz { abc as private; } protected function assertPreConditions() {} private function foo5() { } // end foo5 protected function __construct() { } // comment /** * Docblock */ protected function foo4(\ArrayObject $object, array $array, $a = null) { bar(); if (!$a) { $a = function ($x) { var_dump($x); }; } } } EOT ]; yield [ <<<'EOT' $configuration * * @dataProvider provideFixWithConfigurationCases */ public function testFixWithConfiguration(array $configuration, string $expected, string $input): void { $this->fixer->configure(['order' => $configuration]); $this->doTest($expected, $input); } public static function provideFixWithConfigurationCases(): iterable { yield [ ['use_trait', 'constant', 'property', 'construct', 'method', 'destruct'], <<<'EOT' $configuration * * @dataProvider provideFixWithSortingAlgorithmCases */ public function testFixWithSortingAlgorithm(array $configuration, string $expected, string $input): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFixWithSortingAlgorithmCases(): iterable { yield [ [ 'order' => [ 'property_public_static', 'method_public', 'method_private', ], 'sort_algorithm' => OrderedClassElementsFixer::SORT_ALPHA, ], <<<'EOT' [ 'use_trait', 'constant', 'property_public_static', 'property_protected_static', 'property_private_static', 'property_public', 'property_protected', 'property_private', 'construct', 'destruct', 'magic', 'method_public_static', 'method_protected_static', 'method_private_static', 'method_public', 'method_protected', 'method_private', ], 'sort_algorithm' => OrderedClassElementsFixer::SORT_ALPHA, ], <<<'EOT' privFunc(); } protected static function protStatFunc() {} private static function privStatFunc() {} public function pubFunc1() {} function pubFunc2() {} public function pubFunc3(int $b, int $c) { $a = $b*$c; return $a % 4; } protected function protFunc() {} private function privFunc() {} } EOT , <<<'EOT' privFunc(); } public function pubFunc1() {} public static function pubStatFunc1() {} private function privFunc() {} protected function __construct() {} protected static function protStatFunc() {} } EOT , ]; yield [ [ 'order' => [ 'use_trait', 'constant', 'property_public_static', 'property_protected_static', 'property_private_static', 'property_public', 'property_protected', 'property_private', 'construct', 'destruct', 'magic', 'method_public_static', 'method_public_abstract_static', 'method_protected_static', 'method_protected_abstract_static', 'method_private_static', 'method_public', 'method_public_abstract', 'method_protected', 'method_protected_abstract', 'method_private', ], 'sort_algorithm' => OrderedClassElementsFixer::SORT_ALPHA, ], <<<'EOT' privFunc(); } abstract public static function absPubStatFunc1(); protected static function protStatFunc() {} abstract protected static function absProtStatFunc(); private static function privStatFunc() {} public function pubFunc1() {} function pubFunc2() {} public function pubFunc3(int $b, int $c) { $a = $b*$c; return $a % 4; } abstract public function absPubFunc(); protected function protFunc() {} abstract protected function absProtFunc(); private function privFunc() {} } EOT , <<<'EOT' privFunc(); } public function pubFunc1() {} public static function pubStatFunc1() {} private function privFunc() {} protected function __construct() {} protected static function protStatFunc() {} abstract public static function absPubStatFunc1(); } EOT , ]; yield [ [], <<<'EOT' OrderedClassElementsFixer::SORT_ALPHA], <<<'EOT' OrderedClassElementsFixer::SORT_ALPHA], <<<'EOT' OrderedClassElementsFixer::SORT_ALPHA, 'case_sensitive' => true], <<<'EOT' $configuration * * @dataProvider provideFix74Cases */ public function testFix74(string $expected, ?string $input = null, array $configuration = []): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFix74Cases(): iterable { yield [ ' OrderedClassElementsFixer::SORT_ALPHA, ], ]; } public function testWrongConfig(): void { $this->expectException(InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches('/^\[ordered_class_elements\] Invalid configuration: The option "order" .*\.$/'); $this->fixer->configure(['order' => ['foo']]); } /** * @dataProvider provideWithConfigWithNoCandidateCases */ public function testWithConfigWithNoCandidate(string $methodName1, string $methodName2): void { $template = 'fixer->configure(['order' => ['use_trait'], 'sort_algorithm' => OrderedClassElementsFixer::SORT_ALPHA]); $this->doTest( sprintf($template, $methodName2, $methodName1), sprintf($template, $methodName1, $methodName2) ); } public static function provideWithConfigWithNoCandidateCases(): iterable { yield ['z', '__construct']; yield ['z', '__destruct']; yield ['z', '__sleep']; yield ['z', 'abc']; } /** * @dataProvider provideFix80Cases * * @requires PHP 8.0 */ public function testFix80(string $expected, string $input): void { $this->doTest($expected, $input); } public static function provideFix80Cases(): iterable { yield [ ' $configuration * * @dataProvider provideFix81Cases * * @requires PHP 8.1 */ public function testFix81(string $expected, ?string $input = null, array $configuration = []): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFix81Cases(): iterable { yield [ ' ['property_public_readonly', 'property_public', 'property_protected_readonly', 'property_private_readonly'], 'sort_algorithm' => 'alpha'], ]; yield [ 'doTest($expected, $input); } public static function provideFix82Cases(): iterable { yield [ '