diff --git a/composer.json b/composer.json index 14771e8..4b4513b 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "require": { "php": "^7.4 || ^8.0", "phpstan/phpstan": "^2.0", - "thecodingmachine/safe": "^1.0 || ^2.0" + "thecodingmachine/safe": "^1.0 || ^2.0", + "nikic/php-parser": "^5" }, "require-dev": { "phpunit/phpunit": "^9.6", diff --git a/phpstan.neon b/phpstan.neon index 46b5aa0..f4ecada 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,9 @@ parameters: level: max paths: - src + - tests + excludePaths: + - tests/Rules/data ignoreErrors: - message: '#^Implementing PHPStan\\Rules\\IdentifierRuleError is not covered by backward compatibility promise\. The interface might change in a minor PHPStan version\.$#' diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ac73057..7b1dd06 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ ./src + + src/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtension.php + diff --git a/src/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtension.php b/src/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtension.php index 02711e1..ca7ba4f 100644 --- a/src/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtension.php +++ b/src/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtension.php @@ -20,7 +20,7 @@ class ReplaceSafeFunctionsDynamicReturnTypeExtension implements DynamicFunctionR { /** @var array */ - private $functions = [ + private array $functions = [ 'Safe\preg_replace' => 2, ]; diff --git a/tests/Rules/CallMethodRuleTest.php b/tests/Rules/CallMethodRuleTest.php deleted file mode 100644 index 4b8e362..0000000 --- a/tests/Rules/CallMethodRuleTest.php +++ /dev/null @@ -1,43 +0,0 @@ -createReflectionProvider(); - $ruleLevelHelper = new RuleLevelHelper($reflectionProvider, true, true, true, false); - return new CallMethodsRule( - new MethodCallCheck($reflectionProvider, $ruleLevelHelper, true, true), - new FunctionCallParametersCheck($ruleLevelHelper, new NullsafeCheck(), new PhpVersion(PHP_VERSION_ID), new UnresolvableTypeHelper(), true, false, false, false) - ); - } - - public function testSafePregReplace() - { - // FIXME: this rule actually runs code but will always return no error because the rule executed is not the correct one. - // This provides code coverage but assert is not ok. - $this->analyse([__DIR__ . '/data/safe_pregreplace.php'], []); - } - - - /** - * @return \PHPStan\Type\DynamicFunctionReturnTypeExtension[] - */ - public function getDynamicFunctionReturnTypeExtensions(): array - { - return [new ReplaceSafeFunctionsDynamicReturnTypeExtension()]; - } -} diff --git a/tests/Rules/UseSafeClassesRuleTest.php b/tests/Rules/UseSafeClassesRuleTest.php index b3258be..bfa8aaf 100644 --- a/tests/Rules/UseSafeClassesRuleTest.php +++ b/tests/Rules/UseSafeClassesRuleTest.php @@ -2,17 +2,20 @@ namespace TheCodingMachine\Safe\PHPStan\Rules; +use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -use TheCodingMachine\Safe\PHPStan\Type\Php\ReplaceSafeFunctionsDynamicReturnTypeExtension; +/** + * @template-extends RuleTestCase + */ class UseSafeClassesRuleTest extends RuleTestCase { - protected function getRule(): \PHPStan\Rules\Rule + protected function getRule(): Rule { return new UseSafeClassesRule(); } - public function testDateTime() + public function testDateTime(): void { $this->analyse([__DIR__ . '/data/datetime.php'], [ [ diff --git a/tests/Rules/UseSafeFunctionsRuleTest.php b/tests/Rules/UseSafeFunctionsRuleTest.php index 4014828..55ba182 100644 --- a/tests/Rules/UseSafeFunctionsRuleTest.php +++ b/tests/Rules/UseSafeFunctionsRuleTest.php @@ -2,17 +2,20 @@ namespace TheCodingMachine\Safe\PHPStan\Rules; +use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; -use TheCodingMachine\Safe\PHPStan\Type\Php\ReplaceSafeFunctionsDynamicReturnTypeExtension; +/** + * @template-extends RuleTestCase + */ class UseSafeFunctionsRuleTest extends RuleTestCase { - protected function getRule(): \PHPStan\Rules\Rule + protected function getRule(): Rule { return new UseSafeFunctionsRule(); } - public function testCatch() + public function testCatch(): void { $this->analyse([__DIR__ . '/data/fopen.php'], [ [ @@ -22,31 +25,23 @@ public function testCatch() ]); } - public function testNoCatchSafe() + public function testNoCatchSafe(): void { $this->analyse([__DIR__ . '/data/safe_fopen.php'], []); } - public function testExprCall() + public function testExprCall(): void { $this->analyse([__DIR__ . '/data/undirect_call.php'], []); } - public function testJSONDecodeNoCatchSafe() + public function testJSONDecodeNoCatchSafe(): void { - if (version_compare(PHP_VERSION, '7.3.0', '>=')) { - $this->analyse([__DIR__ . '/data/safe_json_decode_for_7.3.0.php'], []); - } else { - $this->assertTrue(true); - } + $this->analyse([__DIR__ . '/data/safe_json_decode_for_7.3.0.php'], []); } - public function testJSONEncodeNoCatchSafe() + public function testJSONEncodeNoCatchSafe(): void { - if (version_compare(PHP_VERSION, '7.3.0', '>=')) { - $this->analyse([__DIR__ . '/data/safe_json_encode_for_7.3.0.php'], []); - } else { - $this->assertTrue(true); - } + $this->analyse([__DIR__ . '/data/safe_json_encode_for_7.3.0.php'], []); } } diff --git a/tests/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtensionTest.php b/tests/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtensionTest.php new file mode 100644 index 0000000..3ebce33 --- /dev/null +++ b/tests/Type/Php/ReplaceSafeFunctionsDynamicReturnTypeExtensionTest.php @@ -0,0 +1,22 @@ +assertStringNotContainsString('foo', $x); + } + + public function testWithArrays(): void + { + $x = \Safe\preg_replace(['/foo/'], ['bar'], ['baz']); + + $this->assertNotContains('foo', $x); + } +} diff --git a/tests/Utils/FunctionListLoaderTest.php b/tests/Utils/FunctionListLoaderTest.php index 0234608..c5c7c50 100644 --- a/tests/Utils/FunctionListLoaderTest.php +++ b/tests/Utils/FunctionListLoaderTest.php @@ -6,10 +6,10 @@ class FunctionListLoaderTest extends TestCase { - - public function testGetFunctionList() + public function testGetFunctionList(): void { $functions = FunctionListLoader::getFunctionList(); $this->assertArrayHasKey('fopen', $functions); + $this->assertEquals('fopen', $functions['fopen']); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index ea60222..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,33 +0,0 @@ -defaultExtensions = []; -$configurator->setDebugMode(true); -$configurator->setTempDirectory($tmpDir); -$configurator->addConfig($confDir . '/config.neon'); -$configurator->addConfig($confDir . '/config.level5.neon'); -$configurator->addParameters([ - 'rootDir' => $rootDir, - 'tmpDir' => $tmpDir, - 'currentWorkingDirectory' => $rootDir, - 'cliArgumentsVariablesRegistered' => false, -]); -$container = $configurator->createContainer(); - -PHPStan\Testing\TestCase::setContainer($container); -PHPStan\Type\TypeCombinator::setUnionTypesEnabled(true); -require_once __DIR__ . '/phpstan-bootstrap.php'; -*/ diff --git a/tests/phpstan-bootstrap.php b/tests/phpstan-bootstrap.php deleted file mode 100644 index c39b13a..0000000 --- a/tests/phpstan-bootstrap.php +++ /dev/null @@ -1,4 +0,0 @@ -