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.

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