* 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\Alias; use PhpCsFixer\AbstractFixer; use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; use PhpCsFixer\Tests\Test\AbstractFixerTestCase; /** * @author Sullivan Senechal * * @internal * * @covers \PhpCsFixer\Fixer\Alias\NoMixedEchoPrintFixer * * @extends AbstractFixerTestCase<\PhpCsFixer\Fixer\Alias\NoMixedEchoPrintFixer> * * @phpstan-import-type _AutogeneratedInputConfiguration from \PhpCsFixer\Fixer\Alias\NoMixedEchoPrintFixer */ final class NoMixedEchoPrintFixerTest 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); } /** * @return iterable */ public static function provideFixCases(): iterable { yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; // `echo` can take multiple parameters (although such usage is rare) while `print` can take only one argument, // @see https://php.net/manual/en/function.echo.php and @see https://php.net/manual/en/function.print.php yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ ' 'print'], ]; yield [ "...", "...", ['use' => 'print'], ]; yield [ ' 'print'], ]; yield [ '', null, ['use' => 'print'], ]; foreach (self::getCodeSnippetsToConvertBothWays() as $codeSnippet) { yield [ \sprintf($codeSnippet, 'print'), \sprintf($codeSnippet, 'echo'), ['use' => 'print'], ]; } yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; // https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/1502#issuecomment-156436229 yield [ ' 'echo'], ]; // echo has no return value while print has a return value of 1 so it can be used in expressions. // https://www.w3schools.com/php/php_echo_print.asp yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 0 ? \'a\' : \'b\'; switch(print(\'a\')) {} if (1 === print($a)) {} ', null, ['use' => 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; yield [ ' 'echo'], ]; foreach (self::getCodeSnippetsToConvertBothWays() as $codeSnippet) { yield [ \sprintf($codeSnippet, 'echo'), \sprintf($codeSnippet, 'print'), ['use' => 'echo'], ]; } } public function testConfigure(): void { $this->fixer->configure([]); self::assertCandidateTokenType(T_PRINT, $this->fixer); } /** * @param array $wrongConfig * * @dataProvider provideInvalidConfigurationCases */ public function testInvalidConfiguration(array $wrongConfig, string $expectedMessage): void { $this->expectException(InvalidFixerConfigurationException::class); $this->expectExceptionMessageMatches($expectedMessage); $this->fixer->configure($wrongConfig); } public static function provideInvalidConfigurationCases(): iterable { yield [ ['a' => 'b'], '#^\[no_mixed_echo_print\] Invalid configuration: The option "a" does not exist\. (Known|Defined) options are: "use"\.$#', ]; yield [ ['a' => 'b', 'b' => 'c'], '#^\[no_mixed_echo_print\] Invalid configuration: The options "a", "b" do not exist\. (Known|Defined) options are: "use"\.$#', ]; yield [ [1], '#^\[no_mixed_echo_print\] Invalid configuration: The option "0" does not exist\. (Known|Defined) options are: "use"\.$#', ]; yield [ ['use' => '_invalid_'], '#^\[no_mixed_echo_print\] Invalid configuration: The option "use" with value "_invalid_" is invalid\. Accepted values are: "print", "echo"\.$#', ]; } private static function assertCandidateTokenType(int $expected, AbstractFixer $fixer): void { $reflectionProperty = new \ReflectionProperty($fixer, 'candidateTokenType'); $reflectionProperty->setAccessible(true); self::assertSame($expected, $reflectionProperty->getValue($fixer)); } /** * @return iterable */ private static function getCodeSnippetsToConvertBothWays(): iterable { yield 'inside of HTML' => '
'; yield 'foreach without curly brackets' => ' '