* 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\Comment; use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; use PhpCsFixer\ConfigurationException\RequiredFixerConfigurationException; use PhpCsFixer\Fixer\Comment\HeaderCommentFixer; use PhpCsFixer\Tests\Test\AbstractFixerTestCase; use PhpCsFixer\WhitespacesFixerConfig; /** * @internal * * @covers \PhpCsFixer\Fixer\Comment\HeaderCommentFixer * * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Comment\HeaderCommentFixer> * * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Comment\HeaderCommentFixer */ final class HeaderCommentFixerTest extends AbstractFixerTestCase { /** * @param _AutogeneratedInputConfiguration $configuration * * @dataProvider provideFixCases */ public function testFix(array $configuration, string $expected, ?string $input = null): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFixCases(): iterable { yield [ ['header' => ''], ' 'tmp', 'location' => 'after_declare_strict', ], ' 'tmp', 'location' => 'after_declare_strict', 'separate' => 'bottom', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'tmp', 'location' => 'after_open', ], ' 'new', 'comment_type' => HeaderCommentFixer::HEADER_COMMENT, ], ' 'new', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'def', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'xyz'], ' 'xyz123', 'separate' => 'none', ], ' 'abc', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'ghi', 'separate' => 'both', ], ' 'ghi', 'separate' => 'top', ], ' 'tmp', 'location' => 'after_declare_strict', ], ' 'Foo'], ' 'x'], ' "a\na"], ' 'foo', 'location' => 'after_open', 'separate' => 'bottom', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'foo', 'location' => 'after_open', 'separate' => 'bottom', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'Foo', 'separate' => 'none', ], ' 'tmp'], ' 'tmp'], ' 'tmp', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'tmp', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], ' 'tmp', 'separate' => 'top', ], ' 'bar', 'location' => 'after_open', ], ' 'bar', 'location' => 'after_open', ], ' 'tmp', 'location' => 'after_declare_strict', ], '', '', ]; yield [ [ 'header' => 'tmp', 'location' => 'after_declare_strict', ], '#!/usr/bin/env php 'tmp', 'location' => 'after_open', ], 'Short mixed file A Hello', ]; yield [ [ 'header' => 'tmp', 'location' => 'after_open', ], 'Short mixed file B World!', ]; yield [ [ 'header' => 'tmp', 'location' => 'after_open', ], 'File with anything at the beginning and with multiple opening tags are not supported Hello World!fixer->configure(['header' => 'a']); $this->doTest( 'expectException(InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches("#^\\[header_comment\\] {$exceptionMessage}$#"); $this->fixer->configure($configuration); } public static function provideMisconfigurationCases(): iterable { yield [[], 'Missing required configuration: The required option "header" is missing.']; yield [ ['header' => 1], 'Invalid configuration: The option "header" with value 1 is expected to be of type "string", but is of type "(int|integer)"\.', ]; yield [ [ 'header' => '', 'comment_type' => 'foo', ], 'Invalid configuration: The option "comment_type" with value "foo" is invalid\. Accepted values are: "PHPDoc", "comment"\.', ]; yield [ [ 'header' => '', 'comment_type' => new \stdClass(), ], 'Invalid configuration: The option "comment_type" with value stdClass is invalid\. Accepted values are: "PHPDoc", "comment"\.', ]; yield [ [ 'header' => '', 'location' => new \stdClass(), ], 'Invalid configuration: The option "location" with value stdClass is invalid\. Accepted values are: "after_open", "after_declare_strict"\.', ]; yield [ [ 'header' => '', 'separate' => new \stdClass(), ], 'Invalid configuration: The option "separate" with value stdClass is invalid\. Accepted values are: "both", "top", "bottom", "none"\.', ]; } /** * @dataProvider provideHeaderGenerationCases * * @param HeaderCommentFixer::HEADER_* $type */ public function testHeaderGeneration(string $expected, string $header, string $type): void { $this->fixer->configure([ 'header' => $header, 'comment_type' => $type, ]); $this->doTest( ' */ public static function provideHeaderGenerationCases(): iterable { yield [ '/* * a */', 'a', HeaderCommentFixer::HEADER_COMMENT, ]; yield [ '/** * a */', 'a', HeaderCommentFixer::HEADER_PHPDOC, ]; } /** * @dataProvider provideDoNotTouchCases */ public function testDoNotTouch(string $expected): void { $this->fixer->configure([ 'header' => '', ]); $this->doTest($expected); } /** * @return iterable */ public static function provideDoNotTouchCases(): iterable { yield ["\n
"]; yield [" ']; yield ["\nexpectException(RequiredFixerConfigurationException::class); $this->doTest('fixer->setWhitespacesConfig(new WhitespacesFixerConfig("\t", "\r\n")); $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideMessyWhitespacesCases(): iterable { yield [ [ 'header' => 'whitemess', 'location' => 'after_declare_strict', 'separate' => 'bottom', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ], "fixer->configure(['header' => 'Foo']); $this->doTest( "fixer->setWhitespacesConfig(new WhitespacesFixerConfig(' ', "\r\n")); $this->doTest( "fixer->configure(['header' => 'Bar']); $this->doTest( "fixer->setWhitespacesConfig(new WhitespacesFixerConfig(' ', "\n")); $this->doTest( "expectException(InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches('#^\[header_comment\] Cannot use \'\*/\' in header\.$#'); $this->fixer->configure([ 'header' => '/** test */', 'comment_type' => HeaderCommentFixer::HEADER_PHPDOC, ]); } /** * @param _AutogeneratedInputConfiguration $configuration * * @dataProvider provideFix81Cases * * @requires PHP 8.1 */ public function testFix81(array $configuration, string $expected, ?string $input = null): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFix81Cases(): iterable { yield [ ['header' => 'tmp'], '