From 2b49b7962a3df9c69629c4bfe6d87c04b9ee850c Mon Sep 17 00:00:00 2001 From: Jaapio Date: Fri, 14 Jul 2017 23:07:21 +0200 Subject: [PATCH] Allow see tag to url The see tag allows Fqsen and uri's. But in the current implementation only Fqsen where allowed. This wrapps the uri and Fqsen in an uniform class to be able address them in the same way. Fixes #78 --- src/DocBlock/Tags/Reference/Fqsen.php | 42 +++++++++++++++++++ src/DocBlock/Tags/Reference/Reference.php | 21 ++++++++++ src/DocBlock/Tags/Reference/Url.php | 40 ++++++++++++++++++ src/DocBlock/Tags/See.php | 20 ++++++--- tests/unit/DocBlock/Tags/SeeTest.php | 49 +++++++++++++++++++---- 5 files changed, 158 insertions(+), 14 deletions(-) create mode 100644 src/DocBlock/Tags/Reference/Fqsen.php create mode 100644 src/DocBlock/Tags/Reference/Reference.php create mode 100644 src/DocBlock/Tags/Reference/Url.php diff --git a/src/DocBlock/Tags/Reference/Fqsen.php b/src/DocBlock/Tags/Reference/Fqsen.php new file mode 100644 index 0000000..dc7b8b6 --- /dev/null +++ b/src/DocBlock/Tags/Reference/Fqsen.php @@ -0,0 +1,42 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +use phpDocumentor\Reflection\Fqsen as RealFqsen; + +/** + * Fqsen reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +final class Fqsen implements Reference +{ + /** + * @var RealFqsen + */ + private $fqsen; + + /** + * Fqsen constructor. + */ + public function __construct(RealFqsen $fqsen) + { + $this->fqsen = $fqsen; + } + + /** + * @return string string representation of the referenced fqsen + */ + public function __toString() + { + return (string)$this->fqsen; + } +} diff --git a/src/DocBlock/Tags/Reference/Reference.php b/src/DocBlock/Tags/Reference/Reference.php new file mode 100644 index 0000000..5bf27d3 --- /dev/null +++ b/src/DocBlock/Tags/Reference/Reference.php @@ -0,0 +1,21 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +/** + * Interface for references in {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +interface Reference +{ + public function __toString(); +} diff --git a/src/DocBlock/Tags/Reference/Url.php b/src/DocBlock/Tags/Reference/Url.php new file mode 100644 index 0000000..2671d5e --- /dev/null +++ b/src/DocBlock/Tags/Reference/Url.php @@ -0,0 +1,40 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @link http://phpdoc.org + */ + +namespace phpDocumentor\Reflection\DocBlock\Tags\Reference; + +use Webmozart\Assert\Assert; + +/** + * Url reference used by {@see phpDocumentor\Reflection\DocBlock\Tags\See} + */ +final class Url implements Reference +{ + /** + * @var string + */ + private $uri; + + /** + * Url constructor. + */ + public function __construct($uri) + { + Assert::stringNotEmpty($uri); + $this->uri = $uri; + } + + public function __toString() + { + return $this->uri; + } +} diff --git a/src/DocBlock/Tags/See.php b/src/DocBlock/Tags/See.php index 64ee3d8..3774b49 100644 --- a/src/DocBlock/Tags/See.php +++ b/src/DocBlock/Tags/See.php @@ -13,6 +13,9 @@ namespace phpDocumentor\Reflection\DocBlock\Tags; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; @@ -26,16 +29,16 @@ class See extends BaseTag implements Factory\StaticMethod { protected $name = 'see'; - /** @var Fqsen */ + /** @var Reference */ protected $refers = null; /** * Initializes this tag. * - * @param Fqsen $refers + * @param Reference $refers * @param Description $description */ - public function __construct(Fqsen $refers, Description $description = null) + public function __construct(Reference $refers, Description $description = null) { $this->refers = $refers; $this->description = $description; @@ -56,13 +59,18 @@ class See extends BaseTag implements Factory\StaticMethod $parts = preg_split('/\s+/Su', $body, 2); $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; - return new static($resolver->resolve($parts[0], $context), $description); + // https://tools.ietf.org/html/rfc2396#section-3 + if (preg_match('/\w:\/\/\w/i', $parts[0])) { + return new static(new Url($parts[0]), $description); + } + + return new static(new FqsenRef($resolver->resolve($parts[0], $context)), $description); } /** - * Returns the structural element this tag refers to. + * Returns the ref of this tag. * - * @return Fqsen + * @return Reference */ public function getReference() { diff --git a/tests/unit/DocBlock/Tags/SeeTest.php b/tests/unit/DocBlock/Tags/SeeTest.php index 8d3e3e8..b60bdf2 100644 --- a/tests/unit/DocBlock/Tags/SeeTest.php +++ b/tests/unit/DocBlock/Tags/SeeTest.php @@ -15,6 +15,8 @@ namespace phpDocumentor\Reflection\DocBlock\Tags; use Mockery as m; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef; +use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url as UrlRef; use phpDocumentor\Reflection\Fqsen; use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context; @@ -32,7 +34,7 @@ class SeeTest extends \PHPUnit_Framework_TestCase */ public function testIfCorrectTagNameIsReturned() { - $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + $fixture = new See(new FqsenRef(new Fqsen('\DateTime')), new Description('Description')); $this->assertSame('see', $fixture->getName()); } @@ -47,7 +49,7 @@ class SeeTest extends \PHPUnit_Framework_TestCase */ public function testIfTagCanBeRenderedUsingDefaultFormatter() { - $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + $fixture = new See(new FqsenRef(new Fqsen('\DateTime')), new Description('Description')); $this->assertSame('@see \DateTime Description', $fixture->render()); } @@ -59,7 +61,7 @@ class SeeTest extends \PHPUnit_Framework_TestCase */ public function testIfTagCanBeRenderedUsingSpecificFormatter() { - $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + $fixture = new See(new FqsenRef(new Fqsen('\DateTime')), new Description('Description')); $formatter = m::mock(Formatter::class); $formatter->shouldReceive('format')->with($fixture)->andReturn('Rendered output'); @@ -73,7 +75,7 @@ class SeeTest extends \PHPUnit_Framework_TestCase */ public function testHasReferenceToFqsen() { - $expected = new Fqsen('\DateTime'); + $expected = new FqsenRef(new Fqsen('\DateTime')); $fixture = new See($expected); @@ -89,7 +91,7 @@ class SeeTest extends \PHPUnit_Framework_TestCase { $expected = new Description('Description'); - $fixture = new See(new Fqsen('\DateTime'), $expected); + $fixture = new See(new FqsenRef(new Fqsen('\DateTime')), $expected); $this->assertSame($expected, $fixture->getDescription()); } @@ -101,9 +103,9 @@ class SeeTest extends \PHPUnit_Framework_TestCase */ public function testStringRepresentationIsReturned() { - $fixture = new See(new Fqsen('\DateTime'), new Description('Description')); + $fixture = new See(new FqsenRef(new Fqsen('\DateTime::format()')), new Description('Description')); - $this->assertSame('\DateTime Description', (string)$fixture); + $this->assertSame('\DateTime::format() Description', (string)$fixture); } /** @@ -131,7 +133,38 @@ class SeeTest extends \PHPUnit_Framework_TestCase $fixture = See::create('DateTime My Description', $resolver, $descriptionFactory, $context); $this->assertSame('\DateTime My Description', (string)$fixture); - $this->assertSame($fqsen, $fixture->getReference()); + $this->assertInstanceOf(FqsenRef::class, $fixture->getReference()); + $this->assertSame((string)$fqsen, (string)$fixture->getReference()); + $this->assertSame($description, $fixture->getDescription()); + } + + /** + * @covers ::create + * @uses \phpDocumentor\Reflection\DocBlock\Tags\See:: + * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory + * @uses \phpDocumentor\Reflection\FqsenResolver + * @uses \phpDocumentor\Reflection\DocBlock\Description + * @uses \phpDocumentor\Reflection\DocBlock\Tags\Reference\Url + * @uses \phpDocumentor\Reflection\Types\Context + */ + public function testFactoryMethodWithUrl() + { + $descriptionFactory = m::mock(DescriptionFactory::class); + $resolver = m::mock(FqsenResolver::class); + $context = new Context(''); + + $description = new Description('My Description'); + + $descriptionFactory + ->shouldReceive('create')->with('My Description', $context)->andReturn($description); + + $resolver->shouldNotReceive('resolve'); + + $fixture = See::create('https://test.org My Description', $resolver, $descriptionFactory, $context); + + $this->assertSame('https://test.org My Description', (string)$fixture); + $this->assertInstanceOf(UrlRef::class, $fixture->getReference()); + $this->assertSame('https://test.org', (string)$fixture->getReference()); $this->assertSame($description, $fixture->getDescription()); }