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.

464 lines
13 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'))
  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('DEBUG', 0);
  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('DEBUG', 0);
  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('DEBUG', 0);
  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('DEBUG', 0);
  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('DEBUG', 0);
  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('DEBUG', 0);
  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('DEBUG', 1);
  151. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  152. $this->assertTrue($this->stmt->execute());
  153. $this->assertEquals(10, $this->stmt->numRows());
  154. }
  155. /**
  156. * @runInSeparateProcess
  157. * @group Mongo
  158. */
  159. public function testBindParam()
  160. {
  161. Config::set('DEBUG', 1);
  162. $this->request
  163. ->expects($this->once())
  164. ->method('bindParam')
  165. ->will($this->returnValue(true));
  166. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  167. $this->assertTrue($this->stmt->execute(array('one' => 'two')));
  168. $this->assertAttributeNotEquals(null, 'result', $this->stmt);
  169. $this->stmt->close();
  170. $this->assertAttributeEquals(null, 'result', $this->stmt);
  171. }
  172. /**
  173. * @runInSeparateProcess
  174. * @group Mongo
  175. */
  176. public function testFetch()
  177. {
  178. Config::set('DEBUG', 1);
  179. $this->assertFalse($this->stmt->fetch());
  180. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  181. $this->stmt->execute();
  182. $result = $this->stmt->fetch();
  183. $this->assertEquals('prev', $result->next);
  184. $this->assertFalse($this->stmt->fetch());
  185. }
  186. /**
  187. * @runInSeparateProcess
  188. * @group Mongo
  189. */
  190. public function testFetchWithInitialArray()
  191. {
  192. Config::set('DEBUG', 1);
  193. $this->assertFalse($this->stmt->fetch());
  194. $this->setDriverGetConnectionMethod();
  195. $this->request
  196. ->expects($this->once())
  197. ->method('execute')
  198. ->will($this->returnValue(array('retval' => 'val')));
  199. $this->stmt->execute();
  200. $this->assertEquals('val', $this->stmt->fetch());
  201. }
  202. /**
  203. * @runInSeparateProcess
  204. * @group Mongo
  205. */
  206. public function testFetchAssocFromCursor()
  207. {
  208. Config::set('DEBUG', 1);
  209. $this->assertFalse($this->stmt->fetch());
  210. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  211. $this->stmt->execute();
  212. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  213. $this->assertEquals('prev', $result['next']);
  214. $this->assertEquals(array(), $this->stmt->fetch(Db::FETCH_ASSOC));
  215. }
  216. /**
  217. * @runInSeparateProcess
  218. * @group Mongo
  219. */
  220. public function testFetchAssocFromArray()
  221. {
  222. Config::set('DEBUG', 1);
  223. $this->assertFalse($this->stmt->fetch());
  224. $this->setDriverGetConnectionMethod();
  225. $this->request
  226. ->expects($this->once())
  227. ->method('execute')
  228. ->will($this->returnValue(array('some' => 'val')));
  229. $this->stmt->execute();
  230. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  231. $this->assertEquals('val', $result['some']);
  232. }
  233. /**
  234. * @runInSeparateProcess
  235. * @group Mongo
  236. */
  237. public function testFetchWrongMode()
  238. {
  239. Config::set('DEBUG', 1);
  240. $this->assertFalse($this->stmt->fetch());
  241. $this->setDriverGetConnectionMethod();
  242. $this->request
  243. ->expects($this->once())
  244. ->method('execute')
  245. ->will($this->returnValue(array('some' => 'val')));
  246. $this->stmt->execute();
  247. $this->setExpectedException('GeneralException', 'Invalid fetch mode "222" specified');
  248. $this->stmt->fetch(222);
  249. }
  250. /**
  251. * @runInSeparateProcess
  252. * @group Mongo
  253. */
  254. public function testSkipOrderLimit()
  255. {
  256. Config::set('DEBUG', 1);
  257. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  258. $this->stmt->execute();
  259. $this->assertInstanceOf('MongoStatement', $this->stmt->order(array('id' => 1)));
  260. $this->assertInstanceOf('MongoStatement', $this->stmt->limit(10));
  261. $this->assertInstanceOf('MongoStatement', $this->stmt->skip(1));
  262. $this->stmt->fetch();
  263. $this->stmt->fetch();
  264. }
  265. /**
  266. * @runInSeparateProcess
  267. * @group Mongo
  268. */
  269. public function testCount()
  270. {
  271. Config::set('DEBUG', 1);
  272. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  273. $this->stmt->execute();
  274. $this->assertSame(10, $this->stmt->count());
  275. $this->stmt->fetch();
  276. }
  277. /**
  278. * @runInSeparateProcess
  279. * @group Mongo
  280. */
  281. public function testCountException()
  282. {
  283. Config::set('DEBUG', 1);
  284. $this->setDriverGetConnectionMethod();
  285. $this->request
  286. ->expects($this->once())
  287. ->method('execute')
  288. ->will($this->returnValue(array('some' => 'val')));
  289. $this->stmt->execute();
  290. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible count result of opened cursor');
  291. $this->stmt->count();
  292. }
  293. /**
  294. * @runInSeparateProcess
  295. * @group Mongo
  296. */
  297. public function testOrderException()
  298. {
  299. Config::set('DEBUG', 1);
  300. $this->setDriverGetConnectionMethod();
  301. $this->request
  302. ->expects($this->once())
  303. ->method('execute')
  304. ->will($this->returnValue(array('some' => 'val')));
  305. $this->stmt->execute();
  306. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible order results of opened cursor');
  307. $this->stmt->order(array('id' => 1));
  308. }
  309. /**
  310. * @runInSeparateProcess
  311. * @group Mongo
  312. */
  313. public function testSkipException()
  314. {
  315. Config::set('DEBUG', 1);
  316. $this->setDriverGetConnectionMethod();
  317. $this->request
  318. ->expects($this->once())
  319. ->method('execute')
  320. ->will($this->returnValue(array('some' => 'val')));
  321. $this->stmt->execute();
  322. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible skip results of opened cursor');
  323. $this->stmt->skip(array('id' => 1));
  324. }
  325. /**
  326. * @runInSeparateProcess
  327. * @group Mongo
  328. */
  329. public function testLimitException()
  330. {
  331. Config::set('DEBUG', 1);
  332. $this->setDriverGetConnectionMethod();
  333. $this->request
  334. ->expects($this->once())
  335. ->method('execute')
  336. ->will($this->returnValue(array('some' => 'val')));
  337. $this->stmt->execute();
  338. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible limit results of opened cursor');
  339. $this->stmt->limit(array('id' => 1));
  340. }
  341. private function setDriverGetConnectionMethod()
  342. {
  343. $mongoMock = $this->getMock('Mongo');
  344. $this->driver
  345. ->expects($this->any())
  346. ->method('getConnection')
  347. ->will($this->returnValue($mongoMock));
  348. return $this;
  349. }
  350. public function setRequestExecuteMethod()
  351. {
  352. $resultMock = $this->getMockBuilder('MongoCursor')
  353. ->setMethods(array('count'))
  354. ->disableOriginalConstructor()
  355. ->getMock();
  356. $resultMock
  357. ->expects($this->any())
  358. ->method('count')
  359. ->will($this->returnValue(10));
  360. $this->request
  361. ->expects($this->any())
  362. ->method('execute')
  363. ->will($this->returnValue($resultMock));
  364. return $this;
  365. }
  366. public function setRequestForFetch()
  367. {
  368. $resultMock = $this->getMockBuilder('MongoCursor')
  369. ->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip'))
  370. ->disableOriginalConstructor()
  371. ->getMock();
  372. $resultMock
  373. ->expects($this->any())
  374. ->method('limit');
  375. $resultMock
  376. ->expects($this->any())
  377. ->method('sort');
  378. $resultMock
  379. ->expects($this->any())
  380. ->method('skip');
  381. $resultMock
  382. ->expects($this->any())
  383. ->method('count')
  384. ->will($this->returnValue(10));
  385. $resultMock
  386. ->expects($this->at(0))
  387. ->method('getNext')
  388. ->will($this->returnValue(array('next' => 'prev', '_id' => 10)));
  389. $resultMock
  390. ->expects($this->at(1))
  391. ->method('getNext')
  392. ->will($this->returnValue(array()));
  393. $this->request
  394. ->expects($this->any())
  395. ->method('execute')
  396. ->will($this->returnValue($resultMock));
  397. return $this;
  398. }
  399. }