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.

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