You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

478 lines
14 KiB

  1. <?php
  2. /*
  3. * @copyright NetMonsters <team@netmonsters.ru>
  4. * @link http://netmonsters.ru
  5. * @package Majestic
  6. * @subpackage UnitTests
  7. * @since 2011-11-15
  8. *
  9. * Unit tests for MySQLiStatement class
  10. */
  11. require_once dirname(__FILE__) . '/../../Registry.php';
  12. require_once dirname(__FILE__) . '/../../Config.php';
  13. require_once dirname(__FILE__) . '/../../util/profiler/CommandProfiler.php';
  14. require_once dirname(__FILE__) . '/../../util/profiler/Profiler.php';
  15. require_once dirname(__FILE__) . '/../../model/Db.php';
  16. require_once dirname(__FILE__) . '/../../model/DbDriver.php';
  17. require_once dirname(__FILE__) . '/../../model/DbStatement.php';
  18. require_once dirname(__FILE__) . '/../../model/MongoStatement.php';
  19. require_once dirname(__FILE__) . '/../../exception/GeneralException.php';
  20. class MongoStatementTest extends PHPUnit_Framework_TestCase
  21. {
  22. private $driver;
  23. private $stmt;
  24. private $request;
  25. private $testData = array(
  26. array('one' => 11, 'two' => 12),
  27. array('one' => 21, 'two' => 22),
  28. array('one' => 31, 'two' => 32),
  29. );
  30. public function run(PHPUnit_Framework_TestResult $result = NULL)
  31. {
  32. $this->setPreserveGlobalState(false);
  33. return parent::run($result);
  34. }
  35. public function setUp()
  36. {
  37. if (!isset($this->stmt)) {
  38. $this->driver = $this->getMockBuilder('DbDriverMock')
  39. ->disableOriginalConstructor()
  40. ->setMethods(array('getConnection'))
  41. ->getMock();
  42. $this->request = $this->getMockBuilder('MongoDbCommandMock')
  43. ->disableOriginalConstructor()
  44. ->setMethods(array('execute', 'bindParam', 'getInsertId', '__toString'))
  45. ->getMock();
  46. $this->stmt = new MongoStatement($this->driver, $this->request);
  47. }
  48. }
  49. /**
  50. * @runInSeparateProcess
  51. * @group Mongo
  52. */
  53. public function testAffectedNumRowsNoResult()
  54. {
  55. Config::set('PROFILER_DETAILS', false);
  56. $this->assertFalse($this->stmt->affectedRows());
  57. $this->assertFalse($this->stmt->numRows());
  58. $this->setDriverGetConnectionMethod();
  59. $this->request
  60. ->expects($this->any())
  61. ->method('execute')
  62. ->will($this->returnValue(array()));
  63. $this->stmt->execute();
  64. $this->assertFalse($this->stmt->affectedRows());
  65. }
  66. /**
  67. * @runInSeparateProcess
  68. * @group Mongo
  69. */
  70. public function testAffectedNumRows()
  71. {
  72. Config::set('PROFILER_DETAILS', false);
  73. $this->setDriverGetConnectionMethod();
  74. $this->request
  75. ->expects($this->once())
  76. ->method('execute')
  77. ->will($this->returnValue(array('n' => 20, 'ok' => 1)));
  78. $this->stmt->execute();
  79. $this->assertEquals(20, $this->stmt->affectedRows());
  80. }
  81. /**
  82. * @runInSeparateProcess
  83. * @group Mongo
  84. */
  85. public function testGetInsertId()
  86. {
  87. Config::set('PROFILER_DETAILS', false);
  88. $this->setDriverGetConnectionMethod();
  89. $this->request = $this->getMockBuilder('InsertMongoCommand')
  90. ->disableOriginalConstructor()
  91. ->setMethods(array('execute', 'bindParam', 'getInsertId'))
  92. ->getMock();
  93. $this->request
  94. ->expects($this->once())
  95. ->method('execute')
  96. ->will($this->returnValue(array('n' => 20, 'ok' => 1)));
  97. $this->request
  98. ->expects($this->once())
  99. ->method('getInsertId')
  100. ->will($this->returnValue('4b0rrs'));
  101. $this->stmt = new MongoStatement($this->driver, $this->request);
  102. $this->stmt->execute();
  103. $this->assertEquals('4b0rrs', $this->stmt->getInsertId());
  104. }
  105. /**
  106. * @runInSeparateProcess
  107. * @group Mongo
  108. */
  109. public function testExecute()
  110. {
  111. Config::set('PROFILER_DETAILS', false);
  112. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  113. $this->assertTrue($this->stmt->execute());
  114. }
  115. /**
  116. * @runInSeparateProcess
  117. * @group Mongo
  118. */
  119. public function testExecuteNoResult()
  120. {
  121. Config::set('PROFILER_DETAILS', false);
  122. $this->setDriverGetConnectionMethod();
  123. $this->request
  124. ->expects($this->any())
  125. ->method('execute')
  126. ->will($this->returnValue(false));
  127. $this->setExpectedException('GeneralException', 'MongoDB request error.');
  128. $this->stmt->execute();
  129. }
  130. /**
  131. * @runInSeparateProcess
  132. * @group Mongo
  133. */
  134. public function testExecuteNoConnection()
  135. {
  136. Config::set('PROFILER_DETAILS', false);
  137. $this->driver
  138. ->expects($this->any())
  139. ->method('getConnection')
  140. ->will($this->returnValue(false));
  141. $this->setExpectedException('GeneralException', 'No connection to MongoDB server.');
  142. $this->stmt->execute();
  143. }
  144. /**
  145. * @runInSeparateProcess
  146. * @group Mongo
  147. */
  148. public function testExecuteWithDebug()
  149. {
  150. Config::set('PROFILER', true);
  151. Config::set('PROFILER_DETAILS', true);
  152. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  153. $this->assertTrue($this->stmt->execute());
  154. $this->assertEquals(10, $this->stmt->numRows());
  155. $this->assertContains('Queries: 1', Profiler::getInstance()->getCli());
  156. }
  157. /**
  158. * @runInSeparateProcess
  159. * @group Mongo
  160. */
  161. public function testBindParam()
  162. {
  163. Config::set('PROFILER', true);
  164. Config::set('PROFILER_DETAILS', true);
  165. $this->request
  166. ->expects($this->once())
  167. ->method('bindParam')
  168. ->will($this->returnValue(true));
  169. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  170. $this->assertTrue($this->stmt->execute(array('one' => 'two')));
  171. $this->assertAttributeNotEquals(null, 'result', $this->stmt);
  172. $this->stmt->close();
  173. $this->assertAttributeEquals(null, 'result', $this->stmt);
  174. }
  175. /**
  176. * @runInSeparateProcess
  177. * @group Mongo
  178. */
  179. public function testFetch()
  180. {
  181. Config::set('PROFILER', true);
  182. Config::set('PROFILER_DETAILS', true);
  183. $this->assertFalse($this->stmt->fetch());
  184. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  185. $this->stmt->execute();
  186. $result = $this->stmt->fetch();
  187. $this->assertEquals('prev', $result->next);
  188. $this->assertFalse($this->stmt->fetch());
  189. }
  190. /**
  191. * @runInSeparateProcess
  192. * @group Mongo
  193. */
  194. public function testFetchWithInitialArray()
  195. {
  196. Config::set('PROFILER', true);
  197. Config::set('PROFILER_DETAILS', true);
  198. $this->assertFalse($this->stmt->fetch());
  199. $this->setDriverGetConnectionMethod();
  200. $this->request
  201. ->expects($this->once())
  202. ->method('execute')
  203. ->will($this->returnValue(array('retval' => 'val')));
  204. $this->stmt->execute();
  205. $this->assertEquals('val', $this->stmt->fetch());
  206. }
  207. /**
  208. * @runInSeparateProcess
  209. * @group Mongo
  210. */
  211. public function testFetchAssocFromCursor()
  212. {
  213. Config::set('PROFILER', true);
  214. Config::set('PROFILER_DETAILS', true);
  215. $this->assertFalse($this->stmt->fetch());
  216. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  217. $this->stmt->execute();
  218. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  219. $this->assertEquals('prev', $result['next']);
  220. $this->assertEquals(array(), $this->stmt->fetch(Db::FETCH_ASSOC));
  221. }
  222. /**
  223. * @runInSeparateProcess
  224. * @group Mongo
  225. */
  226. public function testFetchAssocFromArray()
  227. {
  228. Config::set('PROFILER', true);
  229. Config::set('PROFILER_DETAILS', true);
  230. $this->assertFalse($this->stmt->fetch());
  231. $this->setDriverGetConnectionMethod();
  232. $this->request
  233. ->expects($this->once())
  234. ->method('execute')
  235. ->will($this->returnValue(array('some' => 'val')));
  236. $this->stmt->execute();
  237. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  238. $this->assertEquals('val', $result['some']);
  239. }
  240. /**
  241. * @runInSeparateProcess
  242. * @group Mongo
  243. */
  244. public function testFetchWrongMode()
  245. {
  246. Config::set('PROFILER', true);
  247. Config::set('PROFILER_DETAILS', true);
  248. $this->assertFalse($this->stmt->fetch());
  249. $this->setDriverGetConnectionMethod();
  250. $this->request
  251. ->expects($this->once())
  252. ->method('execute')
  253. ->will($this->returnValue(array('some' => 'val')));
  254. $this->stmt->execute();
  255. $this->setExpectedException('GeneralException', 'Invalid fetch mode "222" specified');
  256. $this->stmt->fetch(222);
  257. }
  258. /**
  259. * @runInSeparateProcess
  260. * @group Mongo
  261. */
  262. public function testSkipOrderLimit()
  263. {
  264. Config::set('PROFILER', true);
  265. Config::set('PROFILER_DETAILS', true);
  266. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  267. $this->stmt->execute();
  268. $this->assertInstanceOf('MongoStatement', $this->stmt->order(array('id' => 1)));
  269. $this->assertInstanceOf('MongoStatement', $this->stmt->limit(10));
  270. $this->assertInstanceOf('MongoStatement', $this->stmt->skip(1));
  271. $this->stmt->fetch();
  272. $this->stmt->fetch();
  273. }
  274. /**
  275. * @runInSeparateProcess
  276. * @group Mongo
  277. */
  278. public function testCount()
  279. {
  280. Config::set('PROFILER', true);
  281. Config::set('PROFILER_DETAILS', true);
  282. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  283. $this->stmt->execute();
  284. $this->assertSame(10, $this->stmt->count());
  285. $this->stmt->fetch();
  286. }
  287. /**
  288. * @runInSeparateProcess
  289. * @group Mongo
  290. */
  291. public function testCountException()
  292. {
  293. Config::set('PROFILER', true);
  294. Config::set('PROFILER_DETAILS', true);
  295. $this->setDriverGetConnectionMethod();
  296. $this->request
  297. ->expects($this->once())
  298. ->method('execute')
  299. ->will($this->returnValue(array('some' => 'val')));
  300. $this->stmt->execute();
  301. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible count result of opened cursor');
  302. $this->stmt->count();
  303. }
  304. /**
  305. * @runInSeparateProcess
  306. * @group Mongo
  307. */
  308. public function testOrderException()
  309. {
  310. Config::set('PROFILER', true);
  311. Config::set('PROFILER_DETAILS', true);
  312. $this->setDriverGetConnectionMethod();
  313. $this->request
  314. ->expects($this->once())
  315. ->method('execute')
  316. ->will($this->returnValue(array('some' => 'val')));
  317. $this->stmt->execute();
  318. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible order results of opened cursor');
  319. $this->stmt->order(array('id' => 1));
  320. }
  321. /**
  322. * @runInSeparateProcess
  323. * @group Mongo
  324. */
  325. public function testSkipException()
  326. {
  327. Config::set('PROFILER', true);
  328. Config::set('PROFILER_DETAILS', true);
  329. $this->setDriverGetConnectionMethod();
  330. $this->request
  331. ->expects($this->once())
  332. ->method('execute')
  333. ->will($this->returnValue(array('some' => 'val')));
  334. $this->stmt->execute();
  335. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible skip results of opened cursor');
  336. $this->stmt->skip(array('id' => 1));
  337. }
  338. /**
  339. * @runInSeparateProcess
  340. * @group Mongo
  341. */
  342. public function testLimitException()
  343. {
  344. Config::set('PROFILER', true);
  345. Config::set('PROFILER_DETAILS', true);
  346. $this->setDriverGetConnectionMethod();
  347. $this->request
  348. ->expects($this->once())
  349. ->method('execute')
  350. ->will($this->returnValue(array('some' => 'val')));
  351. $this->stmt->execute();
  352. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible limit results of opened cursor');
  353. $this->stmt->limit(array('id' => 1));
  354. }
  355. private function setDriverGetConnectionMethod()
  356. {
  357. $mongoMock = $this->getMock('Mongo');
  358. $this->driver
  359. ->expects($this->any())
  360. ->method('getConnection')
  361. ->will($this->returnValue($mongoMock));
  362. return $this;
  363. }
  364. public function setRequestExecuteMethod()
  365. {
  366. $resultMock = $this->getMockBuilder('MongoCursor')
  367. ->setMethods(array('count'))
  368. ->disableOriginalConstructor()
  369. ->getMock();
  370. $resultMock
  371. ->expects($this->any())
  372. ->method('count')
  373. ->will($this->returnValue(10));
  374. $this->request
  375. ->expects($this->any())
  376. ->method('execute')
  377. ->will($this->returnValue($resultMock));
  378. return $this;
  379. }
  380. public function setRequestForFetch()
  381. {
  382. $resultMock = $this->getMockBuilder('MongoCursor')
  383. ->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip'))
  384. ->disableOriginalConstructor()
  385. ->getMock();
  386. $resultMock
  387. ->expects($this->any())
  388. ->method('limit');
  389. $resultMock
  390. ->expects($this->any())
  391. ->method('sort');
  392. $resultMock
  393. ->expects($this->any())
  394. ->method('skip');
  395. $resultMock
  396. ->expects($this->any())
  397. ->method('count')
  398. ->will($this->returnValue(10));
  399. $resultMock
  400. ->expects($this->at(0))
  401. ->method('getNext')
  402. ->will($this->returnValue(array('next' => 'prev', '_id' => 10)));
  403. $resultMock
  404. ->expects($this->at(1))
  405. ->method('getNext')
  406. ->will($this->returnValue(array()));
  407. $this->request
  408. ->expects($this->any())
  409. ->method('execute')
  410. ->will($this->returnValue($resultMock));
  411. return $this;
  412. }
  413. }