diff --git a/src/Illuminate/Collections/LazyCollection.php b/src/Illuminate/Collections/LazyCollection.php index 6ccd10abb1e1..2a9b93c46ce1 100644 --- a/src/Illuminate/Collections/LazyCollection.php +++ b/src/Illuminate/Collections/LazyCollection.php @@ -1414,18 +1414,16 @@ public function takeUntilTimeout(DateTimeInterface $timeout) $timeout = $timeout->getTimestamp(); return new static(function () use ($timeout) { - $iterator = $this->getIterator(); - - if (! $iterator->valid() || $this->now() > $timeout) { + if ($this->now() >= $timeout) { return; } - yield $iterator->key() => $iterator->current(); - - while ($iterator->valid() && $this->now() < $timeout) { - $iterator->next(); + foreach ($this as $key => $value) { + yield $key => $value; - yield $iterator->key() => $iterator->current(); + if ($this->now() >= $timeout) { + break; + } } }); } diff --git a/tests/Support/SupportLazyCollectionIsLazyTest.php b/tests/Support/SupportLazyCollectionIsLazyTest.php index ac5a987573e6..24072d4cf9c9 100644 --- a/tests/Support/SupportLazyCollectionIsLazyTest.php +++ b/tests/Support/SupportLazyCollectionIsLazyTest.php @@ -3,9 +3,11 @@ namespace Illuminate\Tests\Support; use Exception; +use Illuminate\Support\Carbon; use Illuminate\Support\ItemNotFoundException; use Illuminate\Support\LazyCollection; use Illuminate\Support\MultipleItemsFoundException; +use Mockery as m; use PHPUnit\Framework\TestCase; use stdClass; @@ -1214,6 +1216,72 @@ public function testTakeUntilIsLazy() }); } + public function testTakeUntilTimeoutIsLazy() + { + tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) { + $this->assertDoesNotEnumerateCollection($mock, function ($mock) { + $timeout = Carbon::now(); + + $results = $mock + ->tap(function ($collection) use ($mock, $timeout) { + tap($collection) + ->mockery_init($mock->mockery_getContainer()) + ->shouldAllowMockingProtectedMethods() + ->shouldReceive('now') + ->times(1) + ->andReturn( + $timeout->getTimestamp() + ); + }) + ->takeUntilTimeout($timeout) + ->all(); + }); + }); + + tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) { + $this->assertEnumeratesCollection($mock, 1, function ($mock) { + $timeout = Carbon::now(); + + $results = $mock + ->tap(function ($collection) use ($mock, $timeout) { + tap($collection) + ->mockery_init($mock->mockery_getContainer()) + ->shouldAllowMockingProtectedMethods() + ->shouldReceive('now') + ->times(2) + ->andReturn( + (clone $timeout)->sub(1, 'minute')->getTimestamp(), + $timeout->getTimestamp() + ); + }) + ->takeUntilTimeout($timeout) + ->all(); + }); + }); + + tap(m::mock(LazyCollection::class.'[now]')->times(100), function ($mock) { + $this->assertEnumeratesCollectionOnce($mock, function ($mock) { + $timeout = Carbon::now(); + + $results = $mock + ->tap(function ($collection) use ($mock, $timeout) { + tap($collection) + ->mockery_init($mock->mockery_getContainer()) + ->shouldAllowMockingProtectedMethods() + ->shouldReceive('now') + ->times(100) + ->andReturn( + (clone $timeout)->sub(1, 'minute')->getTimestamp() + ); + }) + ->takeUntilTimeout($timeout) + ->all(); + }); + }); + + m::close(); + } + public function testTakeWhileIsLazy() { $this->assertDoesNotEnumerate(function ($collection) { diff --git a/tests/Support/SupportLazyCollectionTest.php b/tests/Support/SupportLazyCollectionTest.php index b34438a2666d..51002dad66a9 100644 --- a/tests/Support/SupportLazyCollectionTest.php +++ b/tests/Support/SupportLazyCollectionTest.php @@ -196,32 +196,6 @@ public function testTakeUntilTimeout() m::close(); } - public function testTakeUntilTimeoutWithPastTimeout() - { - $timeout = Carbon::now()->subMinute(); - - $mock = m::mock(LazyCollection::class.'[now]'); - - $results = $mock - ->times(10) - ->tap(function ($collection) use ($mock, $timeout) { - tap($collection) - ->mockery_init($mock->mockery_getContainer()) - ->shouldAllowMockingProtectedMethods() - ->shouldReceive('now') - ->times(1) - ->andReturn( - (clone $timeout)->add(1, 'minute')->getTimestamp(), - ); - }) - ->takeUntilTimeout($timeout) - ->all(); - - $this->assertSame([], $results); - - m::close(); - } - public function testTapEach() { $data = LazyCollection::times(10);