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.

452 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. */
  50. public function testAffectedNumRowsNoResult()
  51. {
  52. if (!defined('DEBUG')) {
  53. define('DEBUG', false);
  54. }
  55. $this->assertFalse($this->stmt->affectedRows());
  56. $this->assertFalse($this->stmt->numRows());
  57. $this->setDriverGetConnectionMethod();
  58. $this->request
  59. ->expects($this->any())
  60. ->method('execute')
  61. ->will($this->returnValue(array()));
  62. $this->stmt->execute();
  63. $this->assertFalse($this->stmt->affectedRows());
  64. }
  65. /**
  66. * @runInSeparateProcess
  67. */
  68. public function testAffectedNumRows()
  69. {
  70. if (!defined('DEBUG')) {
  71. define('DEBUG', false);
  72. }
  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. */
  84. public function testGetInsertId()
  85. {
  86. if (!defined('DEBUG')) {
  87. define('DEBUG', false);
  88. }
  89. $this->setDriverGetConnectionMethod();
  90. $this->request = $this->getMockBuilder('InsertMongoCommand')
  91. ->disableOriginalConstructor()
  92. ->setMethods(array('execute', 'bindParam', 'getInsertId'))
  93. ->getMock();
  94. $this->request
  95. ->expects($this->once())
  96. ->method('execute')
  97. ->will($this->returnValue(array('n' => 20, 'ok' => 1)));
  98. $this->request
  99. ->expects($this->once())
  100. ->method('getInsertId')
  101. ->will($this->returnValue('4b0rrs'));
  102. $this->stmt = new MongoStatement($this->driver, $this->request);
  103. $this->stmt->execute();
  104. $this->assertEquals('4b0rrs', $this->stmt->getInsertId());
  105. }
  106. /**
  107. * @runInSeparateProcess
  108. */
  109. public function testExecute()
  110. {
  111. if (!defined('DEBUG')) {
  112. define('DEBUG', false);
  113. }
  114. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  115. $this->assertTrue($this->stmt->execute());
  116. }
  117. /**
  118. * @runInSeparateProcess
  119. * @expectedException GeneralException
  120. * @expectedExceptionMessage MongoDB request error.
  121. */
  122. public function testExecuteNoResult()
  123. {
  124. if (!defined('DEBUG')) {
  125. define('DEBUG', false);
  126. }
  127. $this->setDriverGetConnectionMethod();
  128. $this->request
  129. ->expects($this->any())
  130. ->method('execute')
  131. ->will($this->returnValue(false));
  132. $this->stmt->execute();
  133. }
  134. /**
  135. * @runInSeparateProcess
  136. * @expectedException GeneralException
  137. * @expectedExceptionMessage No connection to MongoDB server.
  138. */
  139. public function testExecuteNoConnection()
  140. {
  141. if (!defined('DEBUG')) {
  142. define('DEBUG', false);
  143. }
  144. $this->driver
  145. ->expects($this->any())
  146. ->method('getConnection')
  147. ->will($this->returnValue(false));
  148. $this->stmt->execute();
  149. }
  150. /**
  151. * @runInSeparateProcess
  152. */
  153. public function testExecuteWithDebug()
  154. {
  155. if (!defined('DEBUG')) {
  156. define('DEBUG', true);
  157. }
  158. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  159. $this->assertTrue($this->stmt->execute());
  160. $this->assertEquals(10, $this->stmt->numRows());
  161. }
  162. /**
  163. * @runInSeparateProcess
  164. */
  165. public function testBindParam()
  166. {
  167. if (!defined('DEBUG')) {
  168. define('DEBUG', true);
  169. }
  170. $this->request
  171. ->expects($this->once())
  172. ->method('bindParam')
  173. ->will($this->returnValue(true));
  174. $this->setDriverGetConnectionMethod()->setRequestExecuteMethod();
  175. $this->assertTrue($this->stmt->execute(array('one' => 'two')));
  176. $this->assertAttributeNotEquals(null, 'result', $this->stmt);
  177. $this->stmt->close();
  178. $this->assertAttributeEquals(null, 'result', $this->stmt);
  179. }
  180. /**
  181. * @runInSeparateProcess
  182. */
  183. public function testFetch()
  184. {
  185. if (!defined('DEBUG')) {
  186. define('DEBUG', true);
  187. }
  188. $this->assertFalse($this->stmt->fetch());
  189. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  190. $this->stmt->execute();
  191. $result = $this->stmt->fetch();
  192. $this->assertEquals('prev', $result->next);
  193. $this->assertFalse($this->stmt->fetch());
  194. }
  195. /**
  196. * @runInSeparateProcess
  197. */
  198. public function testFetchWithInitialArray()
  199. {
  200. if (!defined('DEBUG')) {
  201. define('DEBUG', true);
  202. }
  203. $this->assertFalse($this->stmt->fetch());
  204. $this->setDriverGetConnectionMethod();
  205. $this->request
  206. ->expects($this->once())
  207. ->method('execute')
  208. ->will($this->returnValue(array('some' => 'val')));
  209. $this->stmt->execute();
  210. $this->assertFalse($this->stmt->fetch());
  211. }
  212. /**
  213. * @runInSeparateProcess
  214. */
  215. public function testFetchAssocFromCursor()
  216. {
  217. if (!defined('DEBUG')) {
  218. define('DEBUG', true);
  219. }
  220. $this->assertFalse($this->stmt->fetch());
  221. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  222. $this->stmt->execute();
  223. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  224. $this->assertEquals('prev', $result['next']);
  225. $this->assertEquals(array(), $this->stmt->fetch(Db::FETCH_ASSOC));
  226. }
  227. /**
  228. * @runInSeparateProcess
  229. */
  230. public function testFetchAssocFromArray()
  231. {
  232. if (!defined('DEBUG')) {
  233. define('DEBUG', true);
  234. }
  235. $this->assertFalse($this->stmt->fetch());
  236. $this->setDriverGetConnectionMethod();
  237. $this->request
  238. ->expects($this->once())
  239. ->method('execute')
  240. ->will($this->returnValue(array('some' => 'val')));
  241. $this->stmt->execute();
  242. $result = $this->stmt->fetch(Db::FETCH_ASSOC);
  243. $this->assertEquals('val', $result['some']);
  244. }
  245. /**
  246. * @runInSeparateProcess
  247. * @expectedException GeneralException
  248. * @expectedExceptionMessage Invalid fetch mode "222" specified
  249. */
  250. public function testFetchWrongMode()
  251. {
  252. if (!defined('DEBUG')) {
  253. define('DEBUG', true);
  254. }
  255. $this->assertFalse($this->stmt->fetch());
  256. $this->setDriverGetConnectionMethod();
  257. $this->request
  258. ->expects($this->once())
  259. ->method('execute')
  260. ->will($this->returnValue(array('some' => 'val')));
  261. $this->stmt->execute();
  262. $this->stmt->fetch(222);
  263. }
  264. /**
  265. * @runInSeparateProcess
  266. */
  267. public function testSkipOrderLimit()
  268. {
  269. if (!defined('DEBUG')) {
  270. define('DEBUG', true);
  271. }
  272. $this->setDriverGetConnectionMethod()->setRequestForFetch();
  273. $this->stmt->execute();
  274. $this->assertInstanceOf('MongoStatement', $this->stmt->order(array('id' => 1)));
  275. $this->assertInstanceOf('MongoStatement', $this->stmt->limit(10));
  276. $this->assertInstanceOf('MongoStatement', $this->stmt->skip(1));
  277. $this->stmt->fetch();
  278. $this->stmt->fetch();
  279. }
  280. /**
  281. * @runInSeparateProcess
  282. * @expectedException GeneralException
  283. * @expectedExceptionMessage MongoStatement error. Impossible order results of opened cursor
  284. */
  285. public function testOrderException()
  286. {
  287. if (!defined('DEBUG')) {
  288. define('DEBUG', true);
  289. }
  290. $this->setDriverGetConnectionMethod();
  291. $this->request
  292. ->expects($this->once())
  293. ->method('execute')
  294. ->will($this->returnValue(array('some' => 'val')));
  295. $this->stmt->execute();
  296. $this->stmt->order(array('id' => 1));
  297. }
  298. /**
  299. * @runInSeparateProcess
  300. * @expectedException GeneralException
  301. * @expectedExceptionMessage MongoStatement error. Impossible skip results of opened cursor
  302. */
  303. public function testSkipException()
  304. {
  305. if (!defined('DEBUG')) {
  306. define('DEBUG', true);
  307. }
  308. $this->setDriverGetConnectionMethod();
  309. $this->request
  310. ->expects($this->once())
  311. ->method('execute')
  312. ->will($this->returnValue(array('some' => 'val')));
  313. $this->stmt->execute();
  314. $this->stmt->skip(array('id' => 1));
  315. }
  316. /**
  317. * @runInSeparateProcess
  318. * @expectedException GeneralException
  319. * @expectedExceptionMessage MongoStatement error. Impossible limit results of opened cursor
  320. */
  321. public function testLimitException()
  322. {
  323. if (!defined('DEBUG')) {
  324. define('DEBUG', true);
  325. }
  326. $this->setDriverGetConnectionMethod();
  327. $this->request
  328. ->expects($this->once())
  329. ->method('execute')
  330. ->will($this->returnValue(array('some' => 'val')));
  331. $this->stmt->execute();
  332. $this->stmt->limit(array('id' => 1));
  333. }
  334. private function setDriverGetConnectionMethod()
  335. {
  336. $mongoMock = $this->getMock('Mongo');
  337. $this->driver
  338. ->expects($this->any())
  339. ->method('getConnection')
  340. ->will($this->returnValue($mongoMock));
  341. return $this;
  342. }
  343. public function setRequestExecuteMethod()
  344. {
  345. $resultMock = $this->getMockBuilder('MongoCursor')
  346. ->setMethods(array('count'))
  347. ->disableOriginalConstructor()
  348. ->getMock();
  349. $resultMock
  350. ->expects($this->any())
  351. ->method('count')
  352. ->will($this->returnValue(10));
  353. $this->request
  354. ->expects($this->any())
  355. ->method('execute')
  356. ->will($this->returnValue($resultMock));
  357. return $this;
  358. }
  359. public function setRequestForFetch()
  360. {
  361. $resultMock = $this->getMockBuilder('MongoCursor')
  362. ->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip'))
  363. ->disableOriginalConstructor()
  364. ->getMock();
  365. $resultMock
  366. ->expects($this->any())
  367. ->method('limit');
  368. $resultMock
  369. ->expects($this->any())
  370. ->method('sort');
  371. $resultMock
  372. ->expects($this->any())
  373. ->method('skip');
  374. $resultMock
  375. ->expects($this->any())
  376. ->method('count')
  377. ->will($this->returnValue(10));
  378. $resultMock
  379. ->expects($this->at(0))
  380. ->method('getNext')
  381. ->will($this->returnValue(array('next' => 'prev', '_id' => 10)));
  382. $resultMock
  383. ->expects($this->at(1))
  384. ->method('getNext')
  385. ->will($this->returnValue(array()));
  386. $this->request
  387. ->expects($this->any())
  388. ->method('execute')
  389. ->will($this->returnValue($resultMock));
  390. return $this;
  391. }
  392. }