| Current Path : /home/rtorresani/www/vendor/allure-framework/allure-php-commons/src/Attribute/ |
| Current File : //home/rtorresani/www/vendor/allure-framework/allure-php-commons/src/Attribute/AttributeParser.php |
<?php
declare(strict_types=1);
namespace Qameta\Allure\Attribute;
use Closure;
use Doctrine\Common\Annotations\AnnotationReader;
use Qameta\Allure\Exception\InvalidMethodNameException;
use Qameta\Allure\Model;
use Qameta\Allure\Model\ModelProviderInterface;
use Qameta\Allure\Setup\LinkTemplateCollection;
use Qameta\Allure\Setup\LinkTemplateCollectionInterface;
use ReflectionClass;
use ReflectionException;
use ReflectionFunction;
use ReflectionMethod;
use ReflectionProperty;
use function array_merge;
use function array_pop;
use function array_push;
use function array_reverse;
use function is_string;
final class AttributeParser implements ModelProviderInterface
{
use Model\ModelProviderTrait;
private ?string $displayName = null;
private ?string $description = null;
private ?string $descriptionHtml = null;
/**
* @var list<Model\Label>
*/
private array $labels = [];
/**
* @var list<Model\Link>
*/
private array $links = [];
/**
* @var list<Model\Parameter>
*/
private array $parameters = [];
/**
* @param array<AttributeInterface> $attributes
* @param LinkTemplateCollectionInterface $linkTemplates
*/
public function __construct(
array $attributes,
private LinkTemplateCollectionInterface $linkTemplates,
) {
$this->processAnnotations(...$attributes);
}
/**
* @param class-string|object|null $classOrObject
* @param callable-string|Closure|null $methodOrFunction
* @param string|null $property
* @param LinkTemplateCollectionInterface|null $linkTemplates
* @return list<ModelProviderInterface>
* @throws ReflectionException
*/
public static function createForChain(
string|object|null $classOrObject,
string|Closure|null $methodOrFunction = null,
?string $property = null,
?LinkTemplateCollectionInterface $linkTemplates = null,
): array {
$reader = new LegacyAttributeReader(
new AnnotationReader(),
new AttributeReader(),
);
$annotations = [];
if (isset($classOrObject)) {
$annotations[] = $reader->getClassAnnotations(new ReflectionClass($classOrObject));
if (isset($property)) {
$annotations[] = $reader->getPropertyAnnotations(new ReflectionProperty($classOrObject, $property));
}
}
if (isset($methodOrFunction)) {
$annotations[] = isset($classOrObject)
? $reader->getMethodAnnotations(
new ReflectionMethod(
$classOrObject,
is_string($methodOrFunction)
? $methodOrFunction
: throw new InvalidMethodNameException($methodOrFunction),
),
)
: $reader->getFunctionAnnotations(new ReflectionFunction($methodOrFunction));
}
return [
new self(
array_merge(...$annotations),
$linkTemplates ?? new LinkTemplateCollection(),
)
];
}
private function processAnnotations(AttributeInterface ...$attributes): void
{
while (!empty($attributes)) {
$attribute = array_shift($attributes);
if ($attribute instanceof AttributeSetInterface) {
array_unshift($attributes, ...$attribute->getAttributes());
continue;
}
if ($attribute instanceof DisplayNameInterface) {
$this->displayName = $attribute->getValue();
}
if ($attribute instanceof DescriptionInterface) {
if ($attribute->isHtml()) {
$this->descriptionHtml = $attribute->getValue();
} else {
$this->description = $attribute->getValue();
}
}
if ($attribute instanceof LinkInterface) {
$this->links[] = $this->createLink($attribute);
}
if ($attribute instanceof LabelInterface) {
$this->labels[] = $this->createLabel($attribute);
}
if ($attribute instanceof ParameterInterface) {
$this->parameters[] = $this->createParameter($attribute);
}
}
}
private function createLink(LinkInterface $link): Model\Link
{
$linkType = Model\LinkType::fromOptionalString($link->getType());
return new Model\Link(
name: $link->getName(),
url: $link->getUrl() ?? $this->linkTemplates->get($linkType)?->buildUrl($link->getName()),
type: $linkType,
);
}
/**
* @return list<Model\Link>
*/
public function getLinks(): array
{
return $this->links;
}
private function createLabel(LabelInterface $label): Model\Label
{
return new Model\Label(
name: $label->getName(),
value: $label->getValue(),
);
}
/**
* @return list<Model\Label>
*/
public function getLabels(): array
{
return array_reverse($this->labels);
}
private function createParameter(ParameterInterface $parameter): Model\Parameter
{
return new Model\Parameter(
name: $parameter->getName(),
value: $parameter->getValue(),
excluded: $parameter->getExcluded(),
mode: Model\ParameterMode::fromOptionalString($parameter->getMode()),
);
}
/**
* @return list<Model\Parameter>
*/
public function getParameters(): array
{
return $this->parameters;
}
public function getDisplayName(): ?string
{
return $this->displayName;
}
public function getDescription(): ?string
{
return $this->description;
}
public function getDescriptionHtml(): ?string
{
return $this->descriptionHtml;
}
}