From f5a13734e1518693376421e4d479fab4291e186e Mon Sep 17 00:00:00 2001 From: Aleksei Lebedev <1329824+LastDragon-ru@users.noreply.github.com> Date: Sun, 4 Dec 2022 10:10:55 +0400 Subject: [PATCH] feat(eloquent): `IteratorImpl` (= all iterators) will implement `Countable`. --- .../eloquent/src/Iterators/ChunkedChangeSafeIterator.php | 2 +- .../src/Iterators/ChunkedChangeSafeIteratorTest.php | 4 +++- packages/eloquent/src/Iterators/ChunkedIteratorTest.php | 2 ++ packages/eloquent/src/Iterators/IteratorImpl.php | 8 +++++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/eloquent/src/Iterators/ChunkedChangeSafeIterator.php b/packages/eloquent/src/Iterators/ChunkedChangeSafeIterator.php index ad7a15633..32812b5b7 100644 --- a/packages/eloquent/src/Iterators/ChunkedChangeSafeIterator.php +++ b/packages/eloquent/src/Iterators/ChunkedChangeSafeIterator.php @@ -44,7 +44,7 @@ public function __construct(Builder $builder, string $column = null) { // it just adds conditional to the main query, and this leads to an // infinite loop. if ($this->hasUnions()) { - throw new InvalidArgumentException('Queries with UNION is not supported.'); + throw new InvalidArgumentException('Query with UNION is not supported.'); } } diff --git a/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php b/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php index b9f73f15e..7fd61e0ba 100644 --- a/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php +++ b/packages/eloquent/src/Iterators/ChunkedChangeSafeIteratorTest.php @@ -29,6 +29,7 @@ class ChunkedChangeSafeIteratorTest extends TestCase { * @covers ::getIterator * @covers ::getOffset * @covers ::getIndex + * @covers ::count */ public function testGetIterator(): void { TestObject::factory()->create(['value' => '1']); @@ -74,6 +75,7 @@ public function testGetIterator(): void { self::assertEquals(count($expected), $iterator->getIndex()); self::assertEquals(count($expected), $iterator->getOffset()); + self::assertEquals(4, count($iterator)); $spyBefore ->shouldHaveBeenCalled() @@ -133,7 +135,7 @@ public function testGetIteratorEloquentDefaults(string $column): void { * @covers ::getIterator */ public function testGetIteratorUnion(): void { - self::expectExceptionObject(new InvalidArgumentException('Queries with UNION is not supported.')); + self::expectExceptionObject(new InvalidArgumentException('Query with UNION is not supported.')); new ChunkedChangeSafeIterator(TestObject::query()->union(TestObject::query()->toBase())); } diff --git a/packages/eloquent/src/Iterators/ChunkedIteratorTest.php b/packages/eloquent/src/Iterators/ChunkedIteratorTest.php index 2e01d42bf..5b450cf67 100644 --- a/packages/eloquent/src/Iterators/ChunkedIteratorTest.php +++ b/packages/eloquent/src/Iterators/ChunkedIteratorTest.php @@ -23,6 +23,7 @@ class ChunkedIteratorTest extends TestCase { * @covers ::getIterator * @covers ::getOffset * @covers ::getIndex + * @covers ::count */ public function testGetIterator(): void { TestObject::factory()->create(['value' => '1']); @@ -50,6 +51,7 @@ public function testGetIterator(): void { self::assertEquals(2, count($log) - $count); self::assertEquals(count($expected), $iterator->getIndex()); self::assertEquals(count($expected), $iterator->getOffset()); + self::assertEquals(3, count($iterator)); $spyBefore ->shouldHaveBeenCalled() diff --git a/packages/eloquent/src/Iterators/IteratorImpl.php b/packages/eloquent/src/Iterators/IteratorImpl.php index 4dce90c94..57bba3e42 100644 --- a/packages/eloquent/src/Iterators/IteratorImpl.php +++ b/packages/eloquent/src/Iterators/IteratorImpl.php @@ -3,12 +3,14 @@ namespace LastDragon_ru\LaraASP\Eloquent\Iterators; use Closure; +use Countable; use EmptyIterator; use Generator; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; use LastDragon_ru\LaraASP\Core\Observer\Dispatcher; +use function max; use function min; /** @@ -18,7 +20,7 @@ * * @internal */ -abstract class IteratorImpl implements Iterator { +abstract class IteratorImpl implements Iterator, Countable { /** * @var Dispatcher> */ @@ -191,4 +193,8 @@ protected function getDefaultOffset(): ?int { protected function getBuilder(): Builder { return $this->builder; } + + public function count(): int { + return max(0, $this->getBuilder()->toBase()->count()); + } }