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()); }