<?php namespace Doctrine\Tests; /** * Base testcase class for all orm testcases. * * @since 2.0 */ class OrmFunctionalTestCase extends OrmTestCase { /* The metadata cache shared between all functional tests. */ private static $_metadataCacheImpl = null; /** The EntityManager for this testcase. */ protected $_em; /** * The currently loaded model names of the fixtures for the testcase. */ private $_loadedFixtures = array(); /** * All loaded fixtures during test execution. Common fixture cache. */ private static $_fixtures = array(); /** * The names of all tables that were already exported. Each table is exported * only once. Then it's just filled & erased for each testmethod in a testcase * that uses one or more fixtures. */ private static $_exportedTables = array(); /** * Loads a data fixture into the database. This method must only be called * from within the setUp() method of testcases. The database will then be * populated with fresh data of all loaded fixtures for each test method. * * WARNING: A single testcase should never load fixtures from different scenarios of * the same package as the concistency and uniqueness of keys is not guaranteed. * * @param string $package The package name. Must be one of Doctrine's test model packages * (forum, cms or ecommerce). * @param string $scenario The fixture scenario. A model package can have many fixture * scenarios. Within a scenario all primary keys and foreign keys * of fixtures are consistent and unique. * @param string $name The name of the fixture to load from the specified package. */ protected function loadFixture($package, $scenario, $name) { $uniqueName = $package . '/' . $scenario . '/' . $name; if ( ! isset(self::$_fixtures[$uniqueName])) { // load fixture file $fixtureFile = 'fixtures' . DIRECTORY_SEPARATOR . $package . DIRECTORY_SEPARATOR . $scenario . DIRECTORY_SEPARATOR . $name . '.php'; require $fixtureFile; self::$_fixtures[$uniqueName] = $fixture; } $fixture = self::$_fixtures[$uniqueName]; $this->_loadedFixtures[] = $fixture['table']; $conn = $this->sharedFixture['conn']; $tableName = $fixture['table']; if ( ! in_array($tableName, self::$_exportedTables)) { $conn->getSchemaManager()->exportClasses(array($fixture['model'])); self::$_exportedTables[] = $tableName; } foreach ($fixture['rows'] as $row) { $conn->insert($tableName, $row); } } /** * Loads multiple fixtures of the same package and scenario. * This method must only be called from within the setUp() method of testcases. * The database will then be populated with fresh data of all loaded fixtures for each * test method. * * WARNING: A single testcase should never load fixtures from different scenarios of * the same package as the concistency and uniqueness of keys is not guaranteed. * * @param string $package The package name. Must be one of Doctrine's test model packages * (forum, cms or ecommerce). * @param string $scenario The fixture scenario. A model package can have many fixture * scenarios. Within a scenario all primary keys and foreign keys * of fixtures are consistent and unique. * @param array $names The names of the fixtures to load from the specified package. */ protected function loadFixtures($package, $scenario, array $names) { foreach ($names as $name) { $this->loadFixture($package, $scenario, $name); } } /** * Sweeps the database tables of all used fixtures and clears the EntityManager. */ protected function tearDown() { $conn = $this->sharedFixture['conn']; foreach (array_reverse($this->_loadedFixtures) as $table) { $conn->exec("DELETE FROM " . $table); } $this->_em->clear(); } protected function setUp() { if ( ! isset($this->sharedFixture['conn'])) { echo PHP_EOL . " --- CREATE CONNECTION ----" . PHP_EOL; $this->sharedFixture['conn'] = TestUtil::getConnection(); } if ( ! $this->_em) { $this->_em = $this->_getEntityManager(); } } protected function _getEntityManager($config = null, $eventManager = null) { // NOTE: Functional tests use their own shared metadata cache, because // the actual database platform used during execution has effect on some // metadata mapping behaviors (like the choice of the ID generation). if (is_null(self::$_metadataCacheImpl)) { self::$_metadataCacheImpl = new \Doctrine\ORM\Cache\ArrayCache; } $config = new \Doctrine\ORM\Configuration(); $config->setMetadataCacheImpl(self::$_metadataCacheImpl); $eventManager = new \Doctrine\Common\EventManager(); $conn = $this->sharedFixture['conn']; return \Doctrine\ORM\EntityManager::create($conn, 'em', $config, $eventManager); } }