Fix bug in ZSCAN-based iterator when sorted sets have integer members.

When iterating a sorted set containing integer members, our iterator
abstraction based on ZSCAN was always returning "0" as a member value
after the first $member => $score pair because of a wrong assumption
on how the PHP function array_shift() (used internally to advance to
the next pair in our buffered response to ZSCAN) works.

Fixes #216.
This commit is contained in:
Daniele Alessandri
2014-10-21 11:43:53 +02:00
parent d09c4f32f3
commit dc2cb3c639
3 changed files with 48 additions and 2 deletions
+3
View File
@@ -1,6 +1,9 @@
v1.0.1 (2014-xx-xx)
================================================================================
- __FIX__: broken values returned by `Predis\Collection\Iterator\SortedSetKey`
when iterating sorted set containing integer members (ISSUE #216).
- __FIX__: applied a minor workaround for a bug in old versions of PHP < 5.3.9
affecting inheritance.
+6 -2
View File
@@ -49,7 +49,11 @@ class SortedSetKey extends CursorBasedIterator
*/
protected function extractNext()
{
$this->position = key($this->elements);
$this->current = array_shift($this->elements);
if ($kv = each($this->elements)) {
$this->position = $kv[0];
$this->current = $kv[1];
unset($this->elements[$this->position]);
}
}
}
@@ -56,6 +56,45 @@ class SortedSetKeyTest extends PredisTestCase
$this->assertFalse($iterator->valid());
}
/**
* @link https://github.com/nrk/predis/issues/216
* @group disconnected
*/
public function testIterationWithIntegerMembers()
{
$client = $this->getMock('Predis\Client', array('getProfile', 'zscan'));
$client->expects($this->any())
->method('getProfile')
->will($this->returnValue(Profile\Factory::get('2.8')));
$client->expects($this->once())
->method('zscan')
->with('key:zset', 0, array())
->will($this->returnValue(array(0, array(
0 => 0, 101 => 1, 102 => 2,
))));
$iterator = new SortedSetKey($client, 'key:zset');
$iterator->rewind();
$this->assertTrue($iterator->valid());
$this->assertSame(0, $iterator->current());
$this->assertSame(0, $iterator->key());
$iterator->next();
$this->assertTrue($iterator->valid());
$this->assertSame(1, $iterator->current());
$this->assertSame(101, $iterator->key());
$iterator->next();
$this->assertTrue($iterator->valid());
$this->assertSame(2, $iterator->current());
$this->assertSame(102, $iterator->key());
$iterator->next();
$this->assertFalse($iterator->valid());
}
/**
* @group disconnected
*/