Skip to content

Commit

Permalink
feat: calling slice() on a LazyMatchingReadableCollection` now shou…
Browse files Browse the repository at this point in the history
…ld not trigger initialization of the underlying collection. (#12)

* feat: calling `slice()` on a LazyMatchingReadableCollection` now should not trigger initialization of the underlying collection.

* remove order to pass test
  • Loading branch information
priyadi authored Mar 31, 2024
1 parent 30c87b2 commit f661784
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 2.3.0

* feat: calling `slice()` on a `LazyMatchingReadableCollection` now should not
trigger initialization of the underlying collection.
* test: improve `LazyMatchingTest`

## 2.2.0
Expand Down
13 changes: 13 additions & 0 deletions src/LazyMatching/LazyMatchingReadableCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,17 @@ public function matching(Criteria $criteria): ReadableCollection&Selectable

return $clone;
}

public function slice(int $offset, ?int $length = null): array
{
if ($this->criteria === null) {
return parent::slice($offset, $length);
}

$criteria = (clone $this->criteria)
->setFirstResult($offset)
->setMaxResults($length);

return $this->matching($criteria)->toArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,13 @@ public function matching(Criteria $criteria): ReadableCollection&Selectable

return $clone;
}

public function slice(int $offset, ?int $length = null): array
{
$criteria = (clone $this->criteria)
->setFirstResult($offset)
->setMaxResults($length);

return $this->matching($criteria)->toArray();
}
}
35 changes: 35 additions & 0 deletions tests/LazyMatchingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Order;
use PHPUnit\Framework\TestCase;
use Rekalogika\Collections\Decorator\LazyMatching\LazyMatchingCollection;
use Rekalogika\Collections\Decorator\LazyMatching\LazyMatchingReadableCollection;
use Rekalogika\Collections\Decorator\Tests\Model\Book;
use Rekalogika\Collections\Decorator\Tests\Model\BookShelf;
use Rekalogika\Collections\Decorator\Tests\Model\SelectableInterceptor;
use Rekalogika\Collections\Decorator\Tests\Model\SliceInterceptor;

class LazyMatchingTest extends TestCase
{
Expand Down Expand Up @@ -122,4 +124,37 @@ public function testCriteria(): void
$result->toArray()
);
}

public function testSlice(): void
{
$bookshelf = new BookShelf();
$bookshelf->set('a', new Book('A', 100, 'Author A'));
$bookshelf->set('b', new Book('B', 200, 'Author B'));
$bookshelf->set('c', new Book('C', 300, 'Author C'));
$bookshelf->set('d', new Book('D', 50, 'Author C'));
$bookshelf->set('e', new Book('E', 20, 'Author C'));
$bookshelf->set('f', new Book('F', 500, 'Author C'));

$bookshelf = new SliceInterceptor($bookshelf);
$realBookShelf = $bookshelf;

$bookshelf = new LazyMatchingCollection($bookshelf);
$criteria = Criteria::create()
->where(Criteria::expr()->gt('numOfPages', 60));

$filtered = $bookshelf->matching($criteria);
$count = $filtered->count();
$this->assertSame(4, $count);

$sliced = $filtered->slice(1, 2);
$this->assertEquals(
[
'b' => new Book('B', 200, 'Author B'),
'c' => new Book('C', 300, 'Author C'),
],
$sliced
);

$this->assertEquals(0, $realBookShelf->getSliceCount());
}
}
35 changes: 35 additions & 0 deletions tests/Model/SliceInterceptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/doctrine-collections-decorator package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Collections\Decorator\Tests\Model;

use Rekalogika\Collections\Decorator\Decorator\SelectableCollectionDecorator;

/**
* @extends SelectableCollectionDecorator<int|string,Book>
*/
class SliceInterceptor extends SelectableCollectionDecorator
{
private int $sliceCount = 0;

public function count(): int
{
$this->sliceCount++;
return $this->getWrapped()->count();
}

public function getSliceCount(): int
{
return $this->sliceCount;
}
}

0 comments on commit f661784

Please sign in to comment.