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.

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