PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

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

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