* 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 * * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\ClassNotation\FinalInternalClassFixer> * * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\ClassNotation\FinalInternalClassFixer */ final class FinalInternalClassFixerTest extends AbstractFixerTestCase { /** * @param _AutogeneratedInputConfiguration $configuration * * @dataProvider provideFixCases */ public function testFix(string $expected, ?string $input = null, array $configuration = []): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFixCases(): iterable { $input = $expected = ' [ $expected, $input, ]; 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'], ], ]; yield [ 'expectException(InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches($exceptionExpression); if (null !== $deprecationMessage) { $this->expectDeprecation($deprecationMessage); } $this->fixer->configure($config); } /** * @return iterable, string, 2?: string}> */ public static function provideInvalidConfigurationCases(): iterable { 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.', ]; 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.', ]; } /** * @param _AutogeneratedInputConfiguration $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 _AutogeneratedInputConfiguration $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], ]; } }