PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Cake/TestSuite/Fixture/CakeTestFixture.php

https://gitlab.com/manuperazafa/elsartenbackend
PHP | 328 lines | 193 code | 29 blank | 106 comment | 35 complexity | 5e23d428167a7677df2cdc31e8b33fe3 MD5 | raw file
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  12. * @package Cake.TestSuite.Fixture
  13. * @since CakePHP(tm) v 1.2.0.4667
  14. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  15. */
  16. App::uses('CakeSchema', 'Model');
  17. /**
  18. * CakeTestFixture is responsible for building and destroying tables to be used
  19. * during testing.
  20. *
  21. * @package Cake.TestSuite.Fixture
  22. */
  23. class CakeTestFixture {
  24. /**
  25. * Name of the object
  26. *
  27. * @var string
  28. */
  29. public $name = null;
  30. /**
  31. * CakePHP's DBO driver (e.g: DboMysql).
  32. *
  33. * @var object
  34. */
  35. public $db = null;
  36. /**
  37. * Fixture Datasource
  38. *
  39. * @var string
  40. */
  41. public $useDbConfig = 'test';
  42. /**
  43. * Full Table Name
  44. *
  45. * @var string
  46. */
  47. public $table = null;
  48. /**
  49. * List of datasources where this fixture has been created
  50. *
  51. * @var array
  52. */
  53. public $created = array();
  54. /**
  55. * Fields / Schema for the fixture.
  56. * This array should match the output of Model::schema()
  57. *
  58. * @var array
  59. */
  60. public $fields = array();
  61. /**
  62. * Fixture records to be inserted.
  63. *
  64. * @var array
  65. */
  66. public $records = array();
  67. /**
  68. * The primary key for the table this fixture represents.
  69. *
  70. * @var string
  71. */
  72. public $primaryKey = null;
  73. /**
  74. * Fixture data can be stored in memory by default.
  75. * When table is created for a fixture the MEMORY engine is used
  76. * where possible. Set $canUseMemory to false if you don't want this.
  77. *
  78. * @var bool
  79. */
  80. public $canUseMemory = true;
  81. /**
  82. * Instantiate the fixture.
  83. *
  84. * @throws CakeException on invalid datasource usage.
  85. */
  86. public function __construct() {
  87. if ($this->name === null) {
  88. if (preg_match('/^(.*)Fixture$/', get_class($this), $matches)) {
  89. $this->name = $matches[1];
  90. } else {
  91. $this->name = get_class($this);
  92. }
  93. }
  94. $connection = 'test';
  95. if (!empty($this->useDbConfig)) {
  96. $connection = $this->useDbConfig;
  97. if (strpos($connection, 'test') !== 0) {
  98. $message = __d(
  99. 'cake_dev',
  100. 'Invalid datasource name "%s" for "%s" fixture. Fixture datasource names must begin with "test".',
  101. $connection,
  102. $this->name
  103. );
  104. throw new CakeException($message);
  105. }
  106. }
  107. $this->Schema = new CakeSchema(array('name' => 'TestSuite', 'connection' => $connection));
  108. $this->init();
  109. }
  110. /**
  111. * Initialize the fixture.
  112. *
  113. * @return void
  114. * @throws MissingModelException Whe importing from a model that does not exist.
  115. */
  116. public function init() {
  117. if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
  118. $import = array_merge(
  119. array('connection' => 'default', 'records' => false),
  120. is_array($this->import) ? $this->import : array('model' => $this->import)
  121. );
  122. $this->Schema->connection = $import['connection'];
  123. if (isset($import['model'])) {
  124. list($plugin, $modelClass) = pluginSplit($import['model'], true);
  125. App::uses($modelClass, $plugin . 'Model');
  126. if (!class_exists($modelClass)) {
  127. throw new MissingModelException(array('class' => $modelClass));
  128. }
  129. $model = new $modelClass(null, null, $import['connection']);
  130. $db = $model->getDataSource();
  131. if (empty($model->tablePrefix)) {
  132. $model->tablePrefix = $db->config['prefix'];
  133. }
  134. $this->fields = $model->schema(true);
  135. $this->fields[$model->primaryKey]['key'] = 'primary';
  136. $this->table = $db->fullTableName($model, false, false);
  137. $this->primaryKey = $model->primaryKey;
  138. ClassRegistry::config(array('ds' => 'test'));
  139. ClassRegistry::flush();
  140. } elseif (isset($import['table'])) {
  141. $model = new Model(null, $import['table'], $import['connection']);
  142. $db = ConnectionManager::getDataSource($import['connection']);
  143. $db->cacheSources = false;
  144. $model->useDbConfig = $import['connection'];
  145. $model->name = Inflector::camelize(Inflector::singularize($import['table']));
  146. $model->table = $import['table'];
  147. $model->tablePrefix = $db->config['prefix'];
  148. $this->fields = $model->schema(true);
  149. $this->primaryKey = $model->primaryKey;
  150. ClassRegistry::flush();
  151. }
  152. if (!empty($db->config['prefix']) && strpos($this->table, $db->config['prefix']) === 0) {
  153. $this->table = str_replace($db->config['prefix'], '', $this->table);
  154. }
  155. if (isset($import['records']) && $import['records'] !== false && isset($model) && isset($db)) {
  156. $this->records = array();
  157. $query = array(
  158. 'fields' => $db->fields($model, null, array_keys($this->fields)),
  159. 'table' => $db->fullTableName($model),
  160. 'alias' => $model->alias,
  161. 'conditions' => array(),
  162. 'order' => null,
  163. 'limit' => null,
  164. 'group' => null
  165. );
  166. $records = $db->fetchAll($db->buildStatement($query, $model), false, $model->alias);
  167. if ($records !== false && !empty($records)) {
  168. $this->records = Hash::extract($records, '{n}.' . $model->alias);
  169. }
  170. }
  171. }
  172. if (!isset($this->table)) {
  173. $this->table = Inflector::underscore(Inflector::pluralize($this->name));
  174. }
  175. if (!isset($this->primaryKey) && isset($this->fields['id'])) {
  176. $this->primaryKey = 'id';
  177. }
  178. }
  179. /**
  180. * Run before all tests execute, should return SQL statement to create table for this fixture could be executed successfully.
  181. *
  182. * @param DboSource $db An instance of the database object used to create the fixture table
  183. * @return bool True on success, false on failure
  184. */
  185. public function create($db) {
  186. if (!isset($this->fields) || empty($this->fields)) {
  187. return false;
  188. }
  189. if (empty($this->fields['tableParameters']['engine'])) {
  190. $canUseMemory = $this->canUseMemory;
  191. foreach ($this->fields as $args) {
  192. if (is_string($args)) {
  193. $type = $args;
  194. } elseif (!empty($args['type'])) {
  195. $type = $args['type'];
  196. } else {
  197. continue;
  198. }
  199. if (in_array($type, array('blob', 'text', 'binary'))) {
  200. $canUseMemory = false;
  201. break;
  202. }
  203. }
  204. if ($canUseMemory) {
  205. $this->fields['tableParameters']['engine'] = 'MEMORY';
  206. }
  207. }
  208. $this->Schema->build(array($this->table => $this->fields));
  209. try {
  210. $db->execute($db->createSchema($this->Schema), array('log' => false));
  211. $this->created[] = $db->configKeyName;
  212. } catch (Exception $e) {
  213. $msg = __d(
  214. 'cake_dev',
  215. 'Fixture creation for "%s" failed "%s"',
  216. $this->table,
  217. $e->getMessage()
  218. );
  219. CakeLog::error($msg);
  220. trigger_error($msg, E_USER_WARNING);
  221. return false;
  222. }
  223. return true;
  224. }
  225. /**
  226. * Run after all tests executed, should return SQL statement to drop table for this fixture.
  227. *
  228. * @param DboSource $db An instance of the database object used to create the fixture table
  229. * @return bool True on success, false on failure
  230. */
  231. public function drop($db) {
  232. if (empty($this->fields)) {
  233. return false;
  234. }
  235. $this->Schema->build(array($this->table => $this->fields));
  236. try {
  237. $db->execute($db->dropSchema($this->Schema), array('log' => false));
  238. $this->created = array_diff($this->created, array($db->configKeyName));
  239. } catch (Exception $e) {
  240. return false;
  241. }
  242. return true;
  243. }
  244. /**
  245. * Run before each tests is executed, should return a set of SQL statements to insert records for the table
  246. * of this fixture could be executed successfully.
  247. *
  248. * @param DboSource $db An instance of the database into which the records will be inserted
  249. * @return bool on success or if there are no records to insert, or false on failure
  250. * @throws CakeException if counts of values and fields do not match.
  251. */
  252. public function insert($db) {
  253. if (!isset($this->_insert)) {
  254. $values = array();
  255. if (isset($this->records) && !empty($this->records)) {
  256. $fields = array();
  257. foreach ($this->records as $record) {
  258. $fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields)));
  259. }
  260. $fields = array_unique($fields);
  261. $default = array_fill_keys($fields, null);
  262. foreach ($this->records as $record) {
  263. $merge = array_values(array_merge($default, $record));
  264. if (count($fields) !== count($merge)) {
  265. throw new CakeException('Fixture invalid: Count of fields does not match count of values in ' . get_class($this));
  266. }
  267. $values[] = $merge;
  268. }
  269. $nested = $db->useNestedTransactions;
  270. $db->useNestedTransactions = false;
  271. $result = $db->insertMulti($this->table, $fields, $values);
  272. if (
  273. $this->primaryKey &&
  274. isset($this->fields[$this->primaryKey]['type']) &&
  275. in_array($this->fields[$this->primaryKey]['type'], array('integer', 'biginteger'))
  276. ) {
  277. $db->resetSequence($this->table, $this->primaryKey);
  278. }
  279. $db->useNestedTransactions = $nested;
  280. return $result;
  281. }
  282. return true;
  283. }
  284. }
  285. /**
  286. * Truncates the current fixture. Can be overwritten by classes extending
  287. * CakeFixture to trigger other events before / after truncate.
  288. *
  289. * @param DboSource $db A reference to a db instance
  290. * @return bool
  291. */
  292. public function truncate($db) {
  293. $fullDebug = $db->fullDebug;
  294. $db->fullDebug = false;
  295. $return = $db->truncate($this->table);
  296. $db->fullDebug = $fullDebug;
  297. return $return;
  298. }
  299. }