HashKeyTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. <?php
  2. /*
  3. * This file is part of the Predis package.
  4. *
  5. * (c) Daniele Alessandri <suppakilla@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Predis\Collection\Iterator;
  11. use PredisTestCase;
  12. use Predis\Client;
  13. use Predis\Profile\ServerProfile;
  14. /**
  15. * @group realm-iterators
  16. */
  17. class HashKeyTest extends PredisTestCase
  18. {
  19. /**
  20. * @group disconnected
  21. * @expectedException Predis\NotSupportedException
  22. * @expectedExceptionMessage The specified server profile does not support the `HSCAN` command.
  23. */
  24. public function testThrowsExceptionOnInvalidServerProfile()
  25. {
  26. $client = $this->getMock('Predis\ClientInterface');
  27. $client->expects($this->any())
  28. ->method('getProfile')
  29. ->will($this->returnValue(ServerProfile::get('2.0')));
  30. $iterator = new HashKey($client, 'key:hash');
  31. }
  32. /**
  33. * @group disconnected
  34. */
  35. public function testIterationWithNoResults()
  36. {
  37. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  38. $client->expects($this->any())
  39. ->method('getProfile')
  40. ->will($this->returnValue(ServerProfile::get('2.8')));
  41. $client->expects($this->once())
  42. ->method('hscan')
  43. ->with('key:hash', 0, array())
  44. ->will($this->returnValue(array(0, array())));
  45. $iterator = new HashKey($client, 'key:hash');
  46. $iterator->rewind();
  47. $this->assertFalse($iterator->valid());
  48. }
  49. /**
  50. * @group disconnected
  51. */
  52. public function testIterationOnSingleFetch()
  53. {
  54. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  55. $client->expects($this->any())
  56. ->method('getProfile')
  57. ->will($this->returnValue(ServerProfile::get('2.8')));
  58. $client->expects($this->once())
  59. ->method('hscan')
  60. ->with('key:hash', 0, array())
  61. ->will($this->returnValue(array(0, array(
  62. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd', 'field:3rd' => 'value:3rd',
  63. ))));
  64. $iterator = new HashKey($client, 'key:hash');
  65. $iterator->rewind();
  66. $this->assertTrue($iterator->valid());
  67. $this->assertSame('value:1st', $iterator->current());
  68. $this->assertSame('field:1st', $iterator->key());
  69. $iterator->next();
  70. $this->assertTrue($iterator->valid());
  71. $this->assertSame('value:2nd', $iterator->current());
  72. $this->assertSame('field:2nd', $iterator->key());
  73. $iterator->next();
  74. $this->assertTrue($iterator->valid());
  75. $this->assertSame('value:3rd', $iterator->current());
  76. $this->assertSame('field:3rd', $iterator->key());
  77. $iterator->next();
  78. $this->assertFalse($iterator->valid());
  79. }
  80. /**
  81. * @group disconnected
  82. */
  83. public function testIterationOnMultipleFetches()
  84. {
  85. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  86. $client->expects($this->any())
  87. ->method('getProfile')
  88. ->will($this->returnValue(ServerProfile::get('2.8')));
  89. $client->expects($this->at(1))
  90. ->method('hscan')
  91. ->with('key:hash', 0, array())
  92. ->will($this->returnValue(array(2, array(
  93. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  94. ))));
  95. $client->expects($this->at(2))
  96. ->method('hscan')
  97. ->with('key:hash', 2, array())
  98. ->will($this->returnValue(array(0, array(
  99. 'field:3rd' => 'value:3rd',
  100. ))));
  101. $iterator = new HashKey($client, 'key:hash');
  102. $iterator->rewind();
  103. $this->assertTrue($iterator->valid());
  104. $this->assertSame('value:1st', $iterator->current());
  105. $this->assertSame('field:1st', $iterator->key());
  106. $iterator->next();
  107. $this->assertTrue($iterator->valid());
  108. $this->assertSame('value:2nd', $iterator->current());
  109. $this->assertSame('field:2nd', $iterator->key());
  110. $iterator->next();
  111. $this->assertTrue($iterator->valid());
  112. $this->assertSame('value:3rd', $iterator->current());
  113. $this->assertSame('field:3rd', $iterator->key());
  114. $iterator->next();
  115. $this->assertFalse($iterator->valid());
  116. }
  117. /**
  118. * @group disconnected
  119. */
  120. public function testIterationOnMultipleFetchesAndHoleInFirstFetch()
  121. {
  122. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  123. $client->expects($this->any())
  124. ->method('getProfile')
  125. ->will($this->returnValue(ServerProfile::get('2.8')));
  126. $client->expects($this->at(1))
  127. ->method('hscan')
  128. ->with('key:hash', 0, array())
  129. ->will($this->returnValue(array(4, array())));
  130. $client->expects($this->at(2))
  131. ->method('hscan')
  132. ->with('key:hash', 4, array())
  133. ->will($this->returnValue(array(0, array(
  134. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  135. ))));
  136. $iterator = new HashKey($client, 'key:hash');
  137. $iterator->rewind();
  138. $this->assertTrue($iterator->valid());
  139. $this->assertSame('value:1st', $iterator->current());
  140. $this->assertSame('field:1st', $iterator->key());
  141. $iterator->next();
  142. $this->assertTrue($iterator->valid());
  143. $this->assertSame('value:2nd', $iterator->current());
  144. $this->assertSame('field:2nd', $iterator->key());
  145. $iterator->next();
  146. $this->assertFalse($iterator->valid());
  147. }
  148. /**
  149. * @group disconnected
  150. */
  151. public function testIterationOnMultipleFetchesAndHoleInMidFetch()
  152. {
  153. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  154. $client->expects($this->any())
  155. ->method('getProfile')
  156. ->will($this->returnValue(ServerProfile::get('2.8')));
  157. $client->expects($this->at(1))
  158. ->method('hscan')
  159. ->with('key:hash', 0, array())
  160. ->will($this->returnValue(array(2, array(
  161. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  162. ))));
  163. $client->expects($this->at(2))
  164. ->method('hscan')
  165. ->with('key:hash', 2, array())
  166. ->will($this->returnValue(array(5, array())));
  167. $client->expects($this->at(3))
  168. ->method('hscan')
  169. ->with('key:hash', 5, array())
  170. ->will($this->returnValue(array(0, array(
  171. 'field:3rd' => 'value:3rd',
  172. ))));
  173. $iterator = new HashKey($client, 'key:hash');
  174. $iterator->rewind();
  175. $this->assertTrue($iterator->valid());
  176. $this->assertSame('value:1st', $iterator->current());
  177. $this->assertSame('field:1st', $iterator->key());
  178. $iterator->next();
  179. $this->assertTrue($iterator->valid());
  180. $this->assertSame('value:2nd', $iterator->current());
  181. $this->assertSame('field:2nd', $iterator->key());
  182. $iterator->next();
  183. $this->assertTrue($iterator->valid());
  184. $this->assertSame('value:3rd', $iterator->current());
  185. $this->assertSame('field:3rd', $iterator->key());
  186. $iterator->next();
  187. $this->assertFalse($iterator->valid());
  188. }
  189. /**
  190. * @group disconnected
  191. */
  192. public function testIterationWithOptionMatch()
  193. {
  194. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  195. $client->expects($this->any())
  196. ->method('getProfile')
  197. ->will($this->returnValue(ServerProfile::get('2.8')));
  198. $client->expects($this->at(1))
  199. ->method('hscan')
  200. ->with('key:hash', 0, array('MATCH' => 'field:*'))
  201. ->will($this->returnValue(array(2, array(
  202. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  203. ))));
  204. $iterator = new HashKey($client, 'key:hash', 'field:*');
  205. $iterator->rewind();
  206. $this->assertTrue($iterator->valid());
  207. $this->assertSame('value:1st', $iterator->current());
  208. $this->assertSame('field:1st', $iterator->key());
  209. $iterator->next();
  210. $this->assertTrue($iterator->valid());
  211. $this->assertSame('value:2nd', $iterator->current());
  212. $this->assertSame('field:2nd', $iterator->key());
  213. $iterator->next();
  214. $this->assertFalse($iterator->valid());
  215. }
  216. /**
  217. * @group disconnected
  218. */
  219. public function testIterationWithOptionMatchOnMultipleFetches()
  220. {
  221. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  222. $client->expects($this->any())
  223. ->method('getProfile')
  224. ->will($this->returnValue(ServerProfile::get('2.8')));
  225. $client->expects($this->at(1))
  226. ->method('hscan')
  227. ->with('key:hash', 0, array('MATCH' => 'field:*'))
  228. ->will($this->returnValue(array(1, array(
  229. 'field:1st' => 'value:1st',
  230. ))));
  231. $client->expects($this->at(2))
  232. ->method('hscan')
  233. ->with('key:hash', 1, array('MATCH' => 'field:*'))
  234. ->will($this->returnValue(array(0, array(
  235. 'field:2nd' => 'value:2nd',
  236. ))));
  237. $iterator = new HashKey($client, 'key:hash', 'field:*');
  238. $iterator->rewind();
  239. $this->assertTrue($iterator->valid());
  240. $this->assertSame('value:1st', $iterator->current());
  241. $this->assertSame('field:1st', $iterator->key());
  242. $iterator->next();
  243. $this->assertTrue($iterator->valid());
  244. $this->assertSame('value:2nd', $iterator->current());
  245. $this->assertSame('field:2nd', $iterator->key());
  246. $iterator->next();
  247. $this->assertFalse($iterator->valid());
  248. }
  249. /**
  250. * @group disconnected
  251. */
  252. public function testIterationWithOptionCount()
  253. {
  254. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  255. $client->expects($this->any())
  256. ->method('getProfile')
  257. ->will($this->returnValue(ServerProfile::get('2.8')));
  258. $client->expects($this->at(1))
  259. ->method('hscan')
  260. ->with('key:hash', 0, array('COUNT' => 2))
  261. ->will($this->returnValue(array(0, array(
  262. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  263. ))));
  264. $iterator = new HashKey($client, 'key:hash', null, 2);
  265. $iterator->rewind();
  266. $this->assertTrue($iterator->valid());
  267. $this->assertSame('value:1st', $iterator->current());
  268. $this->assertSame('field:1st', $iterator->key());
  269. $iterator->next();
  270. $this->assertTrue($iterator->valid());
  271. $this->assertSame('value:2nd', $iterator->current());
  272. $this->assertSame('field:2nd', $iterator->key());
  273. $iterator->next();
  274. $this->assertFalse($iterator->valid());
  275. }
  276. /**
  277. * @group disconnected
  278. */
  279. public function testIterationWithOptionCountOnMultipleFetches()
  280. {
  281. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  282. $client->expects($this->any())
  283. ->method('getProfile')
  284. ->will($this->returnValue(ServerProfile::get('2.8')));
  285. $client->expects($this->at(1))
  286. ->method('hscan')
  287. ->with('key:hash', 0, array('COUNT' => 1))
  288. ->will($this->returnValue(array(1, array(
  289. 'field:1st' => 'value:1st',
  290. ))));
  291. $client->expects($this->at(2))
  292. ->method('hscan')
  293. ->with('key:hash', 1, array('COUNT' => 1))
  294. ->will($this->returnValue(array(0, array(
  295. 'field:2nd' => 'value:2nd',
  296. ))));
  297. $iterator = new HashKey($client, 'key:hash', null, 1);
  298. $iterator->rewind();
  299. $this->assertTrue($iterator->valid());
  300. $this->assertSame('value:1st', $iterator->current());
  301. $this->assertSame('field:1st', $iterator->key());
  302. $iterator->next();
  303. $this->assertTrue($iterator->valid());
  304. $this->assertSame('value:2nd', $iterator->current());
  305. $this->assertSame('field:2nd', $iterator->key());
  306. $iterator->next();
  307. $this->assertFalse($iterator->valid());
  308. }
  309. /**
  310. * @group disconnected
  311. */
  312. public function testIterationWithOptionsMatchAndCount()
  313. {
  314. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  315. $client->expects($this->any())
  316. ->method('getProfile')
  317. ->will($this->returnValue(ServerProfile::get('2.8')));
  318. $client->expects($this->at(1))
  319. ->method('hscan')
  320. ->with('key:hash', 0, array('MATCH' => 'field:*', 'COUNT' => 2))
  321. ->will($this->returnValue(array(0, array(
  322. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  323. ))));
  324. $iterator = new HashKey($client, 'key:hash', 'field:*', 2);
  325. $iterator->rewind();
  326. $this->assertTrue($iterator->valid());
  327. $this->assertSame('value:1st', $iterator->current());
  328. $this->assertSame('field:1st', $iterator->key());
  329. $iterator->next();
  330. $this->assertTrue($iterator->valid());
  331. $this->assertSame('value:2nd', $iterator->current());
  332. $this->assertSame('field:2nd', $iterator->key());
  333. $iterator->next();
  334. $this->assertFalse($iterator->valid());
  335. }
  336. /**
  337. * @group disconnected
  338. */
  339. public function testIterationWithOptionsMatchAndCountOnMultipleFetches()
  340. {
  341. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  342. $client->expects($this->any())
  343. ->method('getProfile')
  344. ->will($this->returnValue(ServerProfile::get('2.8')));
  345. $client->expects($this->at(1))
  346. ->method('hscan')
  347. ->with('key:hash', 0, array('MATCH' => 'field:*', 'COUNT' => 1))
  348. ->will($this->returnValue(array(1, array(
  349. 'field:1st' => 'value:1st',
  350. ))));
  351. $client->expects($this->at(2))
  352. ->method('hscan')
  353. ->with('key:hash', 1, array('MATCH' => 'field:*', 'COUNT' => 1))
  354. ->will($this->returnValue(array(0, array(
  355. 'field:2nd' => 'value:2nd',
  356. ))));
  357. $iterator = new HashKey($client, 'key:hash', 'field:*', 1);
  358. $iterator->rewind();
  359. $this->assertTrue($iterator->valid());
  360. $this->assertSame('value:1st', $iterator->current());
  361. $this->assertSame('field:1st', $iterator->key());
  362. $iterator->next();
  363. $this->assertTrue($iterator->valid());
  364. $this->assertSame('value:2nd', $iterator->current());
  365. $this->assertSame('field:2nd', $iterator->key());
  366. $iterator->next();
  367. $this->assertFalse($iterator->valid());
  368. }
  369. /**
  370. * @group disconnected
  371. */
  372. public function testIterationRewindable()
  373. {
  374. $client = $this->getMock('Predis\Client', array('getProfile', 'hscan'));
  375. $client->expects($this->any())
  376. ->method('getProfile')
  377. ->will($this->returnValue(ServerProfile::get('2.8')));
  378. $client->expects($this->exactly(2))
  379. ->method('hscan')
  380. ->with('key:hash', 0, array())
  381. ->will($this->returnValue(array(0, array(
  382. 'field:1st' => 'value:1st', 'field:2nd' => 'value:2nd',
  383. ))));
  384. $iterator = new HashKey($client, 'key:hash');
  385. $iterator->rewind();
  386. $this->assertTrue($iterator->valid());
  387. $this->assertSame('value:1st', $iterator->current());
  388. $this->assertSame('field:1st', $iterator->key());
  389. $iterator->rewind();
  390. $this->assertTrue($iterator->valid());
  391. $this->assertSame('value:1st', $iterator->current());
  392. $this->assertSame('field:1st', $iterator->key());
  393. $iterator->next();
  394. $this->assertTrue($iterator->valid());
  395. $this->assertSame('value:2nd', $iterator->current());
  396. $this->assertSame('field:2nd', $iterator->key());
  397. $iterator->next();
  398. $this->assertFalse($iterator->valid());
  399. }
  400. }