Skip to content

Commit

Permalink
Extract an interface for Fixtures and Connections.
Browse files Browse the repository at this point in the history
Extract a basic interface for fixtures and a very tiny one for
connections. The connection interface will be expanded once we
understand it a bit better. For now it is a marker interface.
  • Loading branch information
markstory committed Apr 12, 2015
1 parent 53fbde2 commit cefc37f
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 43 deletions.
3 changes: 2 additions & 1 deletion src/Database/Connection.php
Expand Up @@ -14,6 +14,7 @@
*/
namespace Cake\Database;

use Cake\Datasource\ConnectionInterface;
use Cake\Database\Exception\MissingConnectionException;
use Cake\Database\Exception\MissingDriverException;
use Cake\Database\Exception\MissingExtensionException;
Expand All @@ -28,7 +29,7 @@
/**
* Represents a connection with a database server.
*/
class Connection
class Connection implements ConnectionInterface
{

use TypeConverterTrait;
Expand Down
24 changes: 24 additions & 0 deletions src/Datasource/ConnectionInterface.php
@@ -0,0 +1,24 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.1.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Datasource;

/**
* This interface defines the methods you can depend on in
* a connection.
*/
interface ConnectionInterface
{

}
71 changes: 71 additions & 0 deletions src/Datasource/FixtureInterface.php
@@ -0,0 +1,71 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.1.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Datasource;

use Cake\Datasource\ConnectionInterface;

/**
* Defines the interface that testing fixtures use.
*/
interface FixtureInterface
{
/**
* Create the fixture schema/mapping/definition
*
* @param Connection $db An instance of the connection the fixture should be created on.
* @return bool True on success, false on failure.
*/
public function create(ConnectionInterface $db);

/**
* Run after all tests executed, should remove the table/collection from the connection.
*
* @param Connection $db An instance of the connection the fixture should be removed from.
* @return bool True on success, false on failure.
*/
public function drop(ConnectionInterface $db);

/**
* Run before each test is executed.
*
* Should insert all the records into the test database.
*
* @param Connection $db An instance of the connection into which the records will be inserted.
* @return bool on success or if there are no records to insert, or false on failure.
*/
public function insert(ConnectionInterface $db);

/**
* Truncates the current fixture.
*
* @param Connection $db A reference to a db instance
* @return bool
*/
public function truncate(ConnectionInterface $db);

/**
* Get the connection name this fixture should be inserted into.
*
* @return string
*/
public function connection();

/**
* Get the table/collection name for this fixture.
*
* @return string
*/
public function sourceName();
}
47 changes: 37 additions & 10 deletions src/TestSuite/Fixture/FixtureManager.php
Expand Up @@ -49,6 +49,13 @@ class FixtureManager
*/
protected $_fixtureMap = [];

/**
* A map of connection names and the fixture currently in it.
*
* @var array
*/
protected $_insertionMap = [];

/**
* Inspects the test to look for unloaded fixtures and loads them
*
Expand Down Expand Up @@ -193,11 +200,12 @@ protected function _loadFixtures($test)
*/
protected function _setupTable($fixture, $db, array $sources, $drop = true)
{
if (!empty($fixture->created) && in_array($db->configName(), $fixture->created)) {
$configName = $db->configName();
if ($this->isFixtureSetup($configName, $fixture)) {
return;
}

$table = $fixture->table;
$table = $fixture->sourceName();
$exists = in_array($table, $sources);

if ($drop && $exists) {
Expand All @@ -206,7 +214,7 @@ protected function _setupTable($fixture, $db, array $sources, $drop = true)
} elseif (!$exists) {
$fixture->create($db);
} else {
$fixture->created[] = $db->configName();
$this->_insertionMap[$configName][] = $fixture;
$fixture->truncate($db);
}
}
Expand All @@ -232,8 +240,12 @@ public function load($test)
try {
$createTables = function ($db, $fixtures) use ($test) {
$tables = $db->schemaCollection()->listTables();
$configName = $db->configName();
if (!isset($this->_insertionMap[$configName])) {
$this->_insertionMap[$configName] = [];
}
foreach ($fixtures as $fixture) {
if (!in_array($db->configName(), (array)$fixture->created)) {
if (!in_array($fixture, $this->_insertionMap[$configName])) {
$this->_setupTable($fixture, $db, $tables, $test->dropTables);
} else {
$fixture->truncate($db);
Expand Down Expand Up @@ -294,7 +306,7 @@ protected function _fixtureConnections($fixtures)
foreach ($fixtures as $f) {
if (!empty($this->_loaded[$f])) {
$fixture = $this->_loaded[$f];
$dbs[$fixture->connection][$f] = $fixture;
$dbs[$fixture->connection()][$f] = $fixture;
}
}
return $dbs;
Expand All @@ -312,9 +324,9 @@ public function unload($test)
return;
}
$truncate = function ($db, $fixtures) {
$connection = $db->configName();
$configName = $db->configName();
foreach ($fixtures as $fixture) {
if (!empty($fixture->created) && in_array($connection, $fixture->created)) {
if ($this->isFixtureSetup($configName, $fixture)) {
$fixture->truncate($db);
}
}
Expand All @@ -336,10 +348,10 @@ public function loadSingle($name, $db = null, $dropTables = true)
if (isset($this->_fixtureMap[$name])) {
$fixture = $this->_fixtureMap[$name];
if (!$db) {
$db = ConnectionManager::get($fixture->connection);
$db = ConnectionManager::get($fixture->connection());
}

if (!in_array($db->configName(), (array)$fixture->created)) {
if (!$this->isFixtureSetup($db->configName(), $fixture)) {
$sources = $db->schemaCollection()->listTables();
$this->_setupTable($fixture, $db, $sources, $dropTables);
}
Expand All @@ -362,11 +374,26 @@ public function shutDown()
$shutdown = function ($db, $fixtures) {
$connection = $db->configName();
foreach ($fixtures as $fixture) {
if (!empty($fixture->created) && in_array($connection, $fixture->created)) {
if ($this->isFixtureSetup($connection, $fixture)) {
$fixture->drop($db);
$index = array_search($fixture, $this->_insertionMap[$connection]);
unset($this->_insertionMap[$connection][$index]);
}
}
};
$this->_runOperation(array_keys($this->_loaded), $shutdown);
}

/**
* Check whether or not a fixture has been inserted in a given connection name.
*
* @param string $connection The connection name.
* @param \Cake\Datasource\FixtureInterface $fixture The fixture to check.
* @return bool
*/
public function isFixtureSetup($connection, $fixture)
{
return isset($this->_insertionMap[$connection]) && in_array($fixture, $this->_insertionMap[$connection]);
}

}
59 changes: 27 additions & 32 deletions src/TestSuite/Fixture/TestFixture.php
Expand Up @@ -14,17 +14,18 @@
namespace Cake\TestSuite\Fixture;

use Cake\Core\Exception\Exception;
use Cake\Database\Connection;
use Cake\Datasource\ConnectionInterface;
use Cake\Database\Schema\Table;
use Cake\Datasource\ConnectionManager;
use Cake\Datasource\FixtureInterface;
use Cake\Log\Log;
use Cake\Utility\Inflector;

/**
* Cake TestFixture is responsible for building and destroying tables to be used
* during testing.
*/
class TestFixture
class TestFixture implements FixtureInterface
{

/**
Expand All @@ -41,13 +42,6 @@ class TestFixture
*/
public $table = null;

/**
* List of datasources where this fixture has been created
*
* @var array
*/
public $created = [];

/**
* Fields / Schema for the fixture.
*
Expand Down Expand Up @@ -105,6 +99,22 @@ public function __construct()
$this->init();
}

/**
* {@inheritDoc}
*/
public function connection()
{
return $this->connection;
}

/**
* {@inheritDoc}
*/
public function sourceName()
{
return $this->table;
}

/**
* Initialize the fixture.
*
Expand Down Expand Up @@ -205,12 +215,9 @@ public function schema(Table $schema = null)
}

/**
* Run before all tests execute, should return SQL statement to create table for this fixture could be executed successfully.
*
* @param Connection $db An instance of the database object used to create the fixture table
* @return bool True on success, false on failure
* {@inheritDoc}
*/
public function create(Connection $db)
public function create(ConnectionInterface $db)
{
if (empty($this->_schema)) {
return false;
Expand All @@ -236,12 +243,9 @@ public function create(Connection $db)
}

/**
* Run after all tests executed, should return SQL statement to drop table for this fixture.
*
* @param Connection $db An instance of the database object used to create the fixture table
* @return bool True on success, false on failure
* {@inheritDoc}
*/
public function drop(Connection $db)
public function drop(ConnectionInterface $db)
{
if (empty($this->_schema)) {
return false;
Expand All @@ -251,21 +255,16 @@ public function drop(Connection $db)
foreach ($sql as $stmt) {
$db->execute($stmt)->closeCursor();
}
$this->created = array_diff($this->created, [$db->configName()]);
} catch (\Exception $e) {
return false;
}
return true;
}

/**
* Run before each tests is executed, should return a set of SQL statements to insert records for the table
* of this fixture could be executed successfully.
*
* @param Connection $db An instance of the database into which the records will be inserted
* @return bool on success or if there are no records to insert, or false on failure
* {@inheritDoc}
*/
public function insert(Connection $db)
public function insert(ConnectionInterface $db)
{
if (isset($this->records) && !empty($this->records)) {
list($fields, $values, $types) = $this->_getRecords();
Expand Down Expand Up @@ -308,13 +307,9 @@ protected function _getRecords()
}

/**
* Truncates the current fixture. Can be overwritten by classes extending
* CakeFixture to trigger other events before / after truncate.
*
* @param Connection $db A reference to a db instance
* @return bool
* {@inheritDoc}
*/
public function truncate(Connection $db)
public function truncate(ConnectionInterface $db)
{
$sql = $this->_schema->truncateSql($db);
foreach ($sql as $stmt) {
Expand Down

0 comments on commit cefc37f

Please sign in to comment.