* 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\Tests\Test\AbstractFixerTestCase; /** * @internal * * @covers \PhpCsFixer\Fixer\ClassNotation\FinalInternalClassFixer */ final class FinalInternalClassFixerTest extends AbstractFixerTestCase { /** * @param string $expected PHP source code * @param null|string $input PHP source code * * @dataProvider provideFixCases */ public function testFix(string $expected, ?string $input = null): void { $this->doTest($expected, $input); } public static function provideFixCases(): iterable { $input = $expected = ' [ $expected, $input, ]; yield [ ' [ ' [ ' [ ' $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 [ " ['@Custom'], ], ]; yield [ ' ['@Custom', '@abc'], ], ]; yield [ ' ['@Custom', '@internal'], 'exclude' => ['@not-fix'], ], ]; yield [ ' ['abc'], ], ]; yield [ ' true], ]; yield 'class with annotation with matching include and partial matching exclude' => [ ' ['HelloWorld'], '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 */ public static function provideAnonymousClassesCases(): iterable { yield [ '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 */ public function testConfigureBothNewAndOldIncludeSet(): 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->fixer->configure([ 'annotation_include' => ['@internal', 'a'], 'include' => ['@internal', 'b'], ]); } /** * @group legacy */ public function testConfigureBothNewAndOldExcludeSet(): void { $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.'); $this->fixer->configure([ 'annotation_exclude' => ['@internal', 'a'], 'exclude' => ['@internal', 'b'], ]); } /** * @param array> $config * * @dataProvider provideFix80Cases * * @requires PHP 8.0 */ public function testFix80(string $expected, ?string $input, array $config): void { $this->fixer->configure($config); $this->doTest($expected, $input); } /** * @return iterable, include?: list}}> */ public static function provideFix80Cases(): iterable { yield 'multiple attributes, all configured as not to fix' => [ ' ['a', 'X']], ]; yield 'multiple attributes, one configured as to fix, one as not to fix' => [ ' ['internal'], 'exclude' => ['A'], ], ]; yield 'multiple attributes, one configured as to fix' => [ ' ['internal']], ]; yield 'single attribute configured as to fix' => [ ' ['internal']], ]; yield 'class that should be ignored as it has an attribute not included with absent docblock as true' => [ ' true], ]; yield 'mixed bag of cases' => [ ' ['Entity', 'A'], 'include' => ['orm\entity', 'B'], ], ]; yield 'multiple classes, first configured with attribute, second without attribute' => [ ' ['internal']], ]; yield 'multiple classes, first configured without attribute, second with attribute' => [ ' ['internal']], ]; yield 'include by attribute, but exclude by doc' => [ ' ['final'], 'include' => ['A'], ], ]; yield 'include by phpDoc, but exclude by attribute' => [ ' ['Internal'], 'include' => ['A'], ], ]; yield 'comment between attributes' => [ ' ['A', 'C'], ], ]; } /** * @param array $config * * @dataProvider provideFix82Cases * * @requires PHP 8.2 */ public function testFix82(string $expected, ?string $input, array $config): void { $this->fixer->configure($config); $this->doTest($expected, $input); } /** * @return iterable, include?: list}}> */ public static function provideFix82Cases(): iterable { yield 'readonly with enabled `consider_absent_docblock_as_internal_class`' => [ ' true], ]; yield 'readonly with `internal` attribute and comment in-between' => [ ' true], ]; } }