diff --git a/composer.json b/composer.json index ec787f5..5f8208b 100755 --- a/composer.json +++ b/composer.json @@ -9,16 +9,12 @@ "email": "github@muglug.com" } ], - "config": { - "optimize-autoloader": true, - "sort-packages": true - }, "require": { "php": "^7.1 || ^8.0", "ext-simplexml": "*", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/package-versions-deprecated": "^1.10", - "vimeo/psalm": "dev-master || dev-4.x || ^4.5 || ^5@beta" + "vimeo/psalm": "dev-master || dev-4.x || ^4.7.1 || ^5@beta || ^5.0" }, "conflict": { "phpunit/phpunit": "<7.5" @@ -56,5 +52,12 @@ "cs-check": "phpcs", "cs-fix": "phpcbf", "test": "codecept run -v" + }, + "config": { + "optimize-autoloader": true, + "sort-packages": true, + "allow-plugins": { + "composer/package-versions-deprecated": true + } } } diff --git a/psalm.xml.dist b/psalm.xml.dist index b64f292..04e0d03 100755 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -11,7 +11,7 @@ - + diff --git a/src/Hooks/TestCaseHandler.php b/src/Hooks/TestCaseHandler.php index e58a902..caf1315 100644 --- a/src/Hooks/TestCaseHandler.php +++ b/src/Hooks/TestCaseHandler.php @@ -169,10 +169,15 @@ public static function afterStatementAnalysis(AfterClassLikeAnalysisEvent $event foreach ($specials['dataProvider'] as $line => $provider) { try { + // for older Psalm versions + /** + * @psalm-suppress InvalidClone + * @var CodeLocation + */ $provider_docblock_location = clone $method_storage->location; + /** @psalm-suppress UnusedMethodCall */ $provider_docblock_location->setCommentLine($line); } catch (Error $e) { - /** @var CodeLocation */ $provider_docblock_location = $method_storage->location->setCommentLine($line); } @@ -338,11 +343,18 @@ static function ( $provider_docblock_location ): void { if ($is_optional) { + /** @psalm-suppress RedundantCondition */ if (method_exists($param_type, 'setPossiblyUndefined')) { /** @var Union */ $param_type = $param_type->setPossiblyUndefined(true); } else { + // for older Psalm versions + /** + * @psalm-suppress InvalidClone + * @var Union + */ $param_type = clone $param_type; + /** @psalm-suppress InaccessibleProperty */ $param_type->possibly_undefined = true; } } diff --git a/tests/acceptance/Prophecy.feature b/tests/acceptance/Prophecy.feature index 2841760..386ecfe 100644 --- a/tests/acceptance/Prophecy.feature +++ b/tests/acceptance/Prophecy.feature @@ -74,7 +74,7 @@ Feature: Prophecy When I run Psalm Then I see no errors - Scenario: Argument::that() only accepts callable with boolean return type + Scenario: Argument::that() only accepts callable with boolean return type [Psalm 4] Given I have the following code """ class MyTestCase extends TestCase @@ -87,12 +87,34 @@ Feature: Prophecy } } """ + And I have Psalm older than "5.0" (because of "changed issue type") When I run Psalm Then I see these errors - | Type | Message | - | InvalidScalarArgument | /Argument 1 of Prophecy\\Argument::that expects callable\(mixed...\):bool, (pure-)?Closure\(\):(string\(hello\)\|"hello") provided/ | + | Type | Message | + | InvalidScalarArgument | /Argument 1 of Prophecy\\Argument::that expects callable\(mixed...\):bool, (but )?(pure-)?Closure\(\):(string\(hello\)\|"hello"\|'hello') provided/ | And I see no other errors + Scenario: Argument::that() only accepts callable with boolean return type [Psalm 5] + Given I have the following code + """ + class MyTestCase extends TestCase + { + /** @return void */ + public function testSomething() { + $_argument = Argument::that(function (): string { + return 'hello'; + }); + } + } + """ + And I have Psalm newer than "4.99" (because of "changed issue type") + When I run Psalm + Then I see these errors + | Type | Message | + | InvalidArgument | /Argument 1 of Prophecy\\Argument::that expects callable\(mixed...\):bool, (but )?(pure-)?Closure\(\):(string\(hello\)\|"hello"\|'hello') provided/ | + And I see no other errors + + Scenario: prophesize() provided by ProphecyTrait is generic Given I have the following code """ diff --git a/tests/acceptance/TestCase.feature b/tests/acceptance/TestCase.feature index 1f546a1..744ff6f 100644 --- a/tests/acceptance/TestCase.feature +++ b/tests/acceptance/TestCase.feature @@ -15,6 +15,13 @@ Feature: TestCase + + + + + + + """ And I have the following code preamble @@ -38,8 +45,8 @@ Feature: TestCase """ When I run Psalm Then I see these errors - | Type | Message | - | InvalidArgument | Argument 1 of NS\MyTestCase::expectException expects class-string, NS\MyTestCase::class provided | + | Type | Message | + | InvalidArgument | /Argument 1 of NS\\MyTestCase::expectException expects class-string, (but )?NS\\MyTestCase::class provided/ | And I see no other errors Scenario: TestCase::expectException() accepts throwables @@ -421,8 +428,8 @@ Feature: TestCase """ When I run Psalm Then I see these errors - | Type | Message | - | InvalidArgument | /Argument 1 of NS\\MyTestCase::testSomething expects int, string provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | + | Type | Message | + | InvalidArgument | /Argument 1 of NS\\MyTestCase::testSomething expects int, string provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | And I see no other errors Scenario: Invalid dataset array is reported @@ -469,8 +476,8 @@ Feature: TestCase """ When I run Psalm Then I see these errors - | Type | Message | - | TooFewArguments | /Too few arguments for NS\\MyTestCase::testSomething - expecting at least 2, but saw 1 provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | + | Type | Message | + | TooFewArguments | /Too few arguments for NS\\MyTestCase::testSomething - expecting at least 2, but saw 1 provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | And I see no other errors Scenario: Referenced providers are not marked as unused @@ -605,7 +612,7 @@ Feature: TestCase When I run Psalm Then I see no errors - Scenario: Provider omitting offsets is fine when test method has defaults for those params (specified as constants) + Scenario: Provider omitting offsets is fine when test method has defaults for those params (specified as constants) [Psalm 4] Given I have the following code """ class MyTestCase extends TestCase @@ -625,6 +632,31 @@ Feature: TestCase } } """ + And I have Psalm older than "5.0" (because of "sealed shapes") + When I run Psalm + Then I see no errors + + Scenario: Provider omitting offsets is fine when test method has defaults for those params (specified as constants) [Psalm 5] + Given I have the following code + """ + class MyTestCase extends TestCase + { + /** @var string */ + const S = "s"; + /** @return iterable */ + public function provide() { + yield "data set name" => rand(0,1) ? [1] : [1, "ss"]; + } + /** + * @return void + * @dataProvider provide + */ + public function testSomething(int $int, string $_str = self::S) { + $this->assertEquals(1, $int); + } + } + """ + And I have Psalm newer than "4.99" (because of "sealed shapes") When I run Psalm Then I see no errors @@ -960,8 +992,8 @@ Feature: TestCase """ When I run Psalm Then I see these errors - | Type | Message | - | TooFewArguments | /Too few arguments for NS\\MyTestCase::testSomething - expecting at least 2, but saw 1 provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | + | Type | Message | + | TooFewArguments | /Too few arguments for NS\\MyTestCase::testSomething - expecting at least 2, but saw 1 provided by NS\\MyTestCase::provide\(\):\(iterable\)/ | And I see no other errors Scenario: Providers generating incompatible datasets for variadic tests are reported