Prechádzať zdrojové kódy

employ ReflectionAttribute::IS_INSTANCEOF to also retrieve children of Header

Luke Kuzmish 1 rok pred
rodič
commit
889635aee5

+ 3 - 3
src/Extracting/Strategies/PhpAttributeStrategy.php

@@ -41,19 +41,19 @@ abstract class PhpAttributeStrategy extends Strategy
     protected function getAttributes(ReflectionFunctionAbstract $method, ?ReflectionClass $class = null): array
     {
         $attributesOnMethod = collect(static::$attributeNames)
-            ->flatMap(fn(string $name) => $method->getAttributes($name))
+            ->flatMap(fn(string $name) => $method->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF))
             ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all();
 
         // If there's a FormRequest, we check there.
         if ($formRequestClass = $this->getFormRequestReflectionClass($method)) {
             $attributesOnFormRequest = collect(static::$attributeNames)
-                ->flatMap(fn(string $name) => $formRequestClass->getAttributes($name))
+                ->flatMap(fn(string $name) => $formRequestClass->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF))
                 ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all();
         }
 
         if ($class) {
             $attributesOnController = collect(static::$attributeNames)
-                ->flatMap(fn(string $name) => $class->getAttributes($name))
+                ->flatMap(fn(string $name) => $class->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF))
                 ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all();
         }
 

+ 41 - 7
tests/Strategies/Headers/GetFromHeaderAttributeTest.php

@@ -2,6 +2,7 @@
 
 namespace Knuckles\Scribe\Tests\Strategies\Headers;
 
+use Attribute;
 use Knuckles\Camel\Extraction\ExtractedEndpointData;
 use Knuckles\Scribe\Attributes\Header;
 use Knuckles\Scribe\Extracting\Strategies\Headers\GetFromHeaderAttribute;
@@ -16,21 +17,39 @@ class GetFromHeaderAttributeTest extends TestCase
 
     /** @test */
     public function can_fetch_from_header_attribute()
+    {
+        $results = $this->getHeaderFromAttribute('methodWithAttributes');
+
+        $this->assertArraySubset([
+            'Api-Version' => 'v1',
+        ], $results);
+        $this->assertArrayHasKey('Some-Custom', $results);
+        $this->assertNotEmpty($results['Some-Custom']);
+    }
+
+    /** @test */
+    public function can_fetch_child_of_header_attribute()
+    {
+        $results = $this->getHeaderFromAttribute('methodWithCustomHeaderAttribute');
+
+        $this->assertArraySubset([
+            'Api-Version' => 'v1',
+        ], $results);
+        $this->assertArrayHasKey('hello', $results);
+        $this->assertEquals('world', $results['hello']);
+    }
+
+    private function getHeaderFromAttribute(string $methodName): array
     {
         $endpoint = new class extends ExtractedEndpointData {
             public function __construct(array $parameters = []) {}
         };
         $endpoint->controller = new ReflectionClass(\Knuckles\Scribe\Tests\Strategies\Headers\HeaderAttributeTestController::class);
-        $endpoint->method = $endpoint->controller->getMethod('methodWithAttributes');
+        $endpoint->method = $endpoint->controller->getMethod($methodName);
 
         $strategy = new GetFromHeaderAttribute(new DocumentationConfig([]));
-        $results = $strategy($endpoint);
 
-        $this->assertArraySubset([
-            'Api-Version' => 'v1',
-        ], $results);
-        $this->assertArrayHasKey('Some-Custom', $results);
-        $this->assertNotEmpty($results['Some-Custom']);
+        return $strategy($endpoint);
     }
 
 }
@@ -43,4 +62,19 @@ class HeaderAttributeTestController
     {
 
     }
+
+    #[CustomHeaderClass()]
+    public function methodWithCustomHeaderAttribute()
+    {
+
+    }
+}
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)]
+class CustomHeaderClass extends Header
+{
+    public function __construct()
+    {
+        parent::__construct('hello', 'world');
+    }
 }