More cleanup of tag creation

TagWithType need to be created via a factory now.
This commit is contained in:
Jaapio
2025-12-24 16:16:59 +01:00
parent 02f9ed7a8f
commit fba45a3718
20 changed files with 267 additions and 377 deletions
+30 -50
View File
@@ -20,11 +20,10 @@ use phpDocumentor\Reflection\Assets\CustomServiceClass;
use phpDocumentor\Reflection\Assets\CustomServiceInterface;
use phpDocumentor\Reflection\Assets\CustomTagFactory;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\FqsenResolver;
@@ -69,7 +68,7 @@ class StandardTagFactoryTest extends TestCase
->with($expectedDescriptionText, $context)
->andReturn($expectedDescription);
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class));
$tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));
$tagFactory->addService($descriptionFactory, DescriptionFactory::class);
$tag = $tagFactory->create('@' . $expectedTagName . ' This is a description', $context);
@@ -94,7 +93,7 @@ class StandardTagFactoryTest extends TestCase
$expectedDescriptionText = ' foo Bar 123 ';
$context = new Context('');
$tagFactory = new StandardTagFactory(new FqsenResolver());
$tagFactory = StandardTagFactory::createInstance(new FqsenResolver());
$tagFactory->addService(new DescriptionFactory($tagFactory), DescriptionFactory::class);
$tag = $tagFactory->create('@' . $expectedTagName . $expectedDescriptionText, $context);
@@ -114,7 +113,7 @@ class StandardTagFactoryTest extends TestCase
public function testCreatingASpecificTag(): void
{
$context = new Context('');
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class));
$tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));
$tag = $tagFactory->create('@author Mike van Riel <[email protected]>', $context);
@@ -143,7 +142,7 @@ class StandardTagFactoryTest extends TestCase
$descriptionFactory = m::mock(DescriptionFactory::class);
$descriptionFactory->shouldIgnoreMissing();
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->addService($descriptionFactory, DescriptionFactory::class);
$tag = $tagFactory->create('@see Tag');
@@ -163,7 +162,8 @@ class StandardTagFactoryTest extends TestCase
public function testPassingYourOwnSetOfTagHandlers(): void
{
$context = new Context('');
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class), ['user' => Author::class]);
$tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));
$tagFactory->registerTagHandler('user', Author::class);
$tag = $tagFactory->create('@user Mike van Riel <[email protected]>', $context);
@@ -181,16 +181,11 @@ class StandardTagFactoryTest extends TestCase
*/
public function testPassingYourOwnSetOfTagHandlersWithGermanChars(): void
{
$typeResolver = new TypeResolver();
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$context = new Context('');
$tagFactory = new StandardTagFactory(
$fqsenResolver,
['my-täg' => Author::class]
);
$tagFactory->registerTagHandler('my-täg', Author::class);
$tag = $tagFactory->create('@my-täg foo bar ', $context);
@@ -209,17 +204,11 @@ class StandardTagFactoryTest extends TestCase
*/
public function testPassingYourOwnSetOfTagHandlersWithoutComment(): void
{
$typeResolver = new TypeResolver();
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$context = new Context('');
$tagFactory = new StandardTagFactory(
$fqsenResolver,
['my-täg' => Author::class]
);
$tagFactory->registerTagHandler('my-täg', Author::class);
$tag = $tagFactory->create('@my-täg', $context);
$this->assertInstanceOf(Author::class, $tag);
@@ -233,7 +222,7 @@ class StandardTagFactoryTest extends TestCase
$customFactory = new CustomTagFactory();
$injectedClass = new CustomServiceClass();
$tagFactory = new StandardTagFactory($fqsenResolver);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$tagFactory->addService($injectedClass);
$tagFactory->registerTagHandler('param', $customFactory);
$tag = $tagFactory->create('@param foo');
@@ -259,11 +248,11 @@ class StandardTagFactoryTest extends TestCase
$typeResolver = new TypeResolver();
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$context = new Context('');
$tagFactory = new StandardTagFactory(
$tagFactory = StandardTagFactory::createInstance(
$fqsenResolver,
['my-täg' => Author::class]
);
@@ -283,7 +272,7 @@ class StandardTagFactoryTest extends TestCase
$this->expectExceptionMessage(
'The tag "@user[myuser" does not seem to be wellformed, please check it for errors'
);
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class));
$tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));
$tagFactory->create('@user[myuser');
}
@@ -296,7 +285,7 @@ class StandardTagFactoryTest extends TestCase
public function testAddParameterToServiceLocator(): void
{
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->registerTagHandler('spy', CustomParam::class);
$tagFactory->addParameter('myParam', 'myValue');
@@ -316,7 +305,7 @@ class StandardTagFactoryTest extends TestCase
$service = new PassthroughFormatter();
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->addService($service);
$tagFactory->registerTagHandler('spy', CustomServiceClass::class);
@@ -336,7 +325,7 @@ class StandardTagFactoryTest extends TestCase
$service = new PassthroughFormatter();
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->addService($service, $interfaceName);
$tagFactory->registerTagHandler('spy', CustomServiceInterface::class);
@@ -356,7 +345,7 @@ class StandardTagFactoryTest extends TestCase
public function testRegisteringAHandlerForANewTag(): void
{
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->registerTagHandler('my-tag', Author::class);
@@ -375,7 +364,7 @@ class StandardTagFactoryTest extends TestCase
{
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
// phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
$tagFactory->registerTagHandler(\Name\Spaced\Tag::class, Author::class);
}
@@ -390,7 +379,7 @@ class StandardTagFactoryTest extends TestCase
{
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->registerTagHandler('my-tag', '');
}
@@ -404,7 +393,7 @@ class StandardTagFactoryTest extends TestCase
{
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->registerTagHandler('my-tag', 'IDoNotExist');
}
@@ -418,7 +407,7 @@ class StandardTagFactoryTest extends TestCase
{
$this->expectException('InvalidArgumentException');
$resolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($resolver);
$tagFactory = StandardTagFactory::createInstance($resolver);
$tagFactory->registerTagHandler('my-tag', 'stdClass');
}
@@ -439,28 +428,19 @@ class StandardTagFactoryTest extends TestCase
$descriptionFactory
->shouldReceive('create')
->once()
->with('', $context)
->with('mixed test', $context)
->andReturn(new Description(''));
$typeResolver = new TypeResolver();
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class));
$tagFactory = StandardTagFactory::createInstance(m::mock(FqsenResolver::class));
$tagFactory->addService($descriptionFactory, DescriptionFactory::class);
$tagFactory->addService($typeResolver, TypeResolver::class);
$tag = $tagFactory->create('@return mixed', $context);
$tag = $tagFactory->create('@deprecated mixed test', $context);
$this->assertInstanceOf(Return_::class, $tag);
$this->assertSame('return', $tag->getName());
}
public function testInvalidTagIsReturnedOnFailure(): void
{
$tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class));
$tag = $tagFactory->create('@see $name some invalid tag');
$this->assertInstanceOf(InvalidTag::class, $tag);
$this->assertInstanceOf(Deprecated::class, $tag);
$this->assertSame('deprecated', $tag->getName());
}
/**
@@ -469,7 +449,7 @@ class StandardTagFactoryTest extends TestCase
public function testValidFormattedTags(string $input, string $tagName, string $render): void
{
$fqsenResolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($fqsenResolver);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$tagFactory->registerTagHandler('tag', Generic::class);
$tag = $tagFactory->create($input);
@@ -540,7 +520,7 @@ class StandardTagFactoryTest extends TestCase
{
$this->expectException(InvalidArgumentException::class);
$fqsenResolver = m::mock(FqsenResolver::class);
$tagFactory = new StandardTagFactory($fqsenResolver);
$tagFactory = StandardTagFactory::createInstance($fqsenResolver);
$tagFactory->registerTagHandler('tag', Generic::class);
$tagFactory->create($input);
}
+2 -3
View File
@@ -16,7 +16,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\DocBlock\TagFactory;
use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\Types\Context;
@@ -188,8 +188,7 @@ class CoversTest extends TestCase
public function testFactoryMethodWithSpaceBeforeClass(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = Covers::create(
+3 -8
View File
@@ -16,8 +16,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\DocBlock\TagFactory;
use phpDocumentor\Reflection\Types\Context;
use PHPUnit\Framework\TestCase;
@@ -177,9 +176,7 @@ class LinkTest extends TestCase
*/
public function testFactoryMethodWithoutSpaceBeforeUrl(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = Link::create(
@@ -204,9 +201,7 @@ class LinkTest extends TestCase
*/
public function testFactoryMethodWithSpaceBeforeUrl(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = Link::create(
+2 -3
View File
@@ -16,7 +16,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\DocBlock\TagFactory;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as TagsFqsen;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url as UrlRef;
@@ -266,8 +266,7 @@ class SeeTest extends TestCase
public function testFactoryMethodWithoutUrl(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = See::create(
-152
View File
@@ -13,12 +13,8 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
use InvalidArgumentException;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\TypeResolver;
use phpDocumentor\Reflection\Types\Context;
use phpDocumentor\Reflection\Types\String_;
use PHPUnit\Framework\TestCase;
@@ -146,152 +142,4 @@ class ThrowsTest extends TestCase
$this->assertSame('string', (string) $fixture);
}
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
* @uses \phpDocumentor\Reflection\TypeResolver
* @uses \phpDocumentor\Reflection\DocBlock\Description
* @uses \phpDocumentor\Reflection\Types\String_
* @uses \phpDocumentor\Reflection\Types\Context
*
* @covers ::create
*/
public function testFactoryMethod(): void
{
$descriptionFactory = m::mock(DescriptionFactory::class);
$resolver = new TypeResolver();
$context = new Context('');
$type = new String_();
$description = new Description('My Description');
$descriptionFactory->shouldReceive('create')->with('My Description', $context)->andReturn($description);
$fixture = Throws::create('string My Description', $resolver, $descriptionFactory, $context);
$this->assertSame('string My Description', (string) $fixture);
$this->assertEquals($type, $fixture->getType());
$this->assertSame($description, $fixture->getDescription());
}
/**
* This test checks whether a braces in a Type are allowed.
*
* The advent of generics poses a few issues, one of them is that spaces can now be part of a type. In the past we
* could purely rely on spaces to split the individual parts of the body of a tag; but when there is a type in play
* we now need to check for braces.
*
* This test tests whether an error occurs demonstrating that the braces were taken into account; this test is still
* expected to produce an exception because the TypeResolver does not support generics.
*
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
* @uses \phpDocumentor\Reflection\TypeResolver
* @uses \phpDocumentor\Reflection\DocBlock\Description
* @uses \phpDocumentor\Reflection\Types\String_
* @uses \phpDocumentor\Reflection\Types\Context
*
* @covers ::create
*/
public function testFactoryMethodWithGenericWithSpace(): void
{
$descriptionFactory = m::mock(DescriptionFactory::class);
$resolver = new TypeResolver();
$context = new Context('');
$description = new Description('My Description');
$descriptionFactory->shouldReceive('create')
->with('My Description', $context)
->andReturn($description);
$fixture = Throws::create('array<string, string> My Description', $resolver, $descriptionFactory, $context);
$this->assertSame('array<string, string> My Description', (string) $fixture);
$this->assertEquals('array<string, string>', $fixture->getType());
$this->assertSame($description, $fixture->getDescription());
}
/**
* @see self::testFactoryMethodWithGenericWithSpace()
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
* @uses \phpDocumentor\Reflection\TypeResolver
* @uses \phpDocumentor\Reflection\DocBlock\Description
* @uses \phpDocumentor\Reflection\Types\String_
* @uses \phpDocumentor\Reflection\Types\Context
*
* @covers ::create
*/
public function testFactoryMethodWithGenericWithSpaceAndAddedEmojisToVerifyMultiByteBehaviour(): void
{
$this->markTestSkipped('A bug in the TypeResolver breaks this test');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('"\array😁<string,😁 😁string>" is not a valid Fqsen.');
$descriptionFactory = m::mock(DescriptionFactory::class);
$resolver = new TypeResolver();
$context = new Context('');
$description = new Description('My Description');
$descriptionFactory->shouldReceive('create')
->with('My Description', $context)
->andReturn($description);
Throws::create('array😁<string,😁 😁string> My Description', $resolver, $descriptionFactory, $context);
}
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Throws::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
* @uses \phpDocumentor\Reflection\TypeResolver
* @uses \phpDocumentor\Reflection\DocBlock\Description
* @uses \phpDocumentor\Reflection\Types\String_
* @uses \phpDocumentor\Reflection\Types\Context
*
* @covers ::create
*/
public function testFactoryMethodWithEmojisToVerifyMultiByteBehaviour(): void
{
$descriptionFactory = m::mock(DescriptionFactory::class);
$resolver = new TypeResolver();
$context = new Context('');
$description = new Description('My Description');
$descriptionFactory->shouldReceive('create')
->with('My Description', $context)
->andReturn($description);
$fixture = Throws::create('\My😁Class My Description', $resolver, $descriptionFactory, $context);
$this->assertSame('\My😁Class My Description', (string) $fixture);
$this->assertEquals('\My😁Class', $fixture->getType());
$this->assertSame($description, $fixture->getDescription());
}
/**
* @covers ::create
*/
public function testFactoryMethodFailsIfBodyIsNotEmpty(): void
{
$this->expectException('InvalidArgumentException');
$this->assertNull(Throws::create(''));
}
/**
* @covers ::create
*/
public function testFactoryMethodFailsIfResolverIsNull(): void
{
$this->expectException('InvalidArgumentException');
Throws::create('body');
}
/**
* @covers ::create
*/
public function testFactoryMethodFailsIfDescriptionFactoryIsNull(): void
{
$this->expectException('InvalidArgumentException');
Throws::create('body', new TypeResolver());
}
}
+3 -5
View File
@@ -16,7 +16,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags;
use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\DocBlock\TagFactory;
use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\Types\Context;
@@ -190,8 +190,7 @@ class UsesTest extends TestCase
public function testFactoryMethodWithoutSpaceBeforeClass(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = Uses::create(
@@ -220,8 +219,7 @@ class UsesTest extends TestCase
public function testFactoryMethodWithSpaceBeforeClass(): void
{
$fqsenResolver = new FqsenResolver();
$tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
$descriptionFactory = new DescriptionFactory($this->createMock(TagFactory::class));
$context = new Context('');
$fixture = Uses::create(