Browse Source

Add support for defining Groups and Subgroups as enums (#932)

* add support for enum groups

* wording

---------

Co-authored-by: Shalvah <shalvah@users.noreply.github.com>
James 3 months ago
parent
commit
9f01a1a1a0

+ 17 - 2
src/Attributes/Group.php

@@ -8,17 +8,32 @@ use Attribute;
 class Group
 {
     public function __construct(
-        public string $name,
+        public mixed $name,
         public ?string $description = '',
         /** You can use the separate #[Authenticated] attribute, or pass authenticated: false to this. */
         public ?bool   $authenticated = null,
     ){
     }
 
+    protected function getName(): string
+    {
+        if (is_string($this->name)) {
+            return $this->name;
+        }
+
+        if (interface_exists('BackedEnum') && is_a($this->name, 'BackedEnum')) {
+            return $this->name->value;
+        }
+
+        throw new \InvalidArgumentException(
+            'The name property of a group must be either a PHP Backed Enum or a string'
+        );
+    }
+
     public function toArray()
     {
         $data = [
-            "groupName" => $this->name,
+            "groupName" => $this->getName(),
             "groupDescription" => $this->description,
         ];
 

+ 17 - 2
src/Attributes/Subgroup.php

@@ -8,15 +8,30 @@ use Attribute;
 class Subgroup
 {
     public function __construct(
-        public string $name,
+        public mixed $name,
         public ?string $description = '',
     ){
     }
 
+    protected function getName(): string
+    {
+        if (is_string($this->name)) {
+            return $this->name;
+        }
+
+        if (interface_exists('BackedEnum') && is_a($this->name, 'BackedEnum')) {
+            return $this->name->value;
+        }
+
+        throw new \InvalidArgumentException(
+            'The name property of a subgroup must be either a PHP Backed Enum or a string'
+        );
+    }
+
     public function toArray()
     {
         return [
-            "subgroup" => $this->name,
+            "subgroup" => $this->getName(),
             "subgroupDescription" => $this->description,
         ];
     }

+ 9 - 0
tests/Fixtures/TestGroupBackedEnum.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+enum TestGroupBackedEnum: string
+{
+    case Users = 'Users';
+    case Admins = 'Admins';
+}

+ 23 - 0
tests/Strategies/Metadata/GetFromMetadataAttributesTest.php

@@ -10,6 +10,7 @@ use Knuckles\Scribe\Attributes\Group;
 use Knuckles\Scribe\Attributes\Subgroup;
 use Knuckles\Scribe\Attributes\Unauthenticated;
 use Knuckles\Scribe\Extracting\Strategies\Metadata\GetFromMetadataAttributes;
+use Knuckles\Scribe\Tests\Fixtures\TestGroupBackedEnum;
 use Knuckles\Scribe\Tools\DocumentationConfig;
 use PHPUnit\Framework\TestCase;
 use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
@@ -84,6 +85,21 @@ class UseMetadataAttributesTest extends TestCase
             "authenticated" => false,
         ], $results);
 
+        $endpoint = $this->endpoint(function (ExtractedEndpointData $e) {
+            $e->controller = new ReflectionClass(MetadataAttributesTestController::class);
+            $e->method = $e->controller->getMethod('b2');
+        });
+        $results = $this->fetch($endpoint);
+        $this->assertArraySubset([
+            "groupName" => "Users",
+            "groupDescription" => "",
+            "subgroup" => "Admins",
+            "subgroupDescription" => "",
+            "title" => "Endpoint B2",
+            "description" => "",
+            "authenticated" => false,
+        ], $results);
+
         $endpoint = $this->endpoint(function (ExtractedEndpointData $e) {
             $e->controller = new ReflectionClass(MetadataAttributesTestController2::class);
             $e->method = $e->controller->getMethod('c1');
@@ -159,6 +175,13 @@ class MetadataAttributesTestController
     public function b1()
     {
     }
+
+    #[Group(TestGroupBackedEnum::Users)]
+    #[Subgroup(TestGroupBackedEnum::Admins)]
+    #[Endpoint("Endpoint B2")]
+    public function b2()
+    {
+    }
 }
 
 #[Authenticated]