Skip to content

Commit 93fec0e

Browse files
authored
added attributes for standard labels and attribute sets support (fixes #33, via #58)
1 parent 387497c commit 93fec0e

39 files changed

+694
-72
lines changed

README.md

+53-2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,56 @@ In order to use this API you simply need to add the following to **composer.json
1919
}
2020
```
2121

22-
## Usage examples
23-
See [allure-phpunit](https://github.com/allure-framework/allure-phpunit) project.
22+
## Custom attributes
23+
You can easily implement custom attributes and use them with your test framework. In most cases you would like
24+
to implement [`Qameta\Allure\Attribute\AttributeSetInterface`](./src/Attribute/AttributeSetInterface.php) that allows to set several attributes at once:
25+
26+
```php
27+
<?php
28+
29+
use Qameta\Allure\Attribute\AttributeSetInterface;
30+
use Qameta\Allure\Attribute\DisplayName;
31+
use Qameta\Allure\Attribute\Tag;
32+
33+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
34+
class MyAttribute implements AttributeSetInterface
35+
{
36+
private array $tags;
37+
38+
public function __construct(
39+
private string $displayName,
40+
string ...$tags,
41+
) {
42+
$this->tags = $tags;
43+
}
44+
45+
public function getAttributes() : array
46+
{
47+
return [
48+
new DisplayName($this->displayName),
49+
...array_map(
50+
fn (string $tag): Tag => new Tag($tag),
51+
$this->tags,
52+
),
53+
];
54+
}
55+
}
56+
57+
// Example of usage
58+
#[MyAttribute('Test name', 'tag 1', 'tag 2')]
59+
class MyTestClass
60+
{
61+
}
62+
```
63+
64+
You can also implement particular attribute interfaces instead of using one of the standard implementations:
65+
66+
- [`Qameta\Allure\Attribute\DescriptionInterface`](./src/Attribute/DescriptionInterface.php)
67+
- [`Qameta\Allure\Attribute\DisplayNameInterface`](./src/Attribute/DisplayNameInterface.php)
68+
- [`Qameta\Allure\Attribute\LabelInterface`](./src/Attribute/LabelInterface.php)
69+
- [`Qameta\Allure\Attribute\LinkInterface`](./src/Attribute/LinkInterface.php)
70+
- [`Qameta\Allure\Attribute\ParameterInterface`](./src/Attribute/ParameterInterface.php)
71+
72+
## Other usage examples
73+
See [allure-phpunit](https://github.com/allure-framework/allure-phpunit)
74+
and [allure-codeception](https://github.com/allure-framework/allure-codeception) projects.

src/Allure.php

+5
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ public static function package(string $value): void
193193
self::getInstance()->doLabel(Label::package($value));
194194
}
195195

196+
public static function layer(string $value): void
197+
{
198+
self::getInstance()->doLabel(Label::layer($value));
199+
}
200+
196201
public static function label(string $name, string $value): void
197202
{
198203
self::getInstance()->doLabel(

src/Attribute/AttributeParser.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use ReflectionProperty;
1919

2020
use function array_merge;
21+
use function array_pop;
22+
use function array_push;
2123
use function array_reverse;
2224
use function is_string;
2325

@@ -107,7 +109,12 @@ public static function createForChain(
107109

108110
private function processAnnotations(AttributeInterface ...$attributes): void
109111
{
110-
foreach ($attributes as $attribute) {
112+
while (!empty($attributes)) {
113+
$attribute = array_shift($attributes);
114+
if ($attribute instanceof AttributeSetInterface) {
115+
array_unshift($attributes, ...$attribute->getAttributes());
116+
continue;
117+
}
111118
if ($attribute instanceof DisplayNameInterface) {
112119
$this->displayName = $attribute->getValue();
113120
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
interface AttributeSetInterface extends AttributeInterface
8+
{
9+
/**
10+
* @return list<AttributeInterface>
11+
*/
12+
public function getAttributes(): array;
13+
}

src/Attribute/Label.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ final class Label extends AbstractLabel
2121
public const TAG = Model\Label::TAG;
2222
public const OWNER = Model\Label::OWNER;
2323
public const LEAD = Model\Label::LEAD;
24+
public const PACKAGE = Model\Label::PACKAGE;
25+
public const LAYER = Model\Label::LAYER;
26+
27+
// Technical labels, set by framework automatically
2428
public const HOST = Model\Label::HOST;
2529
public const THREAD = Model\Label::THREAD;
2630
public const TEST_METHOD = Model\Label::TEST_METHOD;
2731
public const TEST_CLASS = Model\Label::TEST_CLASS;
28-
public const PACKAGE = Model\Label::PACKAGE;
2932
public const FRAMEWORK = Model\Label::FRAMEWORK;
3033
public const LANGUAGE = Model\Label::LANGUAGE;
3134
}

src/Attribute/Layer.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
10+
final class Layer extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::LAYER, $value);
15+
}
16+
}

src/Attribute/Lead.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class Lead extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::LEAD, $value);
15+
}
16+
}

src/Attribute/Owner.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class Owner extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::OWNER, $value);
15+
}
16+
}

src/Attribute/Package.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
10+
final class Package extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::PACKAGE, $value);
15+
}
16+
}

src/Attribute/ParentSuite.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class ParentSuite extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::PARENT_SUITE, $value);
15+
}
16+
}

src/Attribute/SubSuite.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class SubSuite extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::SUB_SUITE, $value);
15+
}
16+
}

src/Attribute/Suite.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class Suite extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::SUITE, $value);
15+
}
16+
}

src/Attribute/Tag.php

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Qameta\Allure\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
10+
final class Tag extends AbstractLabel
11+
{
12+
public function __construct(string $value)
13+
{
14+
parent::__construct(Label::TAG, $value);
15+
}
16+
}

src/Legacy/Annotation/AllureId.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
namespace Yandex\Allure\Adapter\Annotation;
66

77
use Doctrine\Common\Annotations\Annotation\Required;
8-
use Qameta\Allure\Attribute\AllureId as QametaAllureId;
8+
use Qameta\Allure\Attribute;
99
use Qameta\Allure\Legacy\Annotation\LegacyAnnotationInterface;
1010

1111
/**
1212
* @Annotation
1313
* @Target({"METHOD"})
14-
* @deprecated Use native PHP attribute {@see \Qameta\Allure\Attribute\AllureId}
14+
* @deprecated Use native PHP attribute {@see Attribute\AllureId}
1515
* @psalm-suppress MissingConstructor
1616
*/
1717
class AllureId implements LegacyAnnotationInterface
@@ -22,8 +22,8 @@ class AllureId implements LegacyAnnotationInterface
2222
*/
2323
public string $value;
2424

25-
public function convert(): QametaAllureId
25+
public function convert(): Attribute\AllureId
2626
{
27-
return new QametaAllureId($this->value);
27+
return new Attribute\AllureId($this->value);
2828
}
2929
}

src/Legacy/Annotation/Description.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
namespace Yandex\Allure\Adapter\Annotation;
66

77
use Doctrine\Common\Annotations\Annotation\Required;
8-
use Qameta\Allure\Attribute\Description as QametaDescription;
8+
use Qameta\Allure\Attribute;
99
use Qameta\Allure\Legacy\Annotation\LegacyAnnotationInterface;
1010
use Yandex\Allure\Adapter\Model\DescriptionType;
1111

1212
/**
1313
* @Annotation
1414
* @Target({"CLASS", "METHOD"})
15-
* @deprecated Use native PHP attribute {@see \Qameta\Allure\Attribute\Description}
15+
* @deprecated Use native PHP attribute {@see Attribute\Description}
1616
* @psalm-suppress MissingConstructor
1717
*/
1818
class Description implements LegacyAnnotationInterface
@@ -29,10 +29,10 @@ class Description implements LegacyAnnotationInterface
2929
*/
3030
public string $type = DescriptionType::TEXT;
3131

32-
public function convert(): QametaDescription
32+
public function convert(): Attribute\Description
3333
{
3434
/** @psalm-suppress DeprecatedClass */
35-
return new QametaDescription(
35+
return new Attribute\Description(
3636
$this->value,
3737
DescriptionType::HTML == $this->type,
3838
);

src/Legacy/Annotation/Epics.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
namespace Yandex\Allure\Adapter\Annotation;
66

77
use Doctrine\Common\Annotations\Annotation\Required;
8-
use Qameta\Allure\Attribute\Epic;
8+
use Qameta\Allure\Attribute;
99
use Qameta\Allure\Legacy\Annotation\LegacyAnnotationInterface;
1010

1111
use function array_map;
1212

1313
/**
1414
* @Annotation
1515
* @Target({"CLASS", "METHOD"})
16-
* @deprecated Use native PHP attribute {@see \Qameta\Allure\Annotation\Epics}
16+
* @deprecated Use native PHP attribute {@see Attribute\Epic}
1717
* @psalm-suppress MissingConstructor
1818
*/
1919
class Epics implements LegacyAnnotationInterface
@@ -33,12 +33,12 @@ public function getEpicNames(): array
3333
}
3434

3535
/**
36-
* @return list<Epic>
36+
* @return list<Attribute\Epic>
3737
*/
3838
public function convert(): array
3939
{
4040
return array_map(
41-
fn (string $name) => new Epic($name),
41+
fn (string $name) => new Attribute\Epic($name),
4242
$this->epicNames,
4343
);
4444
}

src/Legacy/Annotation/Features.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
namespace Yandex\Allure\Adapter\Annotation;
66

77
use Doctrine\Common\Annotations\Annotation\Required;
8-
use Qameta\Allure\Attribute\Feature;
8+
use Qameta\Allure\Attribute;
99
use Qameta\Allure\Legacy\Annotation\LegacyAnnotationInterface;
1010

1111
use function array_map;
1212

1313
/**
1414
* @Annotation
1515
* @Target({"CLASS", "METHOD"})
16-
* @deprecated Use native PHP attribute {@see \Qameta\Allure\Annotation\Features}
16+
* @deprecated Use native PHP attribute {@see Attribute\Features}
1717
* @psalm-suppress MissingConstructor
1818
*/
1919
class Features implements LegacyAnnotationInterface
@@ -30,12 +30,12 @@ public function getFeatureNames(): array
3030
}
3131

3232
/**
33-
* @return list<Feature>
33+
* @return list<Attribute\Feature>
3434
*/
3535
public function convert(): array
3636
{
3737
return array_map(
38-
fn (string $name) => new Feature($name),
38+
fn (string $name) => new Attribute\Feature($name),
3939
$this->featureNames,
4040
);
4141
}

0 commit comments

Comments
 (0)