* 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\FunctionNotation; use PhpCsFixer\ConfigurationException\InvalidConfigurationException; use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; use PhpCsFixer\Fixer\FunctionNotation\NativeFunctionInvocationFixer; use PhpCsFixer\Tests\Test\AbstractFixerTestCase; /** * @author Andreas Möller * * @internal * * @covers \PhpCsFixer\Fixer\FunctionNotation\NativeFunctionInvocationFixer */ final class NativeFunctionInvocationFixerTest extends AbstractFixerTestCase { public function testConfigureRejectsUnknownConfigurationKey(): void { $key = 'foo'; $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage(sprintf( '[native_function_invocation] Invalid configuration: The option "%s" does not exist.', $key )); $this->fixer->configure([ $key => 'bar', ]); } /** * @dataProvider provideConfigureRejectsInvalidConfigurationElementCases * * @param mixed $element */ public function testConfigureRejectsInvalidConfigurationElement($element): void { $this->expectException(InvalidConfigurationException::class); $this->expectExceptionMessage(sprintf( 'Each element must be a non-empty, trimmed string, got "%s" instead.', get_debug_type($element) )); $this->fixer->configure([ 'exclude' => [ $element, ], ]); } public static function provideConfigureRejectsInvalidConfigurationElementCases(): iterable { yield 'null' => [null]; yield 'false' => [false]; yield 'true' => [false]; yield 'int' => [1]; yield 'array' => [[]]; yield 'float' => [0.1]; yield 'object' => [new \stdClass()]; yield 'not-trimmed' => [' is_string ']; } /** * @param string[] $include * * @dataProvider provideConfigureIncludeSetsCases */ public function testConfigureIncludeSets( array $include, ?string $expectedExceptionClass = null, ?string $expectedExceptionMessage = null ): void { if (null !== $expectedExceptionClass) { $this->expectException($expectedExceptionClass); $this->expectExceptionMessageMatches(sprintf('#^%s$#', preg_quote($expectedExceptionMessage, '#'))); } $this->fixer->configure(['include' => $include]); if (null === $expectedExceptionClass) { $this->addToAssertionCount(1); } } public static function provideConfigureIncludeSetsCases(): iterable { yield [['foo', 'bar']]; yield [[NativeFunctionInvocationFixer::SET_ALL]]; yield [[NativeFunctionInvocationFixer::SET_ALL, 'bar']]; yield [ ['@xxx'], InvalidFixerConfigurationException::class, '[native_function_invocation] Invalid configuration: Unknown set "@xxx", known sets are "@all", "@internal" and "@compiler_optimized".', ]; yield [ [' x '], InvalidFixerConfigurationException::class, '[native_function_invocation] Invalid configuration: Each element must be a non-empty, trimmed string, got "string" instead.', ]; } public function testConfigureResetsExclude(): void { $this->fixer->configure([ 'exclude' => [ 'is_string', ], ]); $before = <<<'PHP' doTest($before); $this->fixer->configure([]); $this->doTest($after, $before); } /** * @dataProvider provideFixWithDefaultConfigurationCases */ public function testFixWithDefaultConfiguration(string $expected, ?string $input = null): void { $this->doTest($expected, $input); } public static function provideFixWithDefaultConfigurationCases(): iterable { yield [ ' [ 'fixer->configure([ 'exclude' => [ 'is_string', ], ]); $this->doTest($expected, $input); } public static function provideFixWithConfiguredExcludeCases(): iterable { yield [ 'fixer->configure(['scope' => $scope]); $this->doTest($expected, $input); } public static function provideFixWithNamespaceConfigurationCases(): iterable { yield [ ' ', ' ', ]; yield [ ' $configuration * * @dataProvider provideFixWithConfiguredIncludeCases */ public function testFixWithConfiguredInclude(string $expected, ?string $input = null, array $configuration = []): void { $this->fixer->configure($configuration); $this->doTest($expected, $input); } public static function provideFixWithConfiguredIncludeCases(): iterable { yield 'include set + 1, exclude 1' => [ ' [NativeFunctionInvocationFixer::SET_INTERNAL, 'some_other'], 'exclude' => ['strlen'], ], ]; yield 'include @all' => [ ' [NativeFunctionInvocationFixer::SET_ALL], ], ]; yield 'include @compiler_optimized' => [ ' [NativeFunctionInvocationFixer::SET_COMPILER_OPTIMIZED], ], ]; yield [ ' [ ' 'namespaced', 'strict' => true, ], ]; yield [ ' [NativeFunctionInvocationFixer::SET_ALL], ], ]; if (\PHP_VERSION_ID < 8_00_00) { yield 'include @compiler_optimized with strict enabled' => [ ' [NativeFunctionInvocationFixer::SET_COMPILER_OPTIMIZED], 'strict' => true, ], ]; } } /** * @requires PHP <8.0 */ public function testFixPrePHP80(): void { $this->doTest( ' $config * * @dataProvider provideFix80Cases * * @requires PHP 8.0 */ public function testFix80(string $expected, ?string $input = null, array $config = []): void { $this->fixer->configure($config); $this->doTest($expected, $input); } public static function provideFix80Cases(): iterable { yield 'attribute and strict' => [ ' true], ]; yield 'null safe operator' => ['count();']; yield 'multiple function-calls-like in attribute' => [ ' ['@all']], ]; } }