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.

479 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', false);
  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. $this->assertContains('Queries not counted.', Profiler::getInstance()->getCli());
  190. }
  191. /**
  192. * @runInSeparateProcess
  193. * @group Mongo
  194. */
  195. public function testFetchWithInitialArray()
  196. {
  197. Config::set('PROFILER', true);
  198. Config::set('PROFILER_DETAILS', true);
  199. $this->assertFalse($this->stmt->fetch());
  200. $this->setDriverGetConnectionMethod();
  201. $this->request
  202. ->expects($this->once())
  203. ->method('execute')
  204. ->will($this->returnValue(array('retval' => 'val')));
  205. $this->stmt->execute();
  206. $this->assertEquals('val', $this->stmt->fetch());
  207. }
  208. /**
  209. * @runInSeparateProcess
  210. * @group Mongo
  211. */
  212. public function testFetchAssocFromCursor()
  213. {
  214. Config::set('PROFILER', true);
  215. Config::set('PROFILER_DETAILS', true);
  216. $this->assertFalse($this->stmt->fetch());
  217. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  218. $this->stmt->execute();
  219. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  220. $this->assertEquals('prev', $result['next']);
  221. $this->assertEquals(array(), $this->stmt->fetch(Db::FETCH_ASSOC));
  222. }
  223. /**
  224. * @runInSeparateProcess
  225. * @group Mongo
  226. */
  227. public function testFetchAssocFromArray()
  228. {
  229. Config::set('PROFILER', true);
  230. Config::set('PROFILER_DETAILS', true);
  231. $this->assertFalse($this->stmt->fetch());
  232. $this->setDriverGetConnectionMethod();
  233. $this->request
  234. ->expects($this->once())
  235. ->method('execute')
  236. ->will($this->returnValue(array('some' => 'val')));
  237. $this->stmt->execute();
  238. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  239. $this->assertEquals('val', $result['some']);
  240. }
  241. /**
  242. * @runInSeparateProcess
  243. * @group Mongo
  244. */
  245. public function testFetchWrongMode()
  246. {
  247. Config::set('PROFILER', true);
  248. Config::set('PROFILER_DETAILS', true);
  249. $this->assertFalse($this->stmt->fetch());
  250. $this->setDriverGetConnectionMethod();
  251. $this->request
  252. ->expects($this->once())
  253. ->method('execute')
  254. ->will($this->returnValue(array('some' => 'val')));
  255. $this->stmt->execute();
  256. $this->setExpectedException('GeneralException', 'Invalid fetch mode "222" specified');
  257. $this->stmt->fetch(222);
  258. }
  259. /**
  260. * @runInSeparateProcess
  261. * @group Mongo
  262. */
  263. public function testSkipOrderLimit()
  264. {
  265. Config::set('PROFILER', true);
  266. Config::set('PROFILER_DETAILS', true);
  267. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  268. $this->stmt->execute();
  269. $this->assertInstanceOf('MongoStatement', $this->stmt->order(array('id' => 1)));
  270. $this->assertInstanceOf('MongoStatement', $this->stmt->limit(10));
  271. $this->assertInstanceOf('MongoStatement', $this->stmt->skip(1));
  272. $this->stmt->fetch();
  273. $this->stmt->fetch();
  274. }
  275. /**
  276. * @runInSeparateProcess
  277. * @group Mongo
  278. */
  279. public function testCount()
  280. {
  281. Config::set('PROFILER', true);
  282. Config::set('PROFILER_DETAILS', true);
  283. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  284. $this->stmt->execute();
  285. $this->assertSame(10, $this->stmt->count());
  286. $this->stmt->fetch();
  287. }
  288. /**
  289. * @runInSeparateProcess
  290. * @group Mongo
  291. */
  292. public function testCountException()
  293. {
  294. Config::set('PROFILER', true);
  295. Config::set('PROFILER_DETAILS', true);
  296. $this->setDriverGetConnectionMethod();
  297. $this->request
  298. ->expects($this->once())
  299. ->method('execute')
  300. ->will($this->returnValue(array('some' => 'val')));
  301. $this->stmt->execute();
  302. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible count result of opened cursor');
  303. $this->stmt->count();
  304. }
  305. /**
  306. * @runInSeparateProcess
  307. * @group Mongo
  308. */
  309. public function testOrderException()
  310. {
  311. Config::set('PROFILER', true);
  312. Config::set('PROFILER_DETAILS', true);
  313. $this->setDriverGetConnectionMethod();
  314. $this->request
  315. ->expects($this->once())
  316. ->method('execute')
  317. ->will($this->returnValue(array('some' => 'val')));
  318. $this->stmt->execute();
  319. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible order results of opened cursor');
  320. $this->stmt->order(array('id' => 1));
  321. }
  322. /**
  323. * @runInSeparateProcess
  324. * @group Mongo
  325. */
  326. public function testSkipException()
  327. {
  328. Config::set('PROFILER', true);
  329. Config::set('PROFILER_DETAILS', true);
  330. $this->setDriverGetConnectionMethod();
  331. $this->request
  332. ->expects($this->once())
  333. ->method('execute')
  334. ->will($this->returnValue(array('some' => 'val')));
  335. $this->stmt->execute();
  336. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible skip results of opened cursor');
  337. $this->stmt->skip(array('id' => 1));
  338. }
  339. /**
  340. * @runInSeparateProcess
  341. * @group Mongo
  342. */
  343. public function testLimitException()
  344. {
  345. Config::set('PROFILER', true);
  346. Config::set('PROFILER_DETAILS', true);
  347. $this->setDriverGetConnectionMethod();
  348. $this->request
  349. ->expects($this->once())
  350. ->method('execute')
  351. ->will($this->returnValue(array('some' => 'val')));
  352. $this->stmt->execute();
  353. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible limit results of opened cursor');
  354. $this->stmt->limit(array('id' => 1));
  355. }
  356. private function setDriverGetConnectionMethod()
  357. {
  358. $mongoMock = $this->getMock('Mongo');
  359. $this->driver
  360. ->expects($this->any())
  361. ->method('getConnection')
  362. ->will($this->returnValue($mongoMock));
  363. return $this;
  364. }
  365. public function setRequestExecuteMethod()
  366. {
  367. $resultMock = $this->getMockBuilder('MongoCursor')
  368. ->setMethods(array('count'))
  369. ->disableOriginalConstructor()
  370. ->getMock();
  371. $resultMock
  372. ->expects($this->any())
  373. ->method('count')
  374. ->will($this->returnValue(10));
  375. $this->request
  376. ->expects($this->any())
  377. ->method('execute')
  378. ->will($this->returnValue($resultMock));
  379. return $this;
  380. }
  381. public function setRequestForFetch()
  382. {
  383. $resultMock = $this->getMockBuilder('MongoCursor')
  384. ->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip'))
  385. ->disableOriginalConstructor()
  386. ->getMock();
  387. $resultMock
  388. ->expects($this->any())
  389. ->method('limit');
  390. $resultMock
  391. ->expects($this->any())
  392. ->method('sort');
  393. $resultMock
  394. ->expects($this->any())
  395. ->method('skip');
  396. $resultMock
  397. ->expects($this->any())
  398. ->method('count')
  399. ->will($this->returnValue(10));
  400. $resultMock
  401. ->expects($this->at(0))
  402. ->method('getNext')
  403. ->will($this->returnValue(array('next' => 'prev', '_id' => 10)));
  404. $resultMock
  405. ->expects($this->at(1))
  406. ->method('getNext')
  407. ->will($this->returnValue(array()));
  408. $this->request
  409. ->expects($this->any())
  410. ->method('execute')
  411. ->will($this->returnValue($resultMock));
  412. return $this;
  413. }
  414. }