diff --git a/src/Allure.php b/src/Allure.php index 2098f6e..79705af 100644 --- a/src/Allure.php +++ b/src/Allure.php @@ -209,16 +209,6 @@ public static function package(string $value): void self::getInstance()->doLabel(Label::package($value)); } - public static function framework(string $value): void - { - self::getInstance()->doLabel(Label::framework($value)); - } - - public static function language(string $value): void - { - self::getInstance()->doLabel(Label::language($value)); - } - public static function label(string $name, string $value): void { self::getInstance()->doLabel( @@ -247,12 +237,12 @@ public static function parameter( ); } - public static function issue(string $name, string $url): void + public static function issue(string $name, ?string $url = null): void { self::getInstance()->doLink(Link::issue($name, $url)); } - public static function tms(string $name, string $url): void + public static function tms(string $name, ?string $url = null): void { self::getInstance()->doLink(Link::tms($name, $url)); } @@ -268,6 +258,13 @@ public static function link(string $url, ?string $name = null, ?LinkType $type = ); } + public static function displayName(string $name): void + { + self::getLifecycle()->updateExecutionContext( + fn (ExecutionContextInterface $context) => $context->setName($name), + ); + } + public static function description(string $description): void { self::getLifecycle()->updateExecutionContext( @@ -376,7 +373,7 @@ private function doRunStep(callable $callable, ?string $name = null): mixed $parser = $this->readCallableAttributes($callable); $this->doGetLifecycle()->updateStep( fn (StepResult $s): StepResult => $s - ->setName($name ?? $parser->getTitle() ?? $this->defaultStepName) + ->setName($name ?? $parser->getDisplayName() ?? $this->defaultStepName) ->addParameters(...$parser->getParameters()), $step->getUuid(), ); diff --git a/src/Attribute/AbstractTitle.php b/src/Attribute/AbstractDisplayName.php similarity index 77% rename from src/Attribute/AbstractTitle.php rename to src/Attribute/AbstractDisplayName.php index 95bfd6f..10fafce 100644 --- a/src/Attribute/AbstractTitle.php +++ b/src/Attribute/AbstractDisplayName.php @@ -4,7 +4,7 @@ namespace Qameta\Allure\Attribute; -abstract class AbstractTitle implements TitleInterface +abstract class AbstractDisplayName implements DisplayNameInterface { public function __construct(private string $value) { diff --git a/src/Attribute/AttributeParser.php b/src/Attribute/AttributeParser.php index 6456d1f..eaca048 100644 --- a/src/Attribute/AttributeParser.php +++ b/src/Attribute/AttributeParser.php @@ -4,12 +4,24 @@ 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 ReflectionClass; +use ReflectionException; +use ReflectionFunction; +use ReflectionMethod; +use ReflectionProperty; -class AttributeParser +use function array_merge; +use function is_string; + +class AttributeParser implements ModelProviderInterface { - private ?string $title = null; + private ?string $displayName = null; private ?string $description = null; @@ -41,11 +53,59 @@ public function __construct( $this->processAnnotations(...$attributes); } + /** + * @param class-string|object|null $classOrObject + * @param callable-string|Closure|null $methodOrFunction + * @param string|null $property + * @param array $linkTemplates + * @return list + * @throws ReflectionException + */ + public static function createForChain( + string|object|null $classOrObject, + string|Closure|null $methodOrFunction = null, + ?string $property = null, + array $linkTemplates = [], + ): 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, + ) + ]; + } + private function processAnnotations(AttributeInterface ...$attributes): void { foreach ($attributes as $attribute) { - if ($attribute instanceof TitleInterface) { - $this->title = $attribute->getValue(); + if ($attribute instanceof DisplayNameInterface) { + $this->displayName = $attribute->getValue(); } if ($attribute instanceof DescriptionInterface) { if ($attribute->isHtml()) { @@ -126,9 +186,17 @@ public function getParameters(): array return $this->parameters; } + /** + * @deprecated Please use {@see getDisplayName()} method. + */ public function getTitle(): ?string { - return $this->title; + return $this->getDisplayName(); + } + + public function getDisplayName(): ?string + { + return $this->displayName; } public function getDescription(): ?string diff --git a/src/Attribute/DisplayName.php b/src/Attribute/DisplayName.php new file mode 100644 index 0000000..401ddfa --- /dev/null +++ b/src/Attribute/DisplayName.php @@ -0,0 +1,12 @@ +methodName); + if (is_object($this->methodName)) { + $methodDescription .= '(' . $this->methodName::class . ')'; + } + + parent::__construct("Invalid method name: <$methodDescription>", 0, $previous); + } + + public function getMethodName(): mixed + { + return $this->methodName; + } +} diff --git a/src/Legacy/Annotation/Title.php b/src/Legacy/Annotation/Title.php index af5f240..9017fe8 100644 --- a/src/Legacy/Annotation/Title.php +++ b/src/Legacy/Annotation/Title.php @@ -5,13 +5,13 @@ namespace Yandex\Allure\Adapter\Annotation; use Doctrine\Common\Annotations\Annotation\Required; -use Qameta\Allure\Attribute\Title as QametaTitle; +use Qameta\Allure\Attribute\DisplayName as QametaDisplayName; use Qameta\Allure\Legacy\Annotation\LegacyAnnotationInterface; /** * @Annotation * @Target({"CLASS", "METHOD"}) - * @deprecated Use native PHP attribute {@see \Qameta\Allure\Attribute\Title} + * @deprecated Use native PHP attribute {@see \Qameta\Allure\Attribute\DisplayName} * @psalm-suppress MissingConstructor */ class Title implements LegacyAnnotationInterface @@ -21,8 +21,8 @@ class Title implements LegacyAnnotationInterface */ public string $value; - public function convert(): QametaTitle + public function convert(): QametaDisplayName { - return new QametaTitle($this->value); + return new QametaDisplayName($this->value); } } diff --git a/src/Model/Label.php b/src/Model/Label.php index 98fecd2..5cd0aaa 100644 --- a/src/Model/Label.php +++ b/src/Model/Label.php @@ -6,6 +6,10 @@ use JsonSerializable; +use function preg_match; + +use const PHP_VERSION; + final class Label implements JsonSerializable { use JsonSerializableTrait; @@ -175,10 +179,19 @@ public static function language(?string $value): self { return new self( name: self::LANGUAGE, - value: $value, + value: $value ?? self::buildPhpVersion(), ); } + private static function buildPhpVersion(): string + { + $version = 1 === preg_match('#^\d+\.\d+#', PHP_VERSION, $matches) + ? $matches[0] + : '?.?'; + + return "PHP $version"; + } + public function getName(): ?string { return $this->name; diff --git a/src/Model/ModelProviderChain.php b/src/Model/ModelProviderChain.php new file mode 100644 index 0000000..4f0615b --- /dev/null +++ b/src/Model/ModelProviderChain.php @@ -0,0 +1,103 @@ + + */ + private array $providers; + + public function __construct(ModelProviderInterface ...$providers) + { + $this->providers = array_values($providers); + } + + /** + * @return list + */ + public function getLinks(): array + { + return array_merge( + ...array_map( + /** @psalm-return list */ + fn (ModelProviderInterface $p): array => $p->getLinks(), + $this->providers, + ), + ); + } + + /** + * @return list