Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. CoversHelper.php

class CoversHelper

Hierarchy

  • class \PHPStan\Rules\PHPUnit\CoversHelper

Expanded class hierarchy of CoversHelper

File

vendor/phpstan/phpstan-phpunit/src/Rules/PHPUnit/CoversHelper.php, line 17

Namespace

PHPStan\Rules\PHPUnit
View source
class CoversHelper {
    
    /**
     * Reflection provider.
     *
     * @var ReflectionProvider
     */
    private $reflectionProvider;
    public function __construct(ReflectionProvider $reflectionProvider) {
        $this->reflectionProvider = $reflectionProvider;
    }
    
    /**
     * Gathers @covers and @coversDefaultClass annotations from phpdocs.
     *
     * @return array{PhpDocTagNode[], PhpDocTagNode[]}
     */
    public function getCoverAnnotations(?ResolvedPhpDocBlock $phpDoc) : array {
        if ($phpDoc === null) {
            return [
                [],
                [],
            ];
        }
        $phpDocNodes = $phpDoc->getPhpDocNodes();
        $covers = [];
        $coversDefaultClasses = [];
        foreach ($phpDocNodes as $docNode) {
            $covers = array_merge($covers, $docNode->getTagsByName('@covers'));
            $coversDefaultClasses = array_merge($coversDefaultClasses, $docNode->getTagsByName('@coversDefaultClass'));
        }
        return [
            $covers,
            $coversDefaultClasses,
        ];
    }
    
    /**
     * @return list<IdentifierRuleError> errors
     */
    public function processCovers(Node $node, PhpDocTagNode $phpDocTag, ?PhpDocTagNode $coversDefaultClass) : array {
        $errors = [];
        $covers = (string) $phpDocTag->value;
        if ($covers === '') {
            $errors[] = RuleErrorBuilder::message('@covers value does not specify anything.')->identifier('phpunit.covers')
                ->build();
            return $errors;
        }
        $isMethod = strpos($covers, '::') !== false;
        $fullName = $covers;
        if ($isMethod) {
            [
                $className,
                $method,
            ] = explode('::', $covers);
        }
        else {
            $className = $covers;
        }
        if ($className === '' && $node instanceof Node\Stmt\ClassMethod && $coversDefaultClass !== null) {
            $className = (string) $coversDefaultClass->value;
            $fullName = $className . $covers;
        }
        if ($this->reflectionProvider
            ->hasClass($className)) {
            $class = $this->reflectionProvider
                ->getClass($className);
            if ($class->isInterface()) {
                $errors[] = RuleErrorBuilder::message(sprintf('@covers value %s references an interface.', $fullName))->identifier('phpunit.coversInterface')
                    ->build();
            }
            if (isset($method) && $method !== '' && !$class->hasMethod($method)) {
                $errors[] = RuleErrorBuilder::message(sprintf('@covers value %s references an invalid method.', $fullName))->identifier('phpunit.coversMethod')
                    ->build();
            }
        }
        elseif (isset($method) && $this->reflectionProvider
            ->hasFunction(new Name($method, []), null)) {
            return $errors;
        }
        elseif (!isset($method) && $this->reflectionProvider
            ->hasFunction(new Name($className, []), null)) {
            return $errors;
        }
        else {
            $error = RuleErrorBuilder::message(sprintf('@covers value %s references an invalid %s.', $fullName, $isMethod ? 'method' : 'class or function'))->identifier(sprintf('phpunit.covers%s', $isMethod ? 'Method' : ''));
            if (strpos($className, '\\') === false) {
                $error->tip('The @covers annotation requires a fully qualified name.');
            }
            $errors[] = $error->build();
        }
        return $errors;
    }

}

Members

Title Sort descending Modifiers Object type Summary
CoversHelper::$reflectionProvider private property * Reflection provider.
*
*
CoversHelper::getCoverAnnotations public function * Gathers @covers and @coversDefaultClass annotations from phpdocs.
*
*
CoversHelper::processCovers public function *
CoversHelper::__construct public function
RSS feed
Powered by Drupal