From 678898efe73b30d22fc1a245f199d88b9058a4a2 Mon Sep 17 00:00:00 2001 From: Thai Nguyen Hung Date: Thu, 24 Aug 2023 14:26:54 +0700 Subject: [PATCH 1/3] feat: `toHaveAttribute` expectation --- src/Expectation.php | 15 +++++++++++++++ src/Expectations/OppositeExpectation.php | 15 +++++++++++++++ tests/Features/Expect/toHaveAttribute.php | 18 ++++++++++++++++++ .../ToHaveAttribute/Attributes/AsAttribute.php | 13 +++++++++++++ .../HaveAttribute/HaveAttributeClass.php | 13 +++++++++++++ .../NotHaveAttribute/NotHaveAttributeClass.php | 10 ++++++++++ 6 files changed, 84 insertions(+) create mode 100644 tests/Features/Expect/toHaveAttribute.php create mode 100644 tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php create mode 100644 tests/Fixtures/Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php create mode 100644 tests/Fixtures/Arch/ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php diff --git a/src/Expectation.php b/src/Expectation.php index aaa9b83e..1bc20abd 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -833,4 +833,19 @@ final class Expectation return $this; } + + /** + * Asserts that the given expectation target to have the given attribute. + * + * @param class-string $attribute + */ + public function toHaveAttribute(string $attribute): ArchExpectation + { + return Targeted::make( + $this, + fn (ObjectDescription $object): bool => $object->reflectionClass->getAttributes($attribute) !== [], + "to have attribute '{$attribute}'", + FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')), + ); + } } diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index e857009d..4953c1af 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -378,6 +378,21 @@ final class OppositeExpectation ); } + /** + * Asserts that the given expectation target not to have the given attribute. + * + * @param class-string $attribute + */ + public function toHaveAttribute(string $attribute): ArchExpectation + { + return Targeted::make( + $this->original, + fn (ObjectDescription $object): bool => $object->reflectionClass->getAttributes($attribute) === [], + "to not have attribute '{$attribute}'", + FileLineFinder::where(fn (string $line): bool => str_contains($line, 'class')) + ); + } + /** * Handle dynamic method calls into the original expectation. * diff --git a/tests/Features/Expect/toHaveAttribute.php b/tests/Features/Expect/toHaveAttribute.php new file mode 100644 index 00000000..6de6be72 --- /dev/null +++ b/tests/Features/Expect/toHaveAttribute.php @@ -0,0 +1,18 @@ +expect('Tests\\Fixtures\\Arch\\ToHaveAttribute\\HaveAttribute') + ->toHaveAttribute('Tests\\Fixtures\\Arch\\ToHaveAttribute\\Attributes\\AsAttribute'); + +test('opposite class has attribute') + ->throws(ArchExpectationFailedException::class) + ->expect('Tests\\Fixtures\\Arch\\ToHaveAttribute\\HaveAttribute') + ->not + ->toHaveAttribute('Tests\\Fixtures\\Arch\\ToHaveAttribute\\Attributes\\AsAttribute'); + +test('class not has attribute') + ->expect('Tests\\Fixtures\\Arch\\ToHaveAttribute\\NotHaveAttribute') + ->not + ->toHaveAttribute('Tests\\Fixtures\\Arch\\ToHaveAttribute\\Attributes\\AsAttribute'); diff --git a/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php b/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php new file mode 100644 index 00000000..d77a5bfe --- /dev/null +++ b/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php @@ -0,0 +1,13 @@ + Date: Thu, 24 Aug 2023 14:45:11 +0700 Subject: [PATCH 2/3] fix: pint --- tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php | 1 - .../Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php | 1 - .../ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php | 1 - 3 files changed, 3 deletions(-) diff --git a/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php b/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php index d77a5bfe..00b913bd 100644 --- a/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php +++ b/tests/Fixtures/Arch/ToHaveAttribute/Attributes/AsAttribute.php @@ -9,5 +9,4 @@ use Attribute; #[Attribute()] class AsAttribute { - } diff --git a/tests/Fixtures/Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php b/tests/Fixtures/Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php index 4ea090ca..49a0eb20 100644 --- a/tests/Fixtures/Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php +++ b/tests/Fixtures/Arch/ToHaveAttribute/HaveAttribute/HaveAttributeClass.php @@ -9,5 +9,4 @@ use Tests\Fixtures\Arch\ToHaveAttribute\Attributes\AsAttribute; #[AsAttribute] class HaveAttributeClass { - } diff --git a/tests/Fixtures/Arch/ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php b/tests/Fixtures/Arch/ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php index f57f5219..0628960c 100644 --- a/tests/Fixtures/Arch/ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php +++ b/tests/Fixtures/Arch/ToHaveAttribute/NotHaveAttribute/NotHaveAttributeClass.php @@ -6,5 +6,4 @@ namespace Tests\Fixtures\Arch\ToHaveAttribute\NotHaveAttribute; class NotHaveAttributeClass { - } From e69899559d544dabab4bea4554bae2865be3bb41 Mon Sep 17 00:00:00 2001 From: Thai Nguyen Hung Date: Thu, 24 Aug 2023 15:23:13 +0700 Subject: [PATCH 3/3] refactor: generic attribute --- src/Expectation.php | 3 ++- src/Expectations/OppositeExpectation.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Expectation.php b/src/Expectation.php index 1bc20abd..22f79122 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Pest; +use Attribute; use BadMethodCallException; use Closure; use InvalidArgumentException; @@ -837,7 +838,7 @@ final class Expectation /** * Asserts that the given expectation target to have the given attribute. * - * @param class-string $attribute + * @param class-string $attribute */ public function toHaveAttribute(string $attribute): ArchExpectation { diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 4953c1af..95aae090 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Pest\Expectations; +use Attribute; use Pest\Arch\Contracts\ArchExpectation; use Pest\Arch\Expectations\Targeted; use Pest\Arch\Expectations\ToBeUsedIn; @@ -381,7 +382,7 @@ final class OppositeExpectation /** * Asserts that the given expectation target not to have the given attribute. * - * @param class-string $attribute + * @param class-string $attribute */ public function toHaveAttribute(string $attribute): ArchExpectation {