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.

317 lines
9.9 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-7
  8. *
  9. * Unit tests for MongoModel class
  10. */
  11. require_once dirname(__FILE__) . '/../../Registry.php';
  12. require_once dirname(__FILE__) . '/../../Config.php';
  13. require_once dirname(__FILE__) . '/../../cache/Cacher.php';
  14. require_once dirname(__FILE__) . '/../../model/DbExpr.php';
  15. require_once dirname(__FILE__) . '/../../model/Db.php';
  16. require_once dirname(__FILE__) . '/../../model/MongoDbCommand.php';
  17. require_once dirname(__FILE__) . '/../../model/DbStatement.php';
  18. require_once dirname(__FILE__) . '/../../model/MongoStatement.php';
  19. require_once dirname(__FILE__) . '/../../model/DbDriver.php';
  20. require_once dirname(__FILE__) . '/../../model/NoSqlDbDriver.php';
  21. require_once dirname(__FILE__) . '/../../model/MongoDriver.php';
  22. require_once dirname(__FILE__) . '/../../model/Model.php';
  23. require_once dirname(__FILE__) . '/../../model/MongoModel.php';
  24. class MongoModelTest extends PHPUnit_Framework_TestCase
  25. {
  26. private $model;
  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. $conf = array('default' => array('driver' => 'MongoDriver', 'hostname' => 'localhost', 'database' => 'test', 'username' => 'test', 'password' => '1234', 'port' => 27017));
  35. $this->dbSetUp($conf);
  36. Config::set('Db', $conf);
  37. if (!class_exists('MockModel')) {
  38. $this->model = $this->getMockForAbstractClass('MongoModel', array(), 'MongoMockModel');
  39. } else {
  40. $this->model = new MongoMockModel();
  41. }
  42. set_new_overload(array($this, 'newCallback'));
  43. }
  44. /**
  45. * @group Mongo
  46. */
  47. public function testModel()
  48. {
  49. $this->assertInstanceOf('MongoMockModel', $this->model);
  50. }
  51. /**
  52. * @runInSeparateProcess
  53. * @group Mongo
  54. */
  55. public function testFind()
  56. {
  57. if (!defined('DEBUG')) {
  58. define('DEBUG', false);
  59. }
  60. $result = $this->model->find();
  61. $this->assertInstanceOf('MongoStatement', $result);
  62. $this->assertEquals('milk', $result->limit(2)->order(array('name' => -1))->fetch()->name);
  63. $this->assertEquals('fish', $result->fetch()->name);
  64. $result = $this->model->find(array(), array('name'))->fetch();
  65. $this->assertSame('bread', $result->name);
  66. $this->setExpectedException('PHPUnit_Framework_Error');
  67. $this->assertNull($result->price);
  68. }
  69. /**
  70. * @runInSeparateProcess
  71. * @group Mongo
  72. */
  73. public function testGet()
  74. {
  75. if (!defined('DEBUG')) {
  76. define('DEBUG', false);
  77. }
  78. $result = $this->model->find()->limit(1)->order(array('name' => 1));
  79. $result = $result->fetch();
  80. $this->assertEquals('bread', $result->name);
  81. $id = $result->_id;
  82. $this->assertEquals(10, $this->model->get($id)->quantity);
  83. }
  84. /**
  85. * @runInSeparateProcess
  86. * @group Mongo
  87. */
  88. public function testDelete()
  89. {
  90. if (!defined('DEBUG')) {
  91. define('DEBUG', false);
  92. }
  93. $result = $this->model->find()->limit(1)->order(array('name' => 1));
  94. $id = $result->fetch()->_id;
  95. $this->assertEquals(1, $this->model->delete($id));
  96. $this->assertFalse($this->model->find(array('name' => 'bread'))->fetch());
  97. }
  98. /**
  99. * @runInSeparateProcess
  100. * @group Mongo
  101. */
  102. public function testBatchInsert()
  103. {
  104. if (!defined('DEBUG')) {
  105. define('DEBUG', false);
  106. }
  107. $data = array(
  108. array('name' => 'first object'),
  109. array('name' => 'second object'),
  110. array('name' => 'equal object'),
  111. array('name' => 'equal object')
  112. );
  113. $this->model->batchInsert($data);
  114. $this->assertEquals(1, $this->model->count(array('name' => 'first object')));
  115. $this->assertEquals(2, $this->model->count(array('name' => 'equal object')));
  116. $this->model->batchInsert(array());
  117. }
  118. /**
  119. * @runInSeparateProcess
  120. * @group Mongo
  121. */
  122. public function testDeleteAll()
  123. {
  124. if (!defined('DEBUG')) {
  125. define('DEBUG', false);
  126. }
  127. $this->assertEquals(2, $this->model->count(array('name' => 'eggs')));
  128. $this->assertEquals(0, $this->model->deleteAll(array('name' => 'eggs')));
  129. $this->assertFalse($this->model->find(array('name' => 'eggs'))->fetch());
  130. }
  131. /**
  132. * @runInSeparateProcess
  133. * @group Mongo
  134. */
  135. public function testCount()
  136. {
  137. if (!defined('DEBUG')) {
  138. define('DEBUG', false);
  139. }
  140. $this->assertEquals(5, $this->model->count());
  141. $this->assertEquals(2, $this->model->count(array('name' => 'eggs')));
  142. }
  143. /**
  144. * @runInSeparateProcess
  145. * @group Mongo
  146. */
  147. public function testFetch()
  148. {
  149. if (!defined('DEBUG')) {
  150. define('DEBUG', false);
  151. }
  152. $mock = $this->getMock('CacheKey', array('set', 'get'));
  153. $mock->expects($this->exactly(3))
  154. ->method('set')
  155. ->will($this->returnValue(true));
  156. $mock->expects($this->exactly(3))
  157. ->method('get')
  158. ->will($this->returnValue(false));
  159. $model = new ReflectionClass('MongoModel');
  160. $method = $model->getMethod('fetchField');
  161. $method->setAccessible(true);
  162. $result = $method->invoke($this->model, array('name' => 'milk'), array(), 'quantity', $mock);
  163. $this->assertEquals(1, $result);
  164. $model = new ReflectionClass('MongoModel');
  165. $method = $model->getMethod('fetch');
  166. $method->setAccessible(true);
  167. $result = $method->invoke($this->model, array('name' => 'bread'), array(), $mock);
  168. $this->assertEquals('bread', $result->name);
  169. $model = new ReflectionClass('MongoModel');
  170. $method = $model->getMethod('fetchAll');
  171. $method->setAccessible(true);
  172. $result = $method->invoke($this->model, array('name' => 'eggs'), array(), $mock);
  173. $this->assertEquals(2, count($result));
  174. $this->assertEquals('eggs', $result[0]->name);
  175. }
  176. /**
  177. * @runInSeparateProcess
  178. * @group Mongo
  179. */
  180. public function testUseMongoId()
  181. {
  182. if (!defined('DEBUG')) {
  183. define('DEBUG', false);
  184. }
  185. $this->assertAttributeEquals(true, 'useMongoId', $this->model);
  186. }
  187. /**
  188. * @runInSeparateProcess
  189. * @group Mongo
  190. */
  191. public function testId()
  192. {
  193. if (!defined('DEBUG')) {
  194. define('DEBUG', false);
  195. }
  196. $class = new ReflectionClass('MongoModel');
  197. $prop = $class->getProperty('useMongoId');
  198. $prop->setAccessible(true);
  199. $this->model->insert(array('_id' => 1, 'name' => 'testbread', 'price' => 3.2, 'quantity' => 10));
  200. $this->model->insert(array('_id' => 2, 'name' => 'testbread', 'price' => 12, 'quantity' => 2));
  201. $this->assertSame(2, $this->model->count(array('name' => 'testbread')));
  202. $prop->setValue($this->model, false);
  203. $this->model->delete(1);
  204. $this->assertSame(1, $this->model->count(array('name' => 'testbread')));
  205. }
  206. /**
  207. * @runInSeparateProcess
  208. * @group Mongo
  209. */
  210. public function testIdToMongoId()
  211. {
  212. if (!defined('DEBUG')) {
  213. define('DEBUG', false);
  214. }
  215. $this->model->insert(array('name' => 'testbread', 'price' => 3.2, 'quantity' => 10));
  216. $this->model->insert(array('name' => 'testbread', 'price' => 12, 'quantity' => 2));
  217. $this->assertSame(2, $this->model->count(array('name' => 'testbread')));
  218. $id = $this->model->find(array('name' => 'testbread'))->limit(1)->fetch()->_id->__toString();
  219. $this->assertInternalType('string', $id);
  220. $item = $this->model->get($id);
  221. $this->assertSame('testbread', $item->name);
  222. $this->model->delete($id);
  223. $this->assertSame(1, $this->model->count(array('name' => 'testbread')));
  224. }
  225. public function tearDown()
  226. {
  227. $conf = array('driver' => 'MongoDriver', 'hostname' => 'localhost', 'database' => 'test', 'username' => 'test', 'password' => '1234', 'port' => 27017);
  228. $connection = new Mongo('mongodb://' . $conf['hostname'] . ':' . $conf['port']);
  229. $db = $connection->selectDB($conf['database']);
  230. $db->authenticate($conf['username'], $conf['password']);
  231. $collection = 'mongomock';
  232. $db->dropCollection($collection);
  233. }
  234. protected function newCallback($className)
  235. {
  236. switch ($className) {
  237. case 'CacheKey':
  238. return 'MockCacheKey';
  239. default:
  240. return $className;
  241. }
  242. }
  243. public function dbSetUp($conf)
  244. {
  245. $data = array(
  246. array(
  247. 'name' => 'bread',
  248. 'price' => 3.2,
  249. 'quantity' => 10
  250. ),
  251. array(
  252. 'name' => 'eggs',
  253. 'price' => 2.1,
  254. 'quantity' => 20
  255. ),
  256. array(
  257. 'name' => 'fish',
  258. 'price' => 13.2,
  259. 'quantity' => 2
  260. ),
  261. array(
  262. 'name' => 'milk',
  263. 'price' => 3.8,
  264. 'quantity' => 1
  265. ),
  266. array(
  267. 'name' => 'eggs',
  268. 'price' => 2.3,
  269. 'quantity' => 5
  270. )
  271. );
  272. $connection = new Mongo('mongodb://' . $conf['default']['hostname'] . ':' . $conf['default']['port']);
  273. $db = $connection->selectDB($conf['default']['database']);
  274. $db->authenticate($conf['default']['username'], $conf['default']['password']);
  275. $collection = 'mongomock';
  276. $db->dropCollection($collection);
  277. $collection = $db->selectCollection($collection);
  278. foreach ($data as $document) {
  279. $collection->insert($document);
  280. }
  281. }
  282. }