More phpstan checks for better code

This commit is contained in:
Jaapio
2026-01-01 22:36:45 +01:00
parent f08359470f
commit 3f6d648d7d
26 changed files with 154 additions and 92 deletions
+4 -1
View File
@@ -10,7 +10,10 @@ use phpDocumentor\Reflection\FqsenResolver;
final class CustomParam implements Tag
{
/** @var string|null */
public $myParam;
/** @var FqsenResolver|null */
public $fqsenResolver;
public function getName() : string
@@ -18,7 +21,7 @@ final class CustomParam implements Tag
return 'spy';
}
public static function create($body, FqsenResolver $fqsenResolver = null, ?string $myParam = null)
public static function create(string $body, FqsenResolver $fqsenResolver = null, ?string $myParam = null)
{
$tag = new self();
$tag->fqsenResolver = $fqsenResolver;
+2 -3
View File
@@ -7,11 +7,10 @@ namespace phpDocumentor\Reflection\Assets;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod;
final class CustomServiceClass implements Tag
{
/** @var Formatter|null */
public $formatter;
public function getName() : string
@@ -19,7 +18,7 @@ final class CustomServiceClass implements Tag
return 'spy';
}
public static function create($body, PassthroughFormatter $formatter = null)
public static function create(string $body, PassthroughFormatter $formatter = null)
{
$tag = new self();
$tag->formatter = $formatter;
+2 -1
View File
@@ -11,6 +11,7 @@ use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod;
final class CustomServiceInterface implements Tag
{
/** @var Formatter|null */
public $formatter;
public function getName() : string
@@ -18,7 +19,7 @@ final class CustomServiceInterface implements Tag
return 'spy';
}
public static function create($body, Formatter $formatter = null)
public static function create(string $body, Formatter $formatter = null)
{
$tag = new self();
$tag->formatter = $formatter;
+1
View File
@@ -20,6 +20,7 @@ use phpDocumentor\Reflection\Types\Context;
class CustomTagFactory implements Factory
{
/** @var CustomServiceClass|null */
public $class;
public function create(string $tagLine, ?Context $context = null, CustomServiceClass $class = null): Tag
@@ -13,7 +13,6 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock;
use Exception;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag;
@@ -216,7 +215,7 @@ DESCRIPTION;
$tagFactory->shouldReceive('create')
->once()
->with('@see $name', $context)
->andReturn(InvalidTag::create('$name', 'see', new Exception()));
->andReturn(InvalidTag::create('$name', 'see'));
$factory = new DescriptionFactory($tagFactory);
$description = $factory->create($contents, $context);
+17 -9
View File
@@ -15,6 +15,7 @@ namespace phpDocumentor\Reflection\DocBlock;
use InvalidArgumentException;
use Mockery as m;
use Name\Spaced\Tag;
use phpDocumentor\Reflection\Assets\CustomParam;
use phpDocumentor\Reflection\Assets\CustomServiceClass;
use phpDocumentor\Reflection\Assets\CustomServiceInterface;
@@ -134,10 +135,10 @@ class StandardTagFactoryTest extends TestCase
public function testAnEmptyContextIsCreatedIfNoneIsProvided(): void
{
$fqsen = '\Tag';
$resolver = m::mock(FqsenResolver::class)
->shouldReceive('resolve')
$resolver = m::mock(FqsenResolver::class);
$resolver->allows('resolve')
->with('Tag', m::type(Context::class))
->andReturn(new Fqsen($fqsen))
->andReturns(new Fqsen($fqsen))
->getMock();
$descriptionFactory = m::mock(DescriptionFactory::class);
$descriptionFactory->shouldIgnoreMissing();
@@ -246,18 +247,14 @@ class StandardTagFactoryTest extends TestCase
'The tag "@my-täg " does not seem to be wellformed, please check it for errors'
);
$typeResolver = new TypeResolver();
$fqsenResolver = new FqsenResolver();
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$context = new Context('');
$tagFactory = StandardTagFactory::createInstance(
$fqsenResolver,
['my-täg' => Author::class]
);
$tag = $tagFactory->create('@my-täg ', $context);
$tagFactory->create('@my-täg ', $context);
}
/**
@@ -291,6 +288,7 @@ class StandardTagFactoryTest extends TestCase
$tagFactory->addParameter('myParam', 'myValue');
$spy = $tagFactory->create('@spy');
self::assertInstanceOf(CustomParam::class, $spy);
$this->assertSame($resolver, $spy->fqsenResolver);
$this->assertSame('myValue', $spy->myParam);
}
@@ -311,6 +309,7 @@ class StandardTagFactoryTest extends TestCase
$spy = $tagFactory->create('@spy');
self::assertInstanceOf(CustomServiceClass::class, $spy);
$this->assertSame($service, $spy->formatter);
}
@@ -331,6 +330,7 @@ class StandardTagFactoryTest extends TestCase
$spy = $tagFactory->create('@spy');
self::assertInstanceOf(CustomServiceInterface::class, $spy);
$this->assertSame($service, $spy->formatter);
}
@@ -366,7 +366,10 @@ class StandardTagFactoryTest extends TestCase
$resolver = m::mock(FqsenResolver::class);
$tagFactory = StandardTagFactory::createInstance($resolver);
// phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
$tagFactory->registerTagHandler(\Name\Spaced\Tag::class, Author::class);
$tagFactory->registerTagHandler(
Tag::class, // @phpstan-ignore class.notFound
Author::class
);
}
/**
@@ -380,6 +383,7 @@ class StandardTagFactoryTest extends TestCase
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = StandardTagFactory::createInstance($resolver);
//@phpstan-ignore argument.type
$tagFactory->registerTagHandler('my-tag', '');
}
@@ -394,6 +398,8 @@ class StandardTagFactoryTest extends TestCase
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = StandardTagFactory::createInstance($resolver);
//@phpstan-ignore argument.type
$tagFactory->registerTagHandler('my-tag', 'IDoNotExist');
}
@@ -408,6 +414,8 @@ class StandardTagFactoryTest extends TestCase
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = StandardTagFactory::createInstance($resolver);
//@phpstan-ignore argument.type
$tagFactory->registerTagHandler('my-tag', 'stdClass');
}
+3
View File
@@ -82,6 +82,7 @@ class AuthorTest extends TestCase
$fixture = new Author($expected, '[email protected]');
self::assertInstanceOf(Author::class, $fixture);
$this->assertSame($expected, $fixture->getAuthorName());
}
@@ -95,6 +96,7 @@ class AuthorTest extends TestCase
$fixture = new Author('Mike van Riel', $expected);
self::assertInstanceOf(Author::class, $fixture);
$this->assertSame($expected, $fixture->getEmail());
}
@@ -156,6 +158,7 @@ class AuthorTest extends TestCase
{
$fixture = Author::create($input);
self::assertInstanceOf(Author::class, $fixture);
$this->assertSame($output, (string) $fixture);
$this->assertSame($name, $fixture->getAuthorName());
$this->assertSame($email, $fixture->getEmail());
+6
View File
@@ -23,6 +23,7 @@ class ExampleTest extends TestCase
public function testExampleWithoutContent(): void
{
$tag = Example::create('"example1.php"');
self::assertInstanceOf(Example::class, $tag);
$this->assertEquals('"example1.php"', $tag->getContent());
$this->assertEquals('', $tag->getDescription());
$this->assertEquals('example', $tag->getName());
@@ -39,6 +40,7 @@ class ExampleTest extends TestCase
public function testWithDescription(): void
{
$tag = Example::create('"example1.php" some text');
self::assertInstanceOf(Example::class, $tag);
$this->assertEquals('example1.php', $tag->getFilePath());
$this->assertEquals('some text', $tag->getDescription());
}
@@ -54,6 +56,7 @@ class ExampleTest extends TestCase
public function testStartlineIsParsed(): void
{
$tag = Example::create('"example1.php" 10');
self::assertInstanceOf(Example::class, $tag);
$this->assertEquals('example1.php', $tag->getFilePath());
$this->assertEquals(10, $tag->getStartingLine());
}
@@ -70,6 +73,7 @@ class ExampleTest extends TestCase
public function testAllowOmittingLineCount(): void
{
$tag = Example::create('"example1.php" 10 some text');
self::assertInstanceOf(Example::class, $tag);
$this->assertEquals('example1.php', $tag->getFilePath());
$this->assertEquals(10, $tag->getStartingLine());
$this->assertEquals('some text', $tag->getDescription());
@@ -87,6 +91,7 @@ class ExampleTest extends TestCase
public function testLengthIsParsed(): void
{
$tag = Example::create('"example1.php" 10 5');
self::assertInstanceOf(Example::class, $tag);
$this->assertEquals('example1.php', $tag->getFilePath());
$this->assertEquals(10, $tag->getStartingLine());
$this->assertEquals(5, $tag->getLineCount());
@@ -159,6 +164,7 @@ class ExampleTest extends TestCase
string $content
): void {
$tag = Example::create($input);
self::assertInstanceOf(Example::class, $tag);
$this->assertSame($filePath, $tag->getFilePath());
$this->assertSame($startLine, $tag->getStartingLine());
$this->assertSame($lineCount, $tag->getLineCount());
@@ -48,7 +48,7 @@ final class ParamFactoryTest extends TagFactoryTestCase
}
/**
* @return array<array-key, string|Param>
* @return array<int, array<int, string|Param|InvalidTag>>
*/
public function paramInputProvider(): array
{
@@ -27,23 +27,16 @@ use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\ParserConfig;
use PHPUnit\Framework\TestCase;
use function class_exists;
use function property_exists;
abstract class TagFactoryTestCase extends TestCase
{
public function parseTag(string $tag): PhpDocTagNode
{
if (class_exists(ParserConfig::class)) {
$config = new ParserConfig([]);
$lexer = new Lexer($config);
$constParser = new ConstExprParser($config);
$phpDocParser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser);
} else {
$lexer = new Lexer();
$constParser = new ConstExprParser();
$phpDocParser = new PhpDocParser(new TypeParser($constParser), $constParser);
}
$config = new ParserConfig([]);
$lexer = new Lexer($config);
$constParser = new ConstExprParser($config);
$phpDocParser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser);
$tagNode = $phpDocParser->parseTag(new TokenIterator($lexer->tokenize($tag)));
if (property_exists($tagNode->value, 'description') === true) {
+8 -2
View File
@@ -10,6 +10,7 @@ use PHPUnit\Framework\TestCase;
use Throwable;
use function fopen;
use function is_string;
use function serialize;
use function unserialize;
@@ -57,9 +58,12 @@ final class InvalidTagTest extends TestCase
self::assertSame('name', $tag->getName());
self::assertSame('@name Body', $tag->render());
self::assertSame($parentException, $tag->getException());
self::assertSame($e, $tag->getException()->getPrevious());
$trace = $tag->getException()->getPrevious()->getTrace();
if (isset($trace[0]['args'])) { // Not set by default on 7.4
self::assertTrue(is_string($trace[0]['args'][0]));
self::assertStringStartsWith('(Closure at', $trace[0]['args'][0]);
self::assertStringContainsString(__FILE__, $trace[0]['args'][0]);
}
@@ -70,7 +74,7 @@ final class InvalidTagTest extends TestCase
private function throwExceptionFromClosureWithClosureArgument(): void
{
$function = static function (): void {
$function = static function (?callable $foo = null): void {
throw new InvalidArgumentException();
};
@@ -87,9 +91,11 @@ final class InvalidTagTest extends TestCase
self::assertSame('name', $tag->getName());
self::assertSame('@name Body', $tag->render());
self::assertSame($parentException, $tag->getException());
self::assertSame($e, $tag->getException()->getPrevious());
$trace = $tag->getException()->getPrevious()->getTrace();
if (isset($trace[0]['args'])) { // Not set by default on 7.4
self::assertTrue(is_string($trace[0]['args'][0]));
self::assertStringStartsWith(
'resource(stream)',
$trace[0]['args'][0]
@@ -102,7 +108,7 @@ final class InvalidTagTest extends TestCase
private function throwExceptionWithResourceArgument(): void
{
$function = static function (): void {
$function = static function ($file): void {
throw new InvalidArgumentException();
};
@@ -81,6 +81,10 @@ class MethodParameterTest extends TestCase
sprintf('%s $argument = %s', $type, $defaultValueStr),
(string) $fixture
);
$this->assertSame(
$defaultValueStr,
$fixture->getDefaultValue()
);
}
/**
+2
View File
@@ -158,6 +158,7 @@ class SinceTest extends TestCase
$fixture = Since::create('1.0 My Description', $descriptionFactory, $context);
self::assertInstanceOf(Since::class, $fixture);
$this->assertSame('1.0 My Description', (string) $fixture);
$this->assertSame($version, $fixture->getVersion());
$this->assertSame($description, $fixture->getDescription());
@@ -178,6 +179,7 @@ class SinceTest extends TestCase
$fixture = Since::create('', $descriptionFactory, new Context(''));
self::assertInstanceOf(Since::class, $fixture);
$this->assertSame('', (string) $fixture);
$this->assertSame(null, $fixture->getVersion());
$this->assertSame(null, $fixture->getDescription());
+2
View File
@@ -227,6 +227,8 @@ class SourceTest extends TestCase
public function testExceptionIsThrownIfLineCountIsNotIntegerOrNull(): void
{
$this->expectException('InvalidArgumentException');
//@phpstan-ignore argument.type
new Source('1', []);
}
}
+2
View File
@@ -158,6 +158,7 @@ class VersionTest extends TestCase
$fixture = Version::create('1.0 My Description', $descriptionFactory, $context);
self::assertInstanceOf(Version::class, $fixture);
$this->assertSame('1.0 My Description', (string) $fixture);
$this->assertSame($version, $fixture->getVersion());
$this->assertSame($description, $fixture->getDescription());
@@ -178,6 +179,7 @@ class VersionTest extends TestCase
$fixture = Version::create('', $descriptionFactory, new Context(''));
self::assertInstanceOf(Version::class, $fixture);
$this->assertSame('', (string) $fixture);
$this->assertSame(null, $fixture->getVersion());
$this->assertSame(null, $fixture->getDescription());
+1 -1
View File
@@ -200,7 +200,7 @@ DOCBLOCK;
}
/**
* @return string[]
* @return array<int, array<int, string>>
*/
public function provideSummaryAndDescriptions(): array
{
+3 -2
View File
@@ -108,8 +108,9 @@ class DocBlockTest extends TestCase
public function testDocBlockAllowsOnlyTags(): void
{
$this->expectException('InvalidArgumentException');
$tags = [null];
$fixture = new DocBlock('', null, $tags);
$tags = [null];
// @phpstan-ignore argument.type
new DocBlock('', null, $tags);
}
/**
+6 -2
View File
@@ -41,8 +41,12 @@ final class PregSplitTest extends TestCase
public function testPregSplitThrowsOnError(): void
{
//We need to disable the error handler for phpunit... because we expect some errors here
$this->errorHandler = set_error_handler(static function (): void {
}, E_WARNING);
$this->errorHandler = set_error_handler(
static function (int $i, string $s, string $s2, int $x, ?array $trace = null): bool {
return true;
},
E_WARNING
);
$this->expectException(PcreException::class);
Utils::pregSplit('~InvalidRegular)Expression~', 'some word');