Browse Source

Merge pull request #15413 from cakephp/backport-15405

Backport: Fix BufferedIterator not yielding full results
Mark Story 5 years ago
parent
commit
79d4d5ec14

+ 4 - 0
src/Collection/Iterator/BufferedIterator.php

@@ -157,6 +157,10 @@ class BufferedIterator extends Collection implements Countable, Serializable
     {
         $this->_index++;
 
+        // Don't move inner iterator if we have more buffer
+        if ($this->_buffer->offsetExists($this->_index)) {
+            return;
+        }
         if (!$this->_finished) {
             parent::next();
         }

+ 21 - 2
tests/TestCase/Collection/CollectionTest.php

@@ -683,7 +683,7 @@ class CollectionTest extends TestCase
     {
         $collection = new Collection($items);
         $callback = function ($e) {
-            return $e['a']['b']['c'] * - 1;
+            return $e['a']['b']['c'] * -1;
         };
         $this->assertEquals(['a' => ['b' => ['c' => 4]]], $collection->max($callback));
     }
@@ -698,7 +698,7 @@ class CollectionTest extends TestCase
     {
         $collection = new Collection($items);
         $this->assertEquals(['a' => ['b' => ['c' => 4]]], $collection->max(function ($e) {
-            return $e['a']['b']['c'] * - 1;
+            return $e['a']['b']['c'] * -1;
         }));
     }
 
@@ -1346,6 +1346,25 @@ class CollectionTest extends TestCase
         $this->assertEquals(['a' => 4, 'b' => 5, 'c' => 6], $buffered->toArray());
     }
 
+    public function testBufferedIterator()
+    {
+        $data = [
+            ['myField' => '1'],
+            ['myField' => '2'],
+            ['myField' => '3'],
+        ];
+        $buffered = (new \Cake\Collection\Collection($data))->buffered();
+        // Check going forwards
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '1']));
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '2']));
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '3']));
+
+        // And backwards.
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '3']));
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '2']));
+        $this->assertNotEmpty($buffered->firstMatch(['myField' => '1']));
+    }
+
     /**
      * Tests the combine method
      *

+ 22 - 1
tests/TestCase/Collection/Iterator/BufferedIteratorTest.php

@@ -29,7 +29,7 @@ class BufferedIteratorTest extends TestCase
      *
      * @return void
      */
-    public function testBuffer()
+    public function testBufferItems()
     {
         $items = new ArrayObject([
             'a' => 1,
@@ -67,4 +67,25 @@ class BufferedIteratorTest extends TestCase
         $buffered = $iterator->toArray();
         $this->assertSame((array)$items, $buffered);
     }
+
+    /**
+     * Tests that partial iteration can be reset.
+     *
+     * @return void
+     */
+    public function testBufferPartial()
+    {
+        $items = new ArrayObject([1, 2, 3]);
+        $iterator = new BufferedIterator($items);
+        foreach ($iterator as $key => $value) {
+            if ($key == 1) {
+                break;
+            }
+        }
+        $result = [];
+        foreach ($iterator as $value) {
+            $result[] = $value;
+        }
+        $this->assertEquals([1, 2, 3], $result);
+    }
 }