From a58e5ca31f9fff0e26454a14391c0e6f8411f27a Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 14 Dec 2024 10:33:34 +0100 Subject: [PATCH 1/6] Fix PHPStan level 7 errors --- src/Event/Emitter/Emitter.php | 3 --- .../MockObject/Generator/HookedPropertyGenerator.php | 2 -- src/Framework/TestBuilder.php | 2 +- src/Framework/TestCase.php | 2 ++ src/Logging/EventLogger.php | 2 +- src/Logging/JUnit/JunitXmlLogger.php | 4 ++-- src/Metadata/Api/Requirements.php | 2 +- src/Metadata/CoversClassesThatExtendClass.php | 1 + src/Metadata/Version/Requirement.php | 6 ++---- 9 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Event/Emitter/Emitter.php b/src/Event/Emitter/Emitter.php index 9204ac98534..ec34561de12 100644 --- a/src/Event/Emitter/Emitter.php +++ b/src/Event/Emitter/Emitter.php @@ -145,9 +145,6 @@ public function testConsideredRisky(Code\Test $test, string $message): void; public function testMarkedAsIncomplete(Code\Test $test, Throwable $throwable): void; - /** - * @param non-empty-string $message - */ public function testSkipped(Code\Test $test, string $message): void; /** diff --git a/src/Framework/MockObject/Generator/HookedPropertyGenerator.php b/src/Framework/MockObject/Generator/HookedPropertyGenerator.php index 8da519e4990..4fcff6c824d 100644 --- a/src/Framework/MockObject/Generator/HookedPropertyGenerator.php +++ b/src/Framework/MockObject/Generator/HookedPropertyGenerator.php @@ -21,8 +21,6 @@ final class HookedPropertyGenerator /** * @param class-string $className * @param list $properties - * - * @return non-empty-string */ public function generate(string $className, array $properties): string { diff --git a/src/Framework/TestBuilder.php b/src/Framework/TestBuilder.php index 5c3effc7a35..dba8e6096e9 100644 --- a/src/Framework/TestBuilder.php +++ b/src/Framework/TestBuilder.php @@ -76,7 +76,7 @@ public function build(ReflectionClass $theClass, string $methodName, array $grou /** * @param non-empty-string $methodName * @param class-string $className - * @param array> $data + * @param array> $data * @param array{backupGlobals: ?bool, backupGlobalsExcludeList: list, backupStaticProperties: ?bool, backupStaticPropertiesExcludeList: array>} $backupSettings * @param list $groups */ diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 43305f7c137..dffa70cb479 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -389,6 +389,8 @@ final public function size(): TestSize /** * @internal This method is not covered by the backward compatibility promise for PHPUnit + * + * @phpstan-assert-if-true non-empty-string $this->output() */ final public function hasUnexpectedOutput(): bool { diff --git a/src/Logging/EventLogger.php b/src/Logging/EventLogger.php index e7f029af914..ab3a30c2fed 100644 --- a/src/Logging/EventLogger.php +++ b/src/Logging/EventLogger.php @@ -41,7 +41,7 @@ public function trace(Event $event): void { $telemetryInfo = $this->telemetryInfo($event); $indentation = PHP_EOL . str_repeat(' ', strlen($telemetryInfo)); - $lines = preg_split('/\r\n|\r|\n/', $event->asString()); + $lines = preg_split('/\r\n|\r|\n/', $event->asString()) ?: []; $flags = FILE_APPEND; diff --git a/src/Logging/JUnit/JunitXmlLogger.php b/src/Logging/JUnit/JunitXmlLogger.php index 2eae77ac6de..262872a7ea1 100644 --- a/src/Logging/JUnit/JunitXmlLogger.php +++ b/src/Logging/JUnit/JunitXmlLogger.php @@ -102,7 +102,7 @@ public function __construct(Printer $printer, Facade $facade) public function flush(): void { - $this->printer->print($this->document->saveXML()); + $this->printer->print($this->document->saveXML() ?: ''); $this->printer->flush(); } @@ -269,7 +269,7 @@ private function handleFinish(Info $telemetryInfo, int $numberOfAssertionsPerfor ); $this->testSuiteTests[$this->testSuiteLevel]++; - $this->testSuiteTimes[$this->testSuiteLevel] += $time; + $this->testSuiteTimes[$this->testSuiteLevel] += (int) $time; $this->currentTestCase = null; $this->time = null; diff --git a/src/Metadata/Api/Requirements.php b/src/Metadata/Api/Requirements.php index b29c45f0b99..32ec095cd99 100644 --- a/src/Metadata/Api/Requirements.php +++ b/src/Metadata/Api/Requirements.php @@ -72,7 +72,7 @@ public function requirementsNotSatisfiedFor(string $className, string $methodNam if (!extension_loaded($metadata->extension()) || ($metadata->hasVersionRequirement() && - !$metadata->versionRequirement()->isSatisfiedBy(phpversion($metadata->extension())))) { + !$metadata->versionRequirement()->isSatisfiedBy(phpversion($metadata->extension()) ?: ''))) { $notSatisfied[] = sprintf( 'PHP extension %s%s is required.', $metadata->extension(), diff --git a/src/Metadata/CoversClassesThatExtendClass.php b/src/Metadata/CoversClassesThatExtendClass.php index 383a745d312..8171e00b639 100644 --- a/src/Metadata/CoversClassesThatExtendClass.php +++ b/src/Metadata/CoversClassesThatExtendClass.php @@ -23,6 +23,7 @@ /** * @param int<0, 1> $level + * @param class-string $className */ protected function __construct(int $level, string $className) { diff --git a/src/Metadata/Version/Requirement.php b/src/Metadata/Version/Requirement.php index 5457f5a8a64..2d532174726 100644 --- a/src/Metadata/Version/Requirement.php +++ b/src/Metadata/Version/Requirement.php @@ -23,7 +23,7 @@ */ abstract readonly class Requirement { - private const string VERSION_COMPARISON = '/(?P[<>=!]{0,2})\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; + private const string VERSION_COMPARISON = "/(?P!=|<|<=|<>|=|==|>|>=)\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m"; /** * @throws InvalidVersionOperatorException @@ -41,9 +41,7 @@ public static function from(string $versionRequirement): self if (preg_match(self::VERSION_COMPARISON, $versionRequirement, $matches)) { return new ComparisonRequirement( $matches['version'], - new VersionComparisonOperator( - !empty($matches['operator']) ? $matches['operator'] : '>=', - ), + new VersionComparisonOperator($matches['operator']), ); } } From d40f564263383d28c9a055b1253e6a221dde4d8d Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 14 Dec 2024 10:51:57 +0100 Subject: [PATCH 2/6] Allow empty operator again --- src/Metadata/Version/Requirement.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Metadata/Version/Requirement.php b/src/Metadata/Version/Requirement.php index 2d532174726..6a18beb9887 100644 --- a/src/Metadata/Version/Requirement.php +++ b/src/Metadata/Version/Requirement.php @@ -23,7 +23,7 @@ */ abstract readonly class Requirement { - private const string VERSION_COMPARISON = "/(?P!=|<|<=|<>|=|==|>|>=)\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m"; + private const string VERSION_COMPARISON = "/(?P!=|<|<=|<>|=|==|>|>=)?\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m"; /** * @throws InvalidVersionOperatorException @@ -41,7 +41,9 @@ public static function from(string $versionRequirement): self if (preg_match(self::VERSION_COMPARISON, $versionRequirement, $matches)) { return new ComparisonRequirement( $matches['version'], - new VersionComparisonOperator($matches['operator']), + new VersionComparisonOperator( + !empty($matches['operator']) ? $matches['operator'] : '>=', + ), ); } } From 69e00180697e88ea151ed0503326f633c2bf0544 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 14 Dec 2024 11:00:38 +0100 Subject: [PATCH 3/6] baseline is non-empty-string --- src/TextUI/Configuration/Configuration.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/TextUI/Configuration/Configuration.php b/src/TextUI/Configuration/Configuration.php index 061e0581098..83d2e49bd0a 100644 --- a/src/TextUI/Configuration/Configuration.php +++ b/src/TextUI/Configuration/Configuration.php @@ -161,6 +161,10 @@ private Php $php; private bool $controlGarbageCollector; private int $numberOfTestsBeforeGarbageCollection; + + /** + * @var null|non-empty-string + */ private ?string $generateBaseline; private bool $debug; @@ -179,9 +183,10 @@ * @param list $groups * @param list $excludeGroups * @param non-empty-list $testSuffixes + * @param null|non-empty-string $generateBaseline * @param non-negative-int $shortenArraysForExportThreshold */ - public function __construct(array $cliArguments, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, ?string $specificDeprecationToStopOn, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, bool $outputToStandardErrorStream, int|string $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, bool $testDoxOutputSummary, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, ?string $filter, ?string $excludeFilter, array $groups, array $excludeGroups, int $randomOrderSeed, TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug, int $shortenArraysForExportThreshold) + public function __construct(array $cliArguments, ?string $configurationFile, ?string $bootstrap, bool $cacheResult, ?string $cacheDirectory, ?string $coverageCacheDirectory, Source $source, string $testResultCacheFile, ?string $coverageClover, ?string $coverageCobertura, ?string $coverageCrap4j, int $coverageCrap4jThreshold, ?string $coverageHtml, int $coverageHtmlLowUpperBound, int $coverageHtmlHighLowerBound, string $coverageHtmlColorSuccessLow, string $coverageHtmlColorSuccessMedium, string $coverageHtmlColorSuccessHigh, string $coverageHtmlColorWarning, string $coverageHtmlColorDanger, ?string $coverageHtmlCustomCssFile, ?string $coveragePhp, ?string $coverageText, bool $coverageTextShowUncoveredFiles, bool $coverageTextShowOnlySummary, ?string $coverageXml, bool $pathCoverage, bool $ignoreDeprecatedCodeUnitsFromCodeCoverage, bool $disableCodeCoverageIgnore, bool $failOnDeprecation, bool $failOnPhpunitDeprecation, bool $failOnEmptyTestSuite, bool $failOnIncomplete, bool $failOnNotice, bool $failOnRisky, bool $failOnSkipped, bool $failOnWarning, bool $stopOnDefect, bool $stopOnDeprecation, ?string $specificDeprecationToStopOn, bool $stopOnError, bool $stopOnFailure, bool $stopOnIncomplete, bool $stopOnNotice, bool $stopOnRisky, bool $stopOnSkipped, bool $stopOnWarning, bool $outputToStandardErrorStream, int $columns, bool $noExtensions, ?string $pharExtensionDirectory, array $extensionBootstrappers, bool $backupGlobals, bool $backupStaticProperties, bool $beStrictAboutChangesToGlobalState, bool $colors, bool $processIsolation, bool $enforceTimeLimit, int $defaultTimeLimit, int $timeoutForSmallTests, int $timeoutForMediumTests, int $timeoutForLargeTests, bool $reportUselessTests, bool $strictCoverage, bool $disallowTestOutput, bool $displayDetailsOnIncompleteTests, bool $displayDetailsOnSkippedTests, bool $displayDetailsOnTestsThatTriggerDeprecations, bool $displayDetailsOnPhpunitDeprecations, bool $displayDetailsOnTestsThatTriggerErrors, bool $displayDetailsOnTestsThatTriggerNotices, bool $displayDetailsOnTestsThatTriggerWarnings, bool $reverseDefectList, bool $requireCoverageMetadata, bool $noProgress, bool $noResults, bool $noOutput, int $executionOrder, int $executionOrderDefects, bool $resolveDependencies, ?string $logfileTeamcity, ?string $logfileJunit, ?string $logfileTestdoxHtml, ?string $logfileTestdoxText, ?string $logEventsText, ?string $logEventsVerboseText, bool $teamCityOutput, bool $testDoxOutput, bool $testDoxOutputSummary, ?array $testsCovering, ?array $testsUsing, ?array $testsRequiringPhpExtension, ?string $filter, ?string $excludeFilter, array $groups, array $excludeGroups, int $randomOrderSeed, TestSuiteCollection $testSuite, string $includeTestSuite, string $excludeTestSuite, ?string $defaultTestSuite, array $testSuffixes, Php $php, bool $controlGarbageCollector, int $numberOfTestsBeforeGarbageCollection, ?string $generateBaseline, bool $debug, int $shortenArraysForExportThreshold) { $this->cliArguments = $cliArguments; $this->configurationFile = $configurationFile; @@ -1288,6 +1293,8 @@ public function hasGenerateBaseline(): bool /** * @throws NoBaselineException + * + * @return non-empty-string */ public function generateBaseline(): string { From d057aee2fe603c8f8bba5d3bab34c62b975ac496 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 14 Dec 2024 11:00:43 +0100 Subject: [PATCH 4/6] Fix types --- src/Runner/TestSuiteSorter.php | 4 ++-- src/TextUI/Output/TestDox/ResultPrinter.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Runner/TestSuiteSorter.php b/src/Runner/TestSuiteSorter.php index a0ed43f13ba..2aab5b1c394 100644 --- a/src/Runner/TestSuiteSorter.php +++ b/src/Runner/TestSuiteSorter.php @@ -315,9 +315,9 @@ private function cmpSize(Test $a, Test $b): int * 3. If the test has dependencies but none left to do: mark done, start again from the top * 4. When we reach the end add any leftover tests to the end. These will be marked 'skipped' during execution. * - * @param array $tests + * @param array $tests * - * @return array + * @return array */ private function resolveDependencies(array $tests): array { diff --git a/src/TextUI/Output/TestDox/ResultPrinter.php b/src/TextUI/Output/TestDox/ResultPrinter.php index 394a3fa0fdc..f0a7af9ae32 100644 --- a/src/TextUI/Output/TestDox/ResultPrinter.php +++ b/src/TextUI/Output/TestDox/ResultPrinter.php @@ -306,7 +306,7 @@ private function prefixLines(string $prefix, string $message): string PHP_EOL, array_map( static fn (string $line) => ' ' . $prefix . ($line ? ' ' . $line : ''), - preg_split('/\r\n|\r|\n/', $message), + preg_split('/\r\n|\r|\n/', $message) ?: [], ), ); } From cd010525d1eb47a917193cbff2d1efa905a9b627 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 14 Dec 2024 11:18:58 +0100 Subject: [PATCH 5/6] arguments are not a list when named args given --- src/Framework/MockObject/Generator/Generator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Framework/MockObject/Generator/Generator.php b/src/Framework/MockObject/Generator/Generator.php index 74163f921f1..334279f2e0e 100644 --- a/src/Framework/MockObject/Generator/Generator.php +++ b/src/Framework/MockObject/Generator/Generator.php @@ -89,7 +89,7 @@ final class Generator * * @param class-string $type * @param ?list $methods - * @param list $arguments + * @param array $arguments * * @throws ClassIsEnumerationException * @throws ClassIsFinalException From d196deed62b9eaeeea71c38c245be3f32de65d3b Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 23 Dec 2024 20:14:56 +0100 Subject: [PATCH 6/6] Fix cs --- src/Metadata/CoversClassesThatExtendClass.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Metadata/CoversClassesThatExtendClass.php b/src/Metadata/CoversClassesThatExtendClass.php index 8171e00b639..7feb40d7098 100644 --- a/src/Metadata/CoversClassesThatExtendClass.php +++ b/src/Metadata/CoversClassesThatExtendClass.php @@ -22,7 +22,7 @@ private string $className; /** - * @param int<0, 1> $level + * @param int<0, 1> $level * @param class-string $className */ protected function __construct(int $level, string $className)