Browse Source

Validate argument types.

ADmad 5 years ago
parent
commit
85d3a7e0a1

+ 8 - 0
src/Datasource/FactoryLocator.php

@@ -40,6 +40,14 @@ class FactoryLocator
      */
     public static function add(string $type, $factory): void
     {
+        if (!$factory instanceof LocatorInterface && !is_callable($factory)) {
+            throw new InvalidArgumentException(sprintf(
+                '`$factory` must be an instance of Cake\Datasource\LocatorInterface or a callable.'
+                . ' Got type `%s` instead.',
+                getTypeName($factory)
+            ));
+        }
+
         static::$_modelFactories[$type] = $factory;
     }
 

+ 9 - 0
src/Datasource/ModelAwareTrait.php

@@ -17,6 +17,7 @@ declare(strict_types=1);
 namespace Cake\Datasource;
 
 use Cake\Datasource\Exception\MissingModelException;
+use InvalidArgumentException;
 use UnexpectedValueException;
 
 /**
@@ -138,6 +139,14 @@ trait ModelAwareTrait
      */
     public function modelFactory(string $type, $factory): void
     {
+        if (!$factory instanceof LocatorInterface && !is_callable($factory)) {
+            throw new InvalidArgumentException(sprintf(
+                '`$factory` must be an instance of Cake\Datasource\LocatorInterface or a callable.'
+                . ' Got type `%s` instead.',
+                getTypeName($factory)
+            ));
+        }
+
         $this->_modelFactories[$type] = $factory;
     }
 

+ 12 - 0
tests/TestCase/Datasource/FactoryLocatorTest.php

@@ -18,6 +18,7 @@ namespace Cake\Test\TestCase\Datasource;
 use Cake\Datasource\FactoryLocator;
 use Cake\Datasource\LocatorInterface;
 use Cake\TestSuite\TestCase;
+use InvalidArgumentException;
 
 /**
  * FactoryLocatorTest test case
@@ -67,6 +68,17 @@ class FactoryLocatorTest extends TestCase
         $this->assertInstanceOf(LocatorInterface::class, FactoryLocator::get('MyType'));
     }
 
+    public function testFactoryAddException()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage(
+            '`$factory` must be an instance of Cake\Datasource\LocatorInterface or a callable.'
+            . ' Got type `string` instead.'
+        );
+
+        FactoryLocator::add('Test', 'fail');
+    }
+
     /**
      * test drop()
      *

+ 13 - 0
tests/TestCase/Datasource/ModelAwareTraitTest.php

@@ -19,6 +19,7 @@ use Cake\Datasource\FactoryLocator;
 use Cake\Datasource\LocatorInterface;
 use Cake\Datasource\RepositoryInterface;
 use Cake\TestSuite\TestCase;
+use InvalidArgumentException;
 use TestApp\Model\Table\PaginatorPostsTable;
 use TestApp\Stub\Stub;
 
@@ -142,6 +143,18 @@ class ModelAwareTraitTest extends TestCase
         $this->assertSame('Foo', $stub->Foo->alias);
     }
 
+    public function testModelFactoryException()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage(
+            '`$factory` must be an instance of Cake\Datasource\LocatorInterface or a callable.'
+            . ' Got type `string` instead.'
+        );
+
+        $stub = new Stub();
+        $stub->modelFactory('MyType', 'fail');
+    }
+
     /**
      * test getModelType() and setModelType()
      *