Skip to content

Commit

Permalink
extract test for phpdocs to separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
isfedorov committed Nov 29, 2020
1 parent 072c8d9 commit aa156ca
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 167 deletions.
176 changes: 176 additions & 0 deletions tests/StubsPhpDocTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?php
declare(strict_types=1);

namespace StubTests;

use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Link;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\DocBlock\Tags\Since;
use PHPUnit\Framework\TestCase;
use StubTests\Model\BasePHPClass;
use StubTests\Model\BasePHPElement;
use StubTests\Model\PHPConst;
use StubTests\Model\PHPDocElement;
use StubTests\Model\PHPFunction;
use StubTests\Model\PHPMethod;
use StubTests\Model\Tags\RemovedTag;
use StubTests\Parsers\Utils;

class StubsPhpDocTest extends TestCase
{
/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubClassConstantProvider
*/
public function testClassConstantsPHPDocs(string $className, PHPConst $constant): void
{
self::assertNull($constant->parseError, $constant->parseError ?: '');
self::checkPHPDocCorrectness($constant, "constant $className::$constant->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubConstantProvider
*/
public function testConstantsPHPDocs(PHPConst $constant): void
{
self::assertNull($constant->parseError, $constant->parseError ?: '');
self::checkPHPDocCorrectness($constant, "constant $constant->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubFunctionProvider
*/
public function testFunctionPHPDocs(PHPFunction $function): void
{
self::assertNull($function->parseError, $function->parseError ?: '');
self::checkPHPDocCorrectness($function, "function $function->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubClassProvider
*/
public function testClassesPHPDocs(BasePHPClass $class): void
{
self::assertNull($class->parseError, $class->parseError ?: '');
self::checkPHPDocCorrectness($class, "class $class->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubMethodProvider
*/
public function testMethodsPHPDocs(string $methodName, PHPMethod $method): void
{
if ($methodName === '__construct') {
self::assertNull($method->returnTag, '@return tag for __construct should be omitted');
}
self::assertNull($method->parseError, $method->parseError ?: '');
self::checkPHPDocCorrectness($method, "method $methodName");
}

private static function checkDeprecatedRemovedSinceVersionsMajor(BasePHPElement $element, string $elementName): void
{
/** @var PHPDocElement $element */
foreach ($element->sinceTags as $sinceTag) {
if ($sinceTag instanceof Since) {
$version = $sinceTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($sinceTag), "$elementName has
'since' version $version.'Since' version for PHP Core functionality for style consistency
should have X.X format for the case when patch version is '0'.");
}
}
}
foreach ($element->deprecatedTags as $deprecatedTag) {
if ($deprecatedTag instanceof Deprecated) {
$version = $deprecatedTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($deprecatedTag), "$elementName has
'deprecated' version $version.'Deprecated' version for PHP Core functionality for style consistency
should have X.X format for the case when patch version is '0'.");
}
}
}
foreach ($element->removedTags as $removedTag) {
if ($removedTag instanceof RemovedTag) {
$version = $removedTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($removedTag), "$elementName has
'removed' version $version.'Removed' version for PHP Core functionality for style consistency
should have X.X format for the case when patch version is '0'.");
}
}
}
}

private static function checkLinks(BasePHPElement $element, string $elementName): void
{
/** @var PHPDocElement $element */
foreach ($element->links as $link) {
if ($link instanceof Link) {
self::assertStringStartsWith(
'https',
$link->getLink(),
"In $elementName @link doesn't start with https"
);
if (getenv('CHECK_LINKS') === 'true') {
if ($element->stubBelongsToCore) {
$request = curl_init($link->getLink());
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_exec($request);
$response = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
curl_close($request);
self::assertTrue($response < 400);
}
}
}
}
foreach ($element->see as $see) {
if ($see instanceof See && $see->getReference() instanceof Url) {
$uri = (string)$see->getReference();
self::assertStringStartsWith('https', $uri, "In $elementName @see doesn't start with https");
}
}
}

private static function checkContainsOnlyValidTags(BasePHPElement $element, string $elementName): void
{
$VALID_TAGS = [
'author',
'copyright',
'deprecated',
'example', //temporary addition due to the number of existing cases
'inheritdoc',
'internal',
'link',
'meta',
'method',
'mixin',
'package',
'param',
'property',
'property-read',
'removed',
'return',
'see',
'since',
'throws',
'uses',
'var',
'version',
];
/** @var PHPDocElement $element */
foreach ($element->tagNames as $tagName) {
self::assertContains($tagName, $VALID_TAGS, "Element $elementName has invalid tag: @$tagName");
}
}

private static function checkPHPDocCorrectness(BasePHPElement $element, string $elementName): void
{
self::checkLinks($element, $elementName);
if ($element->stubBelongsToCore) {
self::checkDeprecatedRemovedSinceVersionsMajor($element, $elementName);
}
self::checkContainsOnlyValidTags($element, $elementName);
}
}
172 changes: 5 additions & 167 deletions tests/StubsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,15 @@

namespace StubTests;

use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Link;
use phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\DocBlock\Tags\Since;
use PHPUnit\Framework\TestCase;
use StubTests\Model\BasePHPClass;
use StubTests\Model\BasePHPElement;
use StubTests\Model\PHPClass;
use StubTests\Model\PHPConst;
use StubTests\Model\PHPDocElement;
use StubTests\Model\PHPFunction;
use StubTests\Model\PHPInterface;
use StubTests\Model\PHPMethod;
use StubTests\Model\PHPParameter;
use StubTests\Model\StubProblemType;
use StubTests\Model\Tags\RemovedTag;
use StubTests\Parsers\Utils;
use StubTests\TestData\Providers\PhpStormStubsSingleton;
use function array_filter;

Expand Down Expand Up @@ -112,15 +103,6 @@ public function testFunctions(PHPFunction $function): void
self::assertEquals($function->returnType, preg_replace('/\w+\[]/', 'array', $phpstormFunction->returnType), "Function $functionName has invalid return type");
}

private function printParameters(array $params): string
{
$signature = '';
foreach ($params as $param) {
$signature .= '$' . $param->name . ', ';
}
return trim($signature, ", ");
}

/**
* @dataProvider \StubTests\TestData\Providers\ReflectionTestDataProviders::classProvider
*/
Expand Down Expand Up @@ -325,15 +307,6 @@ public function testInterfaces(PHPInterface $interface): void
}
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubClassConstantProvider
*/
public function testClassConstantsPHPDocs(string $className, PHPConst $constant): void
{
static::assertNull($constant->parseError, $constant->parseError ?: '');
$this->checkPHPDocCorrectness($constant, "constant $className::$constant->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::coreStubMethodProvider
*/
Expand Down Expand Up @@ -368,84 +341,13 @@ public function testCoreMethodsTypeHints(string $methodName, PHPMethod $stubFunc
}
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubConstantProvider
*/
public function testConstantsPHPDocs(PHPConst $constant): void
{
static::assertNull($constant->parseError, $constant->parseError ?: '');
$this->checkPHPDocCorrectness($constant, "constant $constant->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubFunctionProvider
*/
public function testFunctionPHPDocs(PHPFunction $function): void
{
static::assertNull($function->parseError, $function->parseError ?: '');
$this->checkPHPDocCorrectness($function, "function $function->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubClassProvider
*/
public function testClassesPHPDocs(BasePHPClass $class): void
{
static::assertNull($class->parseError, $class->parseError ?: '');
$this->checkPHPDocCorrectness($class, "class $class->name");
}

/**
* @dataProvider \StubTests\TestData\Providers\StubsTestDataProviders::stubMethodProvider
*/
public function testMethodsPHPDocs(string $methodName, PHPMethod $method): void
{
if ($methodName === '__construct') {
static::assertNull($method->returnTag, '@return tag for __construct should be omitted');
}
static::assertNull($method->parseError, $method->parseError ?: '');
$this->checkPHPDocCorrectness($method, "method $methodName");
}

private function checkPHPDocCorrectness(BasePHPElement $element, string $elementName): void
{
$this->checkLinks($element, $elementName);
if ($element->stubBelongsToCore) {
$this->checkDeprecatedRemovedSinceVersionsMajor($element, $elementName);
}
$this->checkContainsOnlyValidTags($element, $elementName);
}

private function checkContainsOnlyValidTags(BasePHPElement $element, string $elementName): void
private function printParameters(array $params): string
{
$VALID_TAGS = [
'author',
'copyright',
'deprecated',
'example', //temporary addition due to the number of existing cases
'inheritdoc',
'internal',
'link',
'meta',
'method',
'mixin',
'package',
'param',
'property',
'property-read',
'removed',
'return',
'see',
'since',
'throws',
'uses',
'var',
'version',
];
/** @var PHPDocElement $element */
foreach ($element->tagNames as $tagName) {
static::assertContains($tagName, $VALID_TAGS, "Element $elementName has invalid tag: @$tagName");
$signature = '';
foreach ($params as $param) {
$signature .= '$' . $param->name . ', ';
}
return trim($signature, ", ");
}

private static function getParameterRepresentation(PHPFunction $function): string
Expand All @@ -468,70 +370,6 @@ private static function getParameterRepresentation(PHPFunction $function): strin
return $result;
}

private function checkLinks(BasePHPElement $element, string $elementName): void
{
/** @var PHPDocElement $element */
foreach ($element->links as $link) {
if ($link instanceof Link) {
static::assertStringStartsWith(
'https',
$link->getLink(),
"In $elementName @link doesn't start with https"
);
if (getenv('CHECK_LINKS') === 'true') {
if ($element->stubBelongsToCore) {
$request = curl_init($link->getLink());
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_exec($request);
$response = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
curl_close($request);
static::assertTrue($response < 400);
}
}
}
}
foreach ($element->see as $see) {
if ($see instanceof See && $see->getReference() instanceof Url && strncmp($see, 'http', 4) === 0) {
static::assertStringStartsWith('https', $see, "In $elementName @see doesn't start with https");
}
}
}

private function checkDeprecatedRemovedSinceVersionsMajor(BasePHPElement $element, $elementName): void
{
/** @var PHPDocElement $element */
foreach ($element->sinceTags as $sinceTag) {
if ($sinceTag instanceof Since) {
$version = $sinceTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($sinceTag), "$elementName has
'since' version $version.'Since' version for PHP Core functionallity for style consistensy
should have X.X format for the case when patch version is '0'.");
}
}
}
foreach ($element->deprecatedTags as $deprecatedTag) {
if ($deprecatedTag instanceof Deprecated) {
$version = $deprecatedTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($deprecatedTag), "$elementName has
'deprecated' version $version.'Deprecated' version for PHP Core functionallity for style consistensy
should have X.X format for the case when patch version is '0'.");
}
}
}
foreach ($element->removedTags as $removedTag) {
if ($removedTag instanceof RemovedTag) {
$version = $removedTag->getVersion();
if ($version !== null) {
self::assertTrue(Utils::tagDoesNotHaveZeroPatchVersion($removedTag), "$elementName has
'removed' version $version.'Removed' version for PHP Core functionallity for style consistensy
should have X.X format for the case when patch version is '0'.");
}
}
}
}

private static function checkMethodDoesNotHaveScalarTypeHints(int $sinceVersion, PHPClass $parentClass, PHPFunction $function)
{
if ($sinceVersion < 7) {
Expand Down

0 comments on commit aa156ca

Please sign in to comment.