From 03d99ecfbd27b3ea434b92719fdbe4eb4b0173bb Mon Sep 17 00:00:00 2001 From: Charles Sprayberry Date: Wed, 8 Jun 2022 08:22:51 -0400 Subject: [PATCH] Add support for attributes on interfaces (#9) --- CHANGELOG.md | 6 +++ .../FooInterface.php | 10 ++++ ...assOnlyAttributeSingleInterfaceFixture.php | 17 +++++++ fixture_src/Fixtures.php | 4 ++ src/PhpParserAnnotatedTargetParser.php | 4 +- .../Unit/ClassOnlyInterfaceAttributeTest.php | 47 +++++++++++++++++++ 6 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 fixture_src/ClassOnlyAttributeSingleInterface/FooInterface.php create mode 100644 fixture_src/ClassOnlyAttributeSingleInterfaceFixture.php create mode 100644 tests/Unit/ClassOnlyInterfaceAttributeTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a89a93..e04303e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.1.1](https://github.com/cspray/annotated-target/tree/v0.1.1) - 2022-06-08 + +### Fixed + +- Fixed a bug where Attributes on interfaces were not properly parsed. + ## [0.1.0](https://github.com/cspray/annotated-target/tree/v0.1.0) - 2022-06-08 ### Added diff --git a/fixture_src/ClassOnlyAttributeSingleInterface/FooInterface.php b/fixture_src/ClassOnlyAttributeSingleInterface/FooInterface.php new file mode 100644 index 0000000..2bde518 --- /dev/null +++ b/fixture_src/ClassOnlyAttributeSingleInterface/FooInterface.php @@ -0,0 +1,10 @@ +filteredAttributes) && !in_array($attrType, $this->filteredAttributes)) { continue; } - if ($node instanceof Node\Stmt\Class_) { + if ($node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Interface_) { ($this->consumer)($this->getAnnotatedTargetFromClassNode($node, $index)); } else if ($node instanceof Node\Stmt\Property) { foreach ($node->props as $prop) { @@ -106,7 +106,7 @@ public function leaveNode(Node $node) { } } - private function getAnnotatedTargetFromClassNode(Node\Stmt\Class_ $class, int $index) : AnnotatedTarget { + private function getAnnotatedTargetFromClassNode(Node\Stmt\Class_|Node\Stmt\Interface_ $class, int $index) : AnnotatedTarget { $classType = $class->namespacedName->toString(); return $this->getAnnotatedTarget(fn() => new ReflectionClass($classType), $index); } diff --git a/tests/Unit/ClassOnlyInterfaceAttributeTest.php b/tests/Unit/ClassOnlyInterfaceAttributeTest.php new file mode 100644 index 0000000..d74bb0c --- /dev/null +++ b/tests/Unit/ClassOnlyInterfaceAttributeTest.php @@ -0,0 +1,47 @@ +withFixtures(Fixtures::classOnlyAttributeSingleInterface()); + +it('counts parsed targets for single class') + ->expect(fn() => $this->getTargets()) + ->toHaveCount(1); + +it('ensures all targets are correct type') + ->expect(fn() => $this->getTargets()) + ->toContainOnlyAnnotatedTargets(); + +it('ensures all targets share target reflection') + ->expect(fn() => $this->getTargets()) + ->toShareTargetReflection(); + +it('ensures all targets share attribute reflection') + ->expect(fn() => $this->getTargets()) + ->toShareAttributeReflection(); + +it('ensures all targets share attribute instance') + ->expect(fn() => $this->getTargets()) + ->toShareAttributeInstance(); + +it('includes target reflection class') + ->expect(fn() => $this->getTargets()) + ->toContainTargetClass(Fixtures::classOnlyAttributeSingleInterface()->fooInterface()); + +it('includes attribute reflection class') + ->expect(fn() => $this->getTargets()) + ->toContainTargetClassWithAttribute(Fixtures::classOnlyAttributeSingleInterface()->fooInterface(), objectType(ClassOnly::class)); + +it('includes attribute instance with correct value') + ->expect(fn() => $this->getTargets()) + ->toContainTargetClassWithAttributeInstance( + Fixtures::classOnlyAttributeSingleInterface()->fooInterface(), + objectType(ClassOnly::class), + fn(ClassOnly $classOnly) => $classOnly->value === 'foo' + ); \ No newline at end of file