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.

463 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__) . '/../../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('some' => 'val')));
  217. $this->stmt->execute();
  218. $this->assertFalse($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 testOrderException()
  296. {
  297. if (!defined('DEBUG')) {
  298. define('DEBUG', true);
  299. }
  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. if (!defined('DEBUG')) {
  316. define('DEBUG', true);
  317. }
  318. $this->setDriverGetConnectionMethod();
  319. $this->request
  320. ->expects($this->once())
  321. ->method('execute')
  322. ->will($this->returnValue(array('some' => 'val')));
  323. $this->stmt->execute();
  324. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible skip results of opened cursor');
  325. $this->stmt->skip(array('id' => 1));
  326. }
  327. /**
  328. * @runInSeparateProcess
  329. * @group Mongo
  330. */
  331. public function testLimitException()
  332. {
  333. if (!defined('DEBUG')) {
  334. define('DEBUG', true);
  335. }
  336. $this->setDriverGetConnectionMethod();
  337. $this->request
  338. ->expects($this->once())
  339. ->method('execute')
  340. ->will($this->returnValue(array('some' => 'val')));
  341. $this->stmt->execute();
  342. $this->setExpectedException('GeneralException', 'MongoStatement error. Impossible limit results of opened cursor');
  343. $this->stmt->limit(array('id' => 1));
  344. }
  345. private function setDriverGetConnectionMethod()
  346. {
  347. $mongoMock = $this->getMock('Mongo');
  348. $this->driver
  349. ->expects($this->any())
  350. ->method('getConnection')
  351. ->will($this->returnValue($mongoMock));
  352. return $this;
  353. }
  354. public function setRequestExecuteMethod()
  355. {
  356. $resultMock = $this->getMockBuilder('MongoCursor')
  357. ->setMethods(array('count'))
  358. ->disableOriginalConstructor()
  359. ->getMock();
  360. $resultMock
  361. ->expects($this->any())
  362. ->method('count')
  363. ->will($this->returnValue(10));
  364. $this->request
  365. ->expects($this->any())
  366. ->method('execute')
  367. ->will($this->returnValue($resultMock));
  368. return $this;
  369. }
  370. public function setRequestForFetch()
  371. {
  372. $resultMock = $this->getMockBuilder('MongoCursor')
  373. ->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip'))
  374. ->disableOriginalConstructor()
  375. ->getMock();
  376. $resultMock
  377. ->expects($this->any())
  378. ->method('limit');
  379. $resultMock
  380. ->expects($this->any())
  381. ->method('sort');
  382. $resultMock
  383. ->expects($this->any())
  384. ->method('skip');
  385. $resultMock
  386. ->expects($this->any())
  387. ->method('count')
  388. ->will($this->returnValue(10));
  389. $resultMock
  390. ->expects($this->at(0))
  391. ->method('getNext')
  392. ->will($this->returnValue(array('next' => 'prev', '_id' => 10)));
  393. $resultMock
  394. ->expects($this->at(1))
  395. ->method('getNext')
  396. ->will($this->returnValue(array()));
  397. $this->request
  398. ->expects($this->any())
  399. ->method('execute')
  400. ->will($this->returnValue($resultMock));
  401. return $this;
  402. }
  403. }