Merge pull request #200 from phpDocumentor/feature/improved-tag-parsing

Limit characters after tag name
This commit is contained in:
Jaap van Otterdijk
2020-02-09 09:15:34 +01:00
committed by GitHub
2 changed files with 96 additions and 9 deletions
+4 -9
View File
@@ -46,6 +46,7 @@ use function count;
use function get_class; use function get_class;
use function preg_match; use function preg_match;
use function strpos; use function strpos;
use function trim;
/** /**
* Creates a Tag object given the contents of a tag. * Creates a Tag object given the contents of a tag.
@@ -67,7 +68,7 @@ use function strpos;
final class StandardTagFactory implements TagFactory final class StandardTagFactory implements TagFactory
{ {
/** PCRE regular expression matching a tag name. */ /** PCRE regular expression matching a tag name. */
public const REGEX_TAGNAME = '[\w\-\_\\\\]+'; public const REGEX_TAGNAME = '[\w\-\_\\\\:]+';
/** /**
* @var string[] An array with a tag as a key, and an * @var string[] An array with a tag as a key, and an
@@ -147,13 +148,7 @@ final class StandardTagFactory implements TagFactory
[$tagName, $tagBody] = $this->extractTagParts($tagLine); [$tagName, $tagBody] = $this->extractTagParts($tagLine);
if ($tagBody !== '' && strpos($tagBody, '[') === 0) { return $this->createTag(trim($tagBody), $tagName, $context);
throw new InvalidArgumentException(
'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
);
}
return $this->createTag($tagBody, $tagName, $context);
} }
/** /**
@@ -199,7 +194,7 @@ final class StandardTagFactory implements TagFactory
private function extractTagParts(string $tagLine) : array private function extractTagParts(string $tagLine) : array
{ {
$matches = []; $matches = [];
if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)/us', $tagLine, $matches)) { if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')((?:[\s\(\{])\s*([^\s].*)|$)/us', $tagLine, $matches)) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors'
); );
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock; namespace phpDocumentor\Reflection\DocBlock;
use InvalidArgumentException;
use Mockery as m; use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Tags\Author; use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter; use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
@@ -341,4 +342,95 @@ class StandardTagFactoryTest extends TestCase
$this->assertInstanceOf(InvalidTag::class, $tag); $this->assertInstanceOf(InvalidTag::class, $tag);
} }
/**
* @dataProvider validTagProvider
*/
public function testValidFormattedTags(string $input, string $tagName, string $render) : void
{
$fqsenResolver = $this->prophesize(FqsenResolver::class);
$tagFactory = new StandardTagFactory($fqsenResolver->reveal());
$tagFactory->registerTagHandler('tag', Generic::class);
$tag = $tagFactory->create($input);
self::assertSame($tagName, $tag->getName());
self::assertSame($render, $tag->render());
}
/**
* @return string[][]
*
* @phpstan-return array<string, array<int, string>>
*/
public function validTagProvider() : array
{
//rendered result is adding a space, because the tags are not rendered properly.
return [
'tag without body' => [
'@tag',
'tag',
'@tag',
],
'tag specialization' => [
'@tag:some-spec body',
'tag:some-spec',
'@tag:some-spec body',
],
'tag specialization followed by parenthesis' => [
'@tag:some-spec(body)',
'tag:some-spec',
'@tag:some-spec (body)',
],
'tag with textual description' => [
'@tag some text',
'tag',
'@tag some text',
],
'tag body starting with sqare brackets is allowed' => [
'@tag [is valid]',
'tag',
'@tag [is valid]',
],
'tag body starting with curly brackets is allowed' => [
'@tag {is valid}',
'tag',
'@tag {is valid}',
],
'tag name followed by curly brackets directly is allowed' => [
'@tag{is valid}',
'tag',
'@tag {is valid}',
],
'parenthesis directly following a tag name is valid' => [
'@tag(is valid)',
'tag',
'@tag (is valid)',
],
];
}
/**
* @dataProvider invalidTagProvider
*/
public function testInValidFormattedTags(string $input) : void
{
$this->expectException(InvalidArgumentException::class);
$fqsenResolver = $this->prophesize(FqsenResolver::class);
$tagFactory = new StandardTagFactory($fqsenResolver->reveal());
$tagFactory->registerTagHandler('tag', Generic::class);
$tagFactory->create($input);
}
/**
* @return string[][]
*
* @phpstan-return list<array<int, string>>
*/
public function invalidTagProvider() : array
{
return [
['@tag[invalid]'],
['@tag@invalid'],
];
}
} }