/lib/Cake/TestSuite/Fixture/CakeFixtureManager.php

https://github.com/gustavor/lore · PHP · 253 lines · 147 code · 20 blank · 86 comment · 26 complexity · 7d5a1e5377de6424a4a9977eecbf64b7 MD5 · raw file

  1. <?php
  2. /**
  3. * A factory class to manage the life cycle of test fixtures
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  8. * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice.
  12. *
  13. * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://cakephp.org CakePHP(tm) Project
  15. * @package Cake.TestSuite.Fixture
  16. * @since CakePHP(tm) v 2.0
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
  20. App::uses('ConnectionManager', 'Model');
  21. App::uses('ClassRegistry', 'Utility');
  22. class CakeFixtureManager {
  23. /**
  24. * Was this class already initialized?
  25. *
  26. * @var boolean
  27. */
  28. protected $_initialized = false;
  29. /**
  30. * Default datasource to use
  31. *
  32. * @var DataSource
  33. */
  34. protected $_db = null;
  35. /**
  36. * Holds the fixture classes that where instantiated
  37. *
  38. * @var array
  39. */
  40. protected $_loaded = array();
  41. /**
  42. * Holds the fixture classes that where ins tantiated indexed by class name
  43. *
  44. * @var array
  45. */
  46. protected $_fixtureMap = array();
  47. /**
  48. * Inspects the test to look for unloaded fixtures and loads them
  49. *
  50. * @param CakeTestCase $test the test case to inspect
  51. * @return void
  52. */
  53. public function fixturize($test) {
  54. if (empty($test->fixtures) || !empty($this->_processed[get_class($test)])) {
  55. $test->db = $this->_db;
  56. return;
  57. }
  58. $this->_initDb();
  59. $test->db = $this->_db;
  60. if (!is_array($test->fixtures)) {
  61. $test->fixtures = array_map('trim', explode(',', $test->fixtures));
  62. }
  63. if (isset($test->fixtures)) {
  64. $this->_loadFixtures($test->fixtures);
  65. }
  66. $this->_processed[get_class($test)] = true;
  67. }
  68. /**
  69. * Initializes this class with a DataSource object to use as default for all fixtures
  70. *
  71. * @return void
  72. */
  73. protected function _initDb() {
  74. if ($this->_initialized) {
  75. return;
  76. }
  77. $db = ConnectionManager::getDataSource('test');
  78. $this->_db = $db;
  79. ClassRegistry::config(array('ds' => 'test'));
  80. $this->_initialized = true;
  81. }
  82. /**
  83. * Looks for fixture files and instantiates the classes accordingly
  84. *
  85. * @param array $fixtures the fixture names to load using the notation {type}.{name}
  86. * @return void
  87. */
  88. protected function _loadFixtures($fixtures) {
  89. foreach ($fixtures as $index => $fixture) {
  90. $fixtureFile = null;
  91. $fixtureIndex = $fixture;
  92. if (isset($this->_loaded[$fixture])) {
  93. continue;
  94. }
  95. if (strpos($fixture, 'core.') === 0) {
  96. $fixture = substr($fixture, strlen('core.'));
  97. $fixturePaths[] = CAKE . 'Test' . DS . 'Fixture';
  98. } elseif (strpos($fixture, 'app.') === 0) {
  99. $fixture = substr($fixture, strlen('app.'));
  100. $fixturePaths = array(
  101. TESTS . 'Fixture'
  102. );
  103. } elseif (strpos($fixture, 'plugin.') === 0) {
  104. $parts = explode('.', $fixture, 3);
  105. $pluginName = $parts[1];
  106. $fixture = $parts[2];
  107. $fixturePaths = array(
  108. CakePlugin::path(Inflector::camelize($pluginName)) . 'Test' . DS . 'Fixture',
  109. TESTS . 'Fixture'
  110. );
  111. } else {
  112. $fixturePaths = array(
  113. TESTS . 'Fixture',
  114. CAKE . 'Test' . DS . 'Fixture'
  115. );
  116. }
  117. foreach ($fixturePaths as $path) {
  118. $className = Inflector::camelize($fixture);
  119. if (is_readable($path . DS . $className . 'Fixture.php')) {
  120. $fixtureFile = $path . DS . $className . 'Fixture.php';
  121. require_once($fixtureFile);
  122. $fixtureClass = $className . 'Fixture';
  123. $this->_loaded[$fixtureIndex] = new $fixtureClass($this->_db);
  124. $this->_fixtureMap[$fixtureClass] = $this->_loaded[$fixtureIndex];
  125. break;
  126. }
  127. }
  128. }
  129. }
  130. /**
  131. * Runs the drop and create commands on the fixtures if necessary
  132. *
  133. * @param CakeTestFixture $fixture the fixture object to create
  134. * @param DataSource $db the datasource instance to use
  135. * @param boolean $drop whether drop the fixture if it is already created or not
  136. * @return void
  137. */
  138. protected function _setupTable($fixture, $db = null, $drop = true) {
  139. if (!$db) {
  140. $db = $this->_db;
  141. }
  142. if (!empty($fixture->created) && $fixture->created == $db->configKeyName) {
  143. return;
  144. }
  145. $cacheSources = $db->cacheSources;
  146. $db->cacheSources = false;
  147. $sources = $db->listSources();
  148. $db->cacheSources = $cacheSources;
  149. $table = $db->config['prefix'] . $fixture->table;
  150. if ($drop && in_array($table, $sources)) {
  151. $fixture->drop($db);
  152. $fixture->create($db);
  153. $fixture->created = $db->configKeyName;
  154. } elseif (!in_array($table, $sources)) {
  155. $fixture->create($db);
  156. $fixture->created = $db->configKeyName;
  157. }
  158. }
  159. /**
  160. * Crates the fixtures tables and inserts data on them
  161. *
  162. * @param CakeTestCase $test the test to inspect for fixture loading
  163. * @return void
  164. */
  165. public function load(CakeTestCase $test) {
  166. if (empty($test->fixtures)) {
  167. return;
  168. }
  169. $fixtures = $test->fixtures;
  170. if (empty($fixtures) || $test->autoFixtures == false) {
  171. return;
  172. }
  173. $test->db->begin();
  174. foreach ($fixtures as $f) {
  175. if (!empty($this->_loaded[$f])) {
  176. $fixture = $this->_loaded[$f];
  177. $this->_setupTable($fixture, $test->db, $test->dropTables);
  178. $fixture->insert($test->db);
  179. }
  180. }
  181. $test->db->commit();
  182. }
  183. /**
  184. * Trucantes the fixtures tables
  185. *
  186. * @param CakeTestCase $test the test to inspect for fixture unloading
  187. * @return void
  188. */
  189. public function unload(CakeTestCase $test) {
  190. $fixtures = !empty($test->fixtures) ? $test->fixtures : array();
  191. foreach (array_reverse($fixtures) as $f) {
  192. if (isset($this->_loaded[$f])) {
  193. $fixture = $this->_loaded[$f];
  194. if (!empty($fixture->created)) {
  195. $fixture->truncate($test->db);
  196. }
  197. }
  198. }
  199. }
  200. /**
  201. * Trucantes the fixtures tables
  202. *
  203. * @param CakeTestCase $test the test to inspect for fixture unloading
  204. * @return void
  205. * @throws UnexpectedValueException if $name is not a previously loaded class
  206. */
  207. public function loadSingle($name, $db = null) {
  208. $name .= 'Fixture';
  209. if (isset($this->_fixtureMap[$name])) {
  210. if (!$db) {
  211. $db = $this->_db;
  212. }
  213. $fixture = $this->_fixtureMap[$name];
  214. $this->_setupTable($fixture, $db);
  215. $fixture->truncate($db);
  216. $fixture->insert($db);
  217. } else {
  218. throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
  219. }
  220. }
  221. /**
  222. * Drop all fixture tables loaded by this class
  223. *
  224. * @return void
  225. */
  226. public function shutDown() {
  227. foreach ($this->_loaded as $fixture) {
  228. if (!empty($fixture->created)) {
  229. $fixture->drop($this->_db);
  230. }
  231. }
  232. }
  233. }