Merge remote-tracking branch 'upstream/master' into fix_for_phpstorm_stubs

* upstream/master:
  Bump mockery
  Fix FQSEN resolving on see,covers,uses
  Improve test coverage
This commit is contained in:
Lars Moelleken
2020-09-03 00:41:27 +02:00
10 changed files with 290 additions and 42 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ psalm:
.PHONY: test
test:
docker run -it --rm -v${CURDIR}:/github/workspace phpdoc/phpunit-ga
docker run -it --rm -v${CURDIR}:/data -w /data php:7.2 -f ./tests/coverage-checker.php 89
docker run -it --rm -v${CURDIR}:/data -w /data php:7.2 -f ./tests/coverage-checker.php 90
.PHONY: pre-commit-test
pre-commit-test: test phpcs phpstan psalm
Generated
-14
View File
@@ -160,20 +160,6 @@
"polyfill",
"portable"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-06-06T08:46:27+00:00"
},
{
+16 -1
View File
@@ -20,6 +20,8 @@ use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\Types\Context as TypeContext;
use phpDocumentor\Reflection\Utils;
use Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
/**
* Reflection class for a @covers tag in a Docblock.
@@ -54,11 +56,24 @@ final class Covers extends BaseTag implements Factory\StaticMethod
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
return new static(
$resolver->resolve($parts[0], $context),
self::resolveFqsen($parts[0], $resolver, $context),
$descriptionFactory->create($parts[1] ?? '', $context)
);
}
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
{
Assert::notNull($fqsenResolver);
$fqsenParts = explode('::', $parts);
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
if (!array_key_exists(1, $fqsenParts)) {
return $resolved;
}
return new Fqsen($resolved . '::' . $fqsenParts[1]);
}
/**
* Returns the structural element this tag refers to.
*/
+3 -3
View File
@@ -48,7 +48,7 @@ final class Example implements Tag, Factory\StaticMethod
public function __construct(string $filePath, bool $isURI, int $startingLine, int $lineCount, ?string $content)
{
Assert::notEmpty($filePath);
Assert::greaterThanEq($startingLine, 0);
Assert::greaterThanEq($startingLine, 1);
Assert::greaterThanEq($lineCount, 0);
$this->filePath = $filePath;
@@ -63,7 +63,7 @@ final class Example implements Tag, Factory\StaticMethod
public function getContent() : string
{
if ($this->content === null) {
if ($this->content === null || $this->content === '') {
$filePath = '"' . $this->filePath . '"';
if ($this->isURI) {
$filePath = $this->isUriRelative($this->filePath)
@@ -107,7 +107,7 @@ final class Example implements Tag, Factory\StaticMethod
// Starting line / Number of lines / Description
if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) {
$startingLine = (int) $contentMatches[1];
if (isset($contentMatches[2]) && $contentMatches[2] !== '') {
if (isset($contentMatches[2])) {
$lineCount = (int) $contentMatches[2];
}
+17 -2
View File
@@ -18,10 +18,13 @@ 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;
use phpDocumentor\Reflection\Utils;
use Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
use function preg_match;
/**
@@ -50,7 +53,6 @@ final class See extends BaseTag implements Factory\StaticMethod
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
) : self {
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
@@ -61,7 +63,20 @@ final class See extends BaseTag implements Factory\StaticMethod
return new static(new Url($parts[0]), $description);
}
return new static(new FqsenRef($typeResolver->resolve($parts[0], $context)), $description);
return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);
}
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
{
Assert::notNull($fqsenResolver);
$fqsenParts = explode('::', $parts);
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
if (!array_key_exists(1, $fqsenParts)) {
return $resolved;
}
return new Fqsen($resolved . '::' . $fqsenParts[1]);
}
/**
+16 -1
View File
@@ -20,6 +20,8 @@ use phpDocumentor\Reflection\FqsenResolver;
use phpDocumentor\Reflection\Types\Context as TypeContext;
use phpDocumentor\Reflection\Utils;
use Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
/**
* Reflection class for a {@}uses tag in a Docblock.
@@ -53,11 +55,24 @@ final class Uses extends BaseTag implements Factory\StaticMethod
$parts = Utils::pregSplit('/\s+/Su', $body, 2);
return new static(
$resolver->resolve($parts[0], $context),
self::resolveFqsen($parts[0], $resolver, $context),
$descriptionFactory->create($parts[1] ?? '', $context)
);
}
private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
{
Assert::notNull($fqsenResolver);
$fqsenParts = explode('::', $parts);
$resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
if (!array_key_exists(1, $fqsenParts)) {
return $resolved;
}
return new Fqsen($resolved . '::' . $fqsenParts[1]);
}
/**
* Returns the structural element this tag refers to.
*/
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace phpDocumentor\Reflection;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\Types\Context;
use PHPUnit\Framework\TestCase;
class DocblockSeeTagResolvingTest extends TestCase
{
public function testResolvesSeeFQSENOfInlineTags()
{
$context = new Context('\Project\Sub\Level', ['Issue2425B' => '\Project\Other\Level\Issue2425B', 'Aliased' => 'Project\Other\Level\Issue2425C']);
$docblockString = <<<DOCBLOCK
/**
* Class summary.
*
* A description containing an inline {@see Issue2425B::bar()} tag
* to a class inside of the project referenced via a use statement.
*
* And here is another inline {@see Aliased::bar()} tag to a class
* aliased via a use statement.
*/
DOCBLOCK;
$factory = DocBlockFactory::createInstance();
$docblock = $factory->create($docblockString, $context);
/** @var See $see1 */
$see1 = $docblock->getDescription()->getTags()[0];
$this->assertSame('\Project\Other\Level\Issue2425B::bar()', (string)$see1->getReference());
}
}
+31 -5
View File
@@ -150,14 +150,40 @@ class AuthorTest extends TestCase
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Author::<public>
*
* @covers ::create
* @dataProvider authorTagProvider
*/
public function testFactoryMethod() : void
public function testFactoryMethod(string $input, string $output, string $name, string $email) : void
{
$fixture = Author::create('Mike van Riel <[email protected]>');
$fixture = Author::create($input);
$this->assertSame('Mike van Riel <[email protected]>', (string) $fixture);
$this->assertSame('Mike van Riel', $fixture->getAuthorName());
$this->assertSame('[email protected]', $fixture->getEmail());
$this->assertSame($output, (string) $fixture);
$this->assertSame($name, $fixture->getAuthorName());
$this->assertSame($email, $fixture->getEmail());
}
/** @return mixed[][] */
public function authorTagProvider() : array
{
return [
[
'Mike van Riel <[email protected]>',
'Mike van Riel <[email protected]>',
'Mike van Riel',
'[email protected]',
],
[
'Mike van Riel < [email protected] >',
'Mike van Riel <[email protected]>',
'Mike van Riel',
'[email protected]',
],
[
'Mike van Riel',
'Mike van Riel',
'Mike van Riel',
'',
],
];
}
/**
+136 -15
View File
@@ -4,23 +4,16 @@ declare(strict_types=1);
namespace DocBlock\Tags;
use Mockery as m;
use InvalidArgumentException;
use phpDocumentor\Reflection\DocBlock\Tags\Example;
use PHPUnit\Framework\TestCase;
/**
* @coversDefaultClass \phpDocumentor\Reflection\DocBlock\Tags\Example
* @covers ::<private>
*/
class ExampleTest extends TestCase
{
/**
* Call Mockery::close after each test.
*/
public function tearDown() : void
{
m::close();
}
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag
*
@@ -103,19 +96,147 @@ class ExampleTest extends TestCase
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag
*
* @dataProvider tagContentProvider
* @covers ::create
* @covers ::__construct
* @covers ::getFilePath
* @covers ::getStartingLine
* @covers ::getLineCount
* @covers ::getDescription
* @covers ::getContent
*/
public function testFullExample() : void
public function testFactoryMethod(
string $input,
string $filePath,
int $startLine,
int $lineCount,
?string $description,
string $content
) : void {
$tag = Example::create($input);
$this->assertSame($filePath, $tag->getFilePath());
$this->assertSame($startLine, $tag->getStartingLine());
$this->assertSame($lineCount, $tag->getLineCount());
$this->assertSame($description, $tag->getDescription());
$this->assertSame($content, $tag->getContent());
}
/** @return mixed[][] */
public function tagContentProvider() : array
{
$tag = Example::create('"example1.php" 10 5 test text');
$this->assertEquals('example1.php', $tag->getFilePath());
$this->assertEquals(10, $tag->getStartingLine());
$this->assertEquals(5, $tag->getLineCount());
$this->assertEquals('test text', $tag->getDescription());
return [
[
'"example1.php" 10 5 test text ',
'example1.php',
10,
5,
'test text',
'test text',
],
[
'example1.php 10 5 test text',
'example1.php',
10,
5,
'test text',
'test text',
],
[
'example1.php 1 10 test text',
'example1.php',
1,
10,
'test text',
'test text',
],
[
'example1.php',
'example1.php',
1,
0,
null,
'example1.php',
],
[
'file://example1.php ',
'file://example1.php',
1,
0,
'',
'file://example1.php',
],
[
'/example1.php',
'/example1.php',
1,
0,
null,
'/example1.php',
],
];
}
/**
* @dataProvider invalidExampleProvider
* @covers ::__construct
*/
public function testValidatesArguments(
string $filePath,
bool $isUrl,
int $startLine,
int $lineCount,
string $description
) : void {
$this->expectException(InvalidArgumentException::class);
new Example(
$filePath,
$isUrl,
$startLine,
$lineCount,
$description
);
}
/** @return mixed[][] */
public function invalidExampleProvider() : array
{
return [
'invalid start' => [
'/some/path',
false,
-1,
0,
'text',
],
'invalid start 2' => [
'/some/path',
false,
-10,
0,
'text',
],
'invalid length' => [
'/some/path',
false,
1,
-1,
'text',
],
'invalid length 2' => [
'/some/path',
false,
1,
-10,
'text',
],
'empty filepath' => [
'',
false,
1,
0,
'text',
],
];
}
}
+32
View File
@@ -188,6 +188,38 @@ class SeeTest extends TestCase
$this->assertSame($description, $fixture->getDescription());
}
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
* @uses \phpDocumentor\Reflection\FqsenResolver
* @uses \phpDocumentor\Reflection\DocBlock\Description
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen
* @uses \phpDocumentor\Reflection\Fqsen
* @uses \phpDocumentor\Reflection\Types\Context
*
* @covers ::create
*/
public function testFactoryMethodWithNonClassFQSEN() : void
{
$descriptionFactory = m::mock(DescriptionFactory::class);
$resolver = m::mock(FqsenResolver::class);
$context = new Context('');
$fqsen = new Fqsen('\DateTime');
$description = new Description('My Description');
$descriptionFactory
->shouldReceive('create')->with('My Description', $context)->andReturn($description);
$resolver->shouldReceive('resolve')->with('DateTime', $context)->andReturn($fqsen);
$fixture = See::create('DateTime::createFromFormat() My Description', $resolver, $descriptionFactory, $context);
$this->assertSame('\DateTime::createFromFormat() My Description', (string) $fixture);
$this->assertInstanceOf(FqsenRef::class, $fixture->getReference());
$this->assertSame('\DateTime::createFromFormat()', (string) $fixture->getReference());
$this->assertSame($description, $fixture->getDescription());
}
/**
* @uses \phpDocumentor\Reflection\DocBlock\Tags\See::<public>
* @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory