Skip to content

Commit

Permalink
Cranked PHPStan up to 11.
Browse files Browse the repository at this point in the history
  • Loading branch information
danbettles committed Sep 14, 2022
1 parent 43579a2 commit 21ac291
Show file tree
Hide file tree
Showing 20 changed files with 194 additions and 79 deletions.
3 changes: 2 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
parameters:
level: 5
level: max
checkGenericClassInNonGenericObjectType: false
paths:
- src
- tests
Expand Down
15 changes: 13 additions & 2 deletions src/AbstractTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ abstract class AbstractTestCase extends TestCase

private string $fixturesDir;

/**
* @phpstan-var class-string
*/
private string $testedClassName;

private ReflectionClass $testedClass;

// @phpstan-ignore-next-line
public function __construct(
?string $name = null,
array $data = [],
Expand All @@ -51,6 +55,7 @@ public function __construct(
$namespaceParts = explode($namespaceSeparator, self::$testsNamespace);
array_pop($namespaceParts);
$namespaceParts[] = preg_replace('~Test$~', '', $relativeClassName);
/** @phpstan-var class-string */
$testedClassName = implode($namespaceSeparator, $namespaceParts);

$this->setTestedClassName($testedClassName);
Expand All @@ -71,11 +76,17 @@ protected function createFixturePathname(string $basename): string
return $this->getFixturesDir() . DIRECTORY_SEPARATOR . $basename;
}

private function setTestedClassName(string $testedClassName): void
/**
* @phpstan-param class-string $className
*/
private function setTestedClassName(string $className): void
{
$this->testedClassName = $testedClassName;
$this->testedClassName = $className;
}

/**
* @phpstan-return class-string
*/
private function getTestedClassName(): string
{
return $this->testedClassName;
Expand Down
3 changes: 3 additions & 0 deletions src/Exception/FileTypeNotSupportedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

class FileTypeNotSupportedException extends RuntimeException
{
/**
* @param string[] $supportedTypes
*/
public function __construct(
string $unsupportedType,
array $supportedTypes = [],
Expand Down
7 changes: 6 additions & 1 deletion src/File/FileInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@

class FileInfo extends SplFileInfo
{
/** @var string */
/**
* @var string
*/
private const BASENAME_SEPARATOR = '.';

/**
* @return string[]
*/
public function getExtensions(): array
{
$parts = explode(self::BASENAME_SEPARATOR, $this->getBasename());
Expand Down
4 changes: 3 additions & 1 deletion src/HttpResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class HttpResponse
/** @var int */
public const HTTP_INTERNAL_SERVER_ERROR = 500;

/** @var array<int, string> */
/**
* @var array<int, string>
*/
private const STATUS_TEXTS = [
self::HTTP_OK => 'OK',
self::HTTP_NOT_FOUND => 'Not Found',
Expand Down
10 changes: 9 additions & 1 deletion src/OutputHelper/Html5OutputHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@

use const null;

/**
* @method string createEl(string $tagName, array<string, string|bool>|string $attributesOrContent, string|null $contentOrNothing = null)
*/
class Html5OutputHelper extends XmlOutputHelper
{
/**
* (Element) tag-names by (element) type.
*
* @var array
* @var array<string, array<int, string>>
*/
private const TAG_NAMES_BY_TYPE = [
'void' => [
Expand All @@ -43,6 +46,9 @@ class Html5OutputHelper extends XmlOutputHelper

private ReflectionMethod $createEl;

/**
* @param array<string, string|bool> $attributes
*/
public function createAttributes(array $attributes): string
{
if (!$attributes) {
Expand Down Expand Up @@ -102,6 +108,7 @@ protected function createElement(
}

/**
* @param mixed[] $arguments
* @throws BadMethodCallException If the called method does not exist.
*/
public function __call(string $methodName, array $arguments): string
Expand All @@ -117,6 +124,7 @@ public function __call(string $methodName, array $arguments): string
$tagName = strtolower($matches[1]);
array_unshift($arguments, $tagName);

/** @var string */
return $this->getCreateEl()->invokeArgs($this, $arguments);
}

Expand Down
18 changes: 15 additions & 3 deletions src/OutputHelper/XmlOutputHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ class XmlOutputHelper implements OutputHelperInterface
*/
public function escape(string $string): string
{
// PHPStan is wrong about this. According to the PHP manual, `string|null` *is* acceptable.
/** @phpstan-var string */
$encoding = $this->getEncoding();

return htmlspecialchars(
$string,
ENT_QUOTES | ENT_SUBSTITUTE | ENT_XML1,
$this->getEncoding(),
$encoding,
false
);
}
Expand All @@ -42,6 +46,9 @@ protected function createAttribute(string $name, string $value): string
return $name . '="' . $this->escape($value) . '"';
}

/**
* @param array<string, string> $attributes
*/
public function createAttributes(array $attributes): string
{
if (!$attributes) {
Expand All @@ -57,6 +64,9 @@ public function createAttributes(array $attributes): string
return implode(' ', $pairs);
}

/**
* @param array<string, string> $attributes
*/
protected function createElement(
string $tagName,
array $attributes,
Expand All @@ -76,7 +86,7 @@ protected function createElement(

/**
* @param string $tagName
* @param array|string|null $attributesOrContent
* @param array<string, string>|string|null $attributesOrContent
* @param string|null $contentOrNothing
* @throws InvalidArgumentException If the content is not a string/null.
*/
Expand All @@ -90,14 +100,16 @@ public function createEl(

if (!is_array($attributesOrContent)) {
$attributes = [];
/** @var mixed */
$content = $attributesOrContent;
}

// @phpstan-ignore-next-line
if (!is_string($content) && null !== $content) {
throw new InvalidArgumentException('The content is not a string/null.');
}

/** @var array $attributes */
/** @var string|null $content */
return $this->createElement($tagName, $attributes, $content);
}

Expand Down
15 changes: 7 additions & 8 deletions src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
class Router
{
/**
* @var array<int, array<string, mixed>>
* @var array<int, array{path: string, action: mixed}>
*/
private array $routes;

/**
* @param array<int, array<string, mixed>> $routes
* @param array<int, array{path: string, action: mixed}> $routes
*/
public function __construct(array $routes)
{
Expand All @@ -56,15 +56,14 @@ private function countPathParts(string $path): int
}

/**
* @param array<int, array<string, mixed>> $routes
* @return array<int, array<string, mixed>>
* @param array<int, array{path: string, action: mixed}> $routes
* @return array<int, array{path: string, action: mixed}>
*/
private function eliminateUnmatchableRoutes(string $path, array $routes): array
{
$numPathParts = $this->countPathParts($path);

$filteredRoutes = array_filter($routes, function (array $route) use ($numPathParts): bool {
/** @var array<string, mixed> $route */
return $numPathParts === $this->countPathParts($route['path']);
});

Expand All @@ -81,7 +80,7 @@ private function createPathRegExpFromRoutePath(string $routePath): string

/**
* @param array<string, string> $serverVars
* @return array<string, mixed>|null
* @return array{path: string, action: mixed, parameters: string[]}|null
* @throws InvalidArgumentException If the request URI is invalid.
*/
public function match(array $serverVars): ?array
Expand Down Expand Up @@ -142,7 +141,7 @@ public function match(array $serverVars): ?array
}

/**
* @param array<int, array<string, mixed>> $routes
* @param array<int, array{path: string, action: mixed}> $routes
*/
private function setRoutes(array $routes): self
{
Expand All @@ -151,7 +150,7 @@ private function setRoutes(array $routes): self
}

/**
* @return array<int, array<string, mixed>>
* @return array<int, array{path: string, action: mixed}>
*/
public function getRoutes(): array
{
Expand Down
15 changes: 15 additions & 0 deletions src/ServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,19 @@

class ServiceFactory
{
/**
* @var array<string, class-string|Closure>
*/
private array $config;

/**
* @var array<string, object>
*/
private array $services = [];

/**
* @param array<string, class-string|Closure> $config
*/
public function __construct(array $config)
{
$this->setConfig($config);
Expand Down Expand Up @@ -77,12 +86,18 @@ public function get(string $id): object
return $this->services[$id];
}

/**
* @param array<string, class-string|Closure> $config
*/
private function setConfig(array $config): self
{
$this->config = $config;
return $this;
}

/**
* @return array<string, class-string|Closure> $config
*/
public function getConfig(): array
{
return $this->config;
Expand Down
4 changes: 3 additions & 1 deletion src/TemplateEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

class TemplateEngine
{
/** @var string[] */
/**
* @var string[]
*/
private const VALID_FILE_EXTENSIONS = [
'php',
'phtml',
Expand Down
3 changes: 3 additions & 0 deletions src/TemplateFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ private function setTemplateDirs(array $dirs): self
return $this;
}

/**
* @return string[]
*/
public function getTemplateDirs(): array
{
return $this->templateDirs;
Expand Down
10 changes: 5 additions & 5 deletions tests/src/AbstractTestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@

class AbstractTestCaseTest extends AbstractTestCase
{
public function testIsAbstract()
public function testIsAbstract(): void
{
$class = new ReflectionClass(AbstractTestCase::class);

$this->assertTrue($class->isAbstract());
}

public function testIsAPhpunitTestcase()
public function testIsAPhpunitTestcase(): void
{
$this->assertTrue(is_subclass_of(AbstractTestCase::class, TestCase::class));
}

public function testGetfixturesdir()
public function testGetfixturesdir(): void
{
$self = new ReflectionClass(__CLASS__);

Expand All @@ -36,7 +36,7 @@ public function testGetfixturesdir()
);
}

public function testCreatefixturepathname()
public function testCreatefixturepathname(): void
{
$self = new ReflectionClass(__CLASS__);

Expand All @@ -46,7 +46,7 @@ public function testCreatefixturepathname()
);
}

public function testGettestedclass()
public function testGettestedclass(): void
{
$testedClass = $this->getTestedClass();

Expand Down
6 changes: 3 additions & 3 deletions tests/src/Exception/FileTypeNotSupportedExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@

class FileTypeNotSupportedExceptionTest extends AbstractTestCase
{
public function testIsARuntimeexception()
public function testIsARuntimeexception(): void
{
$this->assertTrue($this->getTestedClass()->isSubclassOf(RuntimeException::class));
}

public function testCanBeThrownWithOnlyTheNameOfTheInvalidFileType()
public function testCanBeThrownWithOnlyTheNameOfTheInvalidFileType(): void
{
$this->expectException(FileTypeNotSupportedException::class);
$this->expectExceptionMessage("The file-type `foo` is not supported.");

throw new FileTypeNotSupportedException('foo');
}

public function testCanBeThrownWithAListOfSupportedTypes()
public function testCanBeThrownWithAListOfSupportedTypes(): void
{
$this->expectException(FileTypeNotSupportedException::class);
$this->expectExceptionMessage('The file-type `foo` is not supported. Supported types: bar; baz');
Expand Down
Loading

0 comments on commit 21ac291

Please sign in to comment.