Browse Source

Merge pull request #17407 from cakephp/5.x-enum-type

Improve enum type checking.
Mark Story 2 years ago
parent
commit
4e7789e665
2 changed files with 38 additions and 3 deletions
  1. 15 3
      src/Database/Type/EnumType.php
  2. 23 0
      tests/TestCase/Database/Type/EnumTypeTest.php

+ 15 - 3
src/Database/Type/EnumType.php

@@ -57,14 +57,26 @@ class EnumType extends BaseType
     ) {
         parent::__construct($name);
         $this->enumClassName = $enumClassName;
+
         try {
             $reflectionEnum = new ReflectionEnum($enumClassName);
-            $this->backingType = (string)$reflectionEnum->getBackingType();
-        } catch (ReflectionException) {
+        } catch (ReflectionException $e) {
+            throw new DatabaseException(sprintf(
+                'Unable to use `%s` for type `%s`. %s.',
+                $enumClassName,
+                $name,
+                $e->getMessage()
+            ));
+        }
+
+        $namedType = $reflectionEnum->getBackingType();
+        if ($namedType == null) {
             throw new DatabaseException(
-                sprintf('Unable to use enum %s for type %s, must be a backed enum.', $enumClassName, $name)
+                sprintf('Unable to use enum `%s` for type `%s`, must be a backed enum.', $enumClassName, $name)
             );
         }
+
+        $this->backingType = (string)$namedType;
     }
 
     /**

+ 23 - 0
tests/TestCase/Database/Type/EnumTypeTest.php

@@ -25,6 +25,7 @@ use InvalidArgumentException;
 use PDO;
 use TestApp\Model\Entity\Article;
 use TestApp\Model\Enum\ArticleStatus;
+use TestApp\Model\Enum\NonBacked;
 use TestApp\Model\Enum\Priority;
 use ValueError;
 
@@ -105,10 +106,32 @@ class EnumTypeTest extends TestCase
     public function testInvalidEnumClass(): void
     {
         $this->expectException(DatabaseException::class);
+        $this->expectExceptionMessage('Unable to use `TestApp\Model\Entity\Article` for type `invalid`. Class "TestApp\Model\Entity\Article" is not an enum');
         new EnumType('invalid', Article::class);
     }
 
     /**
+     * Check that 2nd argument must be a valid backed enum
+     */
+    public function testInvalidEnumInvalidClass(): void
+    {
+        $this->expectException(DatabaseException::class);
+        $this->expectExceptionMessage('Unable to use `App\Foo` for type `invalid`. Class "App\Foo" does not exist');
+        new EnumType('invalid', 'App\Foo');
+    }
+
+    /**
+     * Check that 2nd argument must be a valid backed enum
+     */
+    public function testInvalidEnumWithoutBackingType(): void
+    {
+        $this->expectException(DatabaseException::class);
+        $this->expectExceptionMessage('Unable to use enum `TestApp\Model\Enum\NonBacked` for type `invalid`, must be a backed enum');
+
+        new EnumType('invalid', NonBacked::class);
+    }
+
+    /**
      * Check get enum class string
      */
     public function testGetEnumClassString(): void