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\PHPUnitView 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 |