From 08588d2ec3a95aa6d9436f382eedf610c035ec0f Mon Sep 17 00:00:00 2001 From: Bl00D4NGEL Date: Tue, 30 Jan 2024 13:54:01 +0100 Subject: [PATCH 1/2] feat: add find and findLast functions --- src/Domain/Collection.php | 39 ++++++++++++++++++++++++- tests/Domain/CollectionTest.php | 50 +++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/src/Domain/Collection.php b/src/Domain/Collection.php index f1d99e2..0ceffd1 100644 --- a/src/Domain/Collection.php +++ b/src/Domain/Collection.php @@ -23,13 +23,14 @@ /** * @template T of object * @implements IteratorAggregate - * @implements ArrayAccess + * @implements ArrayAccess */ class Collection implements ArrayAccess, Countable, IteratorAggregate { /** * @param T[] $items * @param class-string|null $itemType + * @throws Assert\AssertionFailedException */ final public function __construct( private readonly array $items = [], @@ -131,6 +132,42 @@ public function some(callable $callback = null): bool return false; } + /** + * Returns the first element of the collection that matches the given callback or null if the collection is empty + * or the callback never returned true for any item + * + * @param callable(T, int, static): bool $callback + * @return ?T + */ + public function find(callable $callback) + { + foreach ($this->items as $index => $item) { + if ($callback($item, $index, $this)) { + return $item; + } + } + + return null; + } + + /** + * Returns the last element of the collection that matches the given callback or null if the collection is empty + * or the callback never returned true for any item + * + * @param callable(T, int, static): bool $callback + * @return ?T + */ + public function findLast(callable $callback) + { + foreach (array_reverse($this->items) as $index => $item) { + if ($callback($item, $index, $this)) { + return $item; + } + } + + return null; + } + /** * Returns the first element of the collection that matches the given callback. * If no callback is given the first element in the collection is returned. diff --git a/tests/Domain/CollectionTest.php b/tests/Domain/CollectionTest.php index ded3457..5e42dea 100644 --- a/tests/Domain/CollectionTest.php +++ b/tests/Domain/CollectionTest.php @@ -433,6 +433,52 @@ public function testSomeShortCircuitsOnFirstFalsyValue(): void }); } + public function testFind(): void + { + $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + $collection = new Collection($items); + + $this->assertSame(3, $collection->find(static fn ($item) => $item > 2)); + } + + public function testFindReturnsNullIfCallbackNeverReturnsTrue(): void + { + $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + $collection = new Collection($items); + + $this->assertSame(null, $collection->find(static fn () => false)); + } + + public function testFindReturnsNullOnEmptyCollection(): void + { + $collection = new Collection([]); + + $this->assertSame(null, $collection->find(static fn () => true)); + } + + public function testFindLast(): void + { + $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + $collection = new Collection($items); + + $this->assertSame(10, $collection->findLast(static fn ($item) => $item > 2)); + } + + public function testFindLastReturnsNullIfCallbackNeverReturnsTrue(): void + { + $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + $collection = new Collection($items); + + $this->assertSame(null, $collection->findLast(static fn () => false)); + } + + public function testFindLastReturnsNullOnEmptyCollection(): void + { + $collection = new Collection([]); + + $this->assertSame(null, $collection->find(static fn () => true)); + } + public function testFirst(): void { $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -477,7 +523,7 @@ public function testFirstOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): voi { $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; $collection = new Collection($items); - $this->assertSame(-1, $collection->firstOr(static fn ($item) => $item > 10, -1)); + $this->assertSame(-1, $collection->firstOr(static fn () => false, -1)); } public function testLast(): void @@ -524,7 +570,7 @@ public function testLastOrReturnsFallbackValueIfCallbackIsNeverSatisfied(): void { $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; $collection = new Collection($items); - $this->assertSame(-1, $collection->lastOr(static fn ($item) => $item > 10, -1)); + $this->assertSame(-1, $collection->lastOr(static fn () => false, -1)); } public function testIsEmpty(): void From 01e21949130a5e30e361f4626ef80c3b85622055 Mon Sep 17 00:00:00 2001 From: Bl00D4NGEL Date: Fri, 9 Feb 2024 08:15:32 +0100 Subject: [PATCH 2/2] ci: remove sonarcloud action while SONAR_TOKEN is not set --- .github/workflows/tests.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 909efbc..e739e31 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,12 +38,4 @@ jobs: # Run tests - name: Run Unit Tests - run: | - vendor/bin/phpunit --coverage-text --coverage-clover reports/coverage.xml - - # SonarCloud - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: vendor/bin/phpunit