Browse Source

Fixing bug In ConnectionManager::config() when passing an object instance

When passing an already constructed instance to ConnectionManager::config(),
it was cloning the object instead of storing the same object instance in
the registry. This made impossible inject mocked connection objects into the manager.

Additionally, made the ConnectionRegistry also accept a callable, responsible for
returning an already built connection instance. This brings the config() method
in line with how the Log class works.
Jose Lorenzo Rodriguez 10 years ago
parent
commit
21be0b5b8e

+ 12 - 1
src/Datasource/ConnectionRegistry.php

@@ -65,13 +65,24 @@ class ConnectionRegistry extends ObjectRegistry
      *
      * Part of the template method for Cake\Core\ObjectRegistry::load()
      *
-     * @param string|object $class The classname or object to make.
+     * If a callable is passed as first argument, The returned value of this
+     * function will be the result of the callable.
+     *
+     * @param string|object|callable $class The classname or object to make.
      * @param string $alias The alias of the object.
      * @param array $settings An array of settings to use for the driver.
      * @return object A connection with the correct settings.
      */
     protected function _create($class, $alias, $settings)
     {
+        if (is_callable($class)) {
+            return $class($alias);
+        }
+
+        if (is_object($class)) {
+            return $class;
+        }
+
         unset($settings['className']);
         return new $class($settings);
     }

+ 1 - 1
src/Log/LogEngineRegistry.php

@@ -71,7 +71,7 @@ class LogEngineRegistry extends ObjectRegistry
     protected function _create($class, $alias, $settings)
     {
         if (is_callable($class)) {
-            $class = $class();
+            $class = $class($alias);
         }
 
         if (is_object($class)) {

+ 30 - 0
tests/TestCase/Datasource/ConnectionManagerTest.php

@@ -250,4 +250,34 @@ class ConnectionManagerTest extends TestCase
         ];
         $this->assertEquals($expected, $result);
     }
+
+    /**
+     * Tests that directly setting an instance in a config, will not return a different
+     * instance later on
+     *
+     * @return void
+     */
+    public function testConfigWithObject()
+    {
+        $connection = new FakeConnection;
+        ConnectionManager::config('test_variant', $connection);
+        $this->assertSame($connection, ConnectionManager::get('test_variant'));
+    }
+
+    /**
+     * Tests configuring an instance with a callable
+     *
+     * @return void
+     */
+    public function testConfigWithCallable()
+    {
+        $connection = new FakeConnection;
+        $callable = function ($alias) use ($connection) {
+            $this->assertEquals('test_variant', $alias);
+            return $connection;
+        };
+
+        ConnectionManager::config('test_variant', $callable);
+        $this->assertSame($connection, ConnectionManager::get('test_variant'));
+    }
 }

+ 2 - 1
tests/TestCase/Log/LogTest.php

@@ -618,7 +618,8 @@ class LogTest extends TestCase
     public function testCreateLoggerWithCallable()
     {
         $instance = new FileLog;
-        Log::config('default', function () use ($instance) {
+        Log::config('default', function ($alias) use ($instance) {
+            $this->assertEquals('default', $alias);
             return $instance;
         });
         $this->assertSame($instance, Log::engine('default'));