BaseTestCaseORM.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. namespace Tool;
  3. use Gedmo\Tool\Logging\DBAL\QueryAnalyzer;
  4. use Doctrine\Common\Annotations\AnnotationReader;
  5. use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
  6. use Doctrine\ORM\EntityManager;
  7. use Doctrine\Common\EventManager;
  8. use Doctrine\ORM\Tools\SchemaTool;
  9. use Doctrine\ORM\Configuration;
  10. use Gedmo\Translatable\TranslatableListener;
  11. use Gedmo\Sluggable\SluggableListener;
  12. use Gedmo\Tree\TreeListener;
  13. use Gedmo\Timestampable\TimestampableListener;
  14. use Gedmo\Loggable\LoggableListener;
  15. use Gedmo\SoftDeleteable\SoftDeleteableListener;
  16. /**
  17. * Base test case contains common mock objects
  18. * and functionality among all extensions using
  19. * ORM object manager
  20. *
  21. * @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
  22. * @package Gedmo
  23. * @subpackage BaseTestCase
  24. * @link http://www.gediminasm.org
  25. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  26. */
  27. abstract class BaseTestCaseORM extends \PHPUnit_Framework_TestCase
  28. {
  29. /**
  30. * @var EntityManager
  31. */
  32. protected $em;
  33. /**
  34. * @var QueryAnalyzer
  35. */
  36. protected $queryAnalyzer;
  37. /**
  38. * {@inheritdoc}
  39. */
  40. protected function setUp()
  41. {
  42. }
  43. /**
  44. * EntityManager mock object together with
  45. * annotation mapping driver and pdo_sqlite
  46. * database in memory
  47. *
  48. * @param EventManager $evm
  49. * @return EntityManager
  50. */
  51. protected function getMockSqliteEntityManager(EventManager $evm = null, Configuration $config = null)
  52. {
  53. $conn = array(
  54. 'driver' => 'pdo_sqlite',
  55. 'memory' => true,
  56. );
  57. $config = null === $config ? $this->getMockAnnotatedConfig() : $config;
  58. $em = EntityManager::create($conn, $config, $evm ?: $this->getEventManager());
  59. $schema = array_map(function($class) use ($em) {
  60. return $em->getClassMetadata($class);
  61. }, (array)$this->getUsedEntityFixtures());
  62. $schemaTool = new SchemaTool($em);
  63. $schemaTool->dropSchema(array());
  64. $schemaTool->createSchema($schema);
  65. return $this->em = $em;
  66. }
  67. /**
  68. * EntityManager mock object together with
  69. * annotation mapping driver and custom
  70. * connection
  71. *
  72. * @param array $conn
  73. * @param EventManager $evm
  74. * @return EntityManager
  75. */
  76. protected function getMockCustomEntityManager(array $conn, EventManager $evm = null)
  77. {
  78. $config = $this->getMockAnnotatedConfig();
  79. $em = EntityManager::create($conn, $config, $evm ?: $this->getEventManager());
  80. $schema = array_map(function($class) use ($em) {
  81. return $em->getClassMetadata($class);
  82. }, (array)$this->getUsedEntityFixtures());
  83. $schemaTool = new SchemaTool($em);
  84. $schemaTool->dropSchema(array());
  85. $schemaTool->createSchema($schema);
  86. return $this->em = $em;
  87. }
  88. /**
  89. * EntityManager mock object with
  90. * annotation mapping driver
  91. *
  92. * @param EventManager $evm
  93. * @return EntityManager
  94. */
  95. protected function getMockMappedEntityManager(EventManager $evm = null)
  96. {
  97. $driver = $this->getMock('Doctrine\DBAL\Driver');
  98. $driver->expects($this->once())
  99. ->method('getDatabasePlatform')
  100. ->will($this->returnValue($this->getMock('Doctrine\DBAL\Platforms\MySqlPlatform')));
  101. $conn = $this->getMock('Doctrine\DBAL\Connection', array(), array(array(), $driver));
  102. $conn->expects($this->once())
  103. ->method('getEventManager')
  104. ->will($this->returnValue($evm ?: $this->getEventManager()));
  105. $config = $this->getMockAnnotatedConfig();
  106. $this->em = EntityManager::create($conn, $config);
  107. return $this->em;
  108. }
  109. /**
  110. * Starts query statistic log
  111. *
  112. * @throws \RuntimeException
  113. */
  114. protected function startQueryLog()
  115. {
  116. if (!$this->em || !$this->em->getConnection()->getDatabasePlatform()) {
  117. throw new \RuntimeException('EntityManager and database platform must be initialized');
  118. }
  119. $this->queryAnalyzer = new QueryAnalyzer($this->em->getConnection()->getDatabasePlatform());
  120. $this->em
  121. ->getConfiguration()
  122. ->expects($this->any())
  123. ->method('getSQLLogger')
  124. ->will($this->returnValue($this->queryAnalyzer));
  125. }
  126. /**
  127. * Stops query statistic log and outputs
  128. * the data to screen or file
  129. *
  130. * @param boolean $dumpOnlySql
  131. * @param boolean $writeToLog
  132. * @throws \RuntimeException
  133. */
  134. protected function stopQueryLog($dumpOnlySql = false, $writeToLog = false)
  135. {
  136. if ($this->queryAnalyzer) {
  137. $output = $this->queryAnalyzer->getOutput($dumpOnlySql);
  138. if ($writeToLog) {
  139. $fileName = __DIR__.'/../../temp/query_debug_'.time().'.log';
  140. if (($file = fopen($fileName, 'w+')) !== false) {
  141. fwrite($file, $output);
  142. fclose($file);
  143. } else {
  144. throw new \RuntimeException('Unable to write to the log file');
  145. }
  146. } else {
  147. echo $output;
  148. }
  149. }
  150. }
  151. /**
  152. * Creates default mapping driver
  153. *
  154. * @return \Doctrine\ORM\Mapping\Driver\Driver
  155. */
  156. protected function getMetadataDriverImplementation()
  157. {
  158. return new AnnotationDriver($_ENV['annotation_reader']);
  159. }
  160. /**
  161. * Get a list of used fixture classes
  162. *
  163. * @return array
  164. */
  165. abstract protected function getUsedEntityFixtures();
  166. /**
  167. * Build event manager
  168. *
  169. * @return EventManager
  170. */
  171. private function getEventManager()
  172. {
  173. $evm = new EventManager;
  174. $evm->addEventSubscriber(new TreeListener);
  175. $evm->addEventSubscriber(new SluggableListener);
  176. $evm->addEventSubscriber(new LoggableListener);
  177. $evm->addEventSubscriber(new TranslatableListener);
  178. $evm->addEventSubscriber(new TimestampableListener);
  179. $evm->addEventSubscriber(new SoftDeleteableListener);
  180. return $evm;
  181. }
  182. /**
  183. * Get annotation mapping configuration
  184. *
  185. * @return Doctrine\ORM\Configuration
  186. */
  187. protected function getMockAnnotatedConfig()
  188. {
  189. // We need to mock every method except the ones which
  190. // handle the filters
  191. $configurationClass = 'Doctrine\ORM\Configuration';
  192. $refl = new \ReflectionClass($configurationClass);
  193. $methods = $refl->getMethods();
  194. $mockMethods = array();
  195. foreach ($methods as $method) {
  196. if ($method->name !== 'addFilter' && $method->name !== 'getFilterClassName') {
  197. $mockMethods[] = $method->name;
  198. }
  199. }
  200. $config = $this->getMock($configurationClass, $mockMethods);
  201. $config
  202. ->expects($this->once())
  203. ->method('getProxyDir')
  204. ->will($this->returnValue(__DIR__.'/../../temp'))
  205. ;
  206. $config
  207. ->expects($this->once())
  208. ->method('getProxyNamespace')
  209. ->will($this->returnValue('Proxy'))
  210. ;
  211. $config
  212. ->expects($this->once())
  213. ->method('getAutoGenerateProxyClasses')
  214. ->will($this->returnValue(true))
  215. ;
  216. $config
  217. ->expects($this->once())
  218. ->method('getClassMetadataFactoryName')
  219. ->will($this->returnValue('Doctrine\\ORM\\Mapping\\ClassMetadataFactory'))
  220. ;
  221. $mappingDriver = $this->getMetadataDriverImplementation();
  222. $config
  223. ->expects($this->any())
  224. ->method('getMetadataDriverImpl')
  225. ->will($this->returnValue($mappingDriver))
  226. ;
  227. $config
  228. ->expects($this->any())
  229. ->method('getDefaultRepositoryClassName')
  230. ->will($this->returnValue('Doctrine\\ORM\\EntityRepository'))
  231. ;
  232. return $config;
  233. }
  234. }