Skip to content

Commit

Permalink
Merge pull request #7 from boesing/feature/find-in-list
Browse files Browse the repository at this point in the history
  • Loading branch information
boesing committed Oct 21, 2020
2 parents ed1192a + 11d1795 commit b57ccea
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/OrderedList.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Boesing\TypedArrays;

use Closure;
use OutOfBoundsException;
use Webmozart\Assert\Assert;

use function array_combine;
Expand Down Expand Up @@ -253,4 +255,18 @@ public function slice(int $offset, ?int $length = null): OrderedListInterface

return $instance;
}

/**
* @psalm-mutation-free
*/
public function find(callable $callback)
{
foreach ($this->data as $value) {
if ($callback($value)) {
return $value;
}
}

throw new OutOfBoundsException('Could not find value with provided callback.');
}
}
9 changes: 9 additions & 0 deletions src/OrderedListInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Boesing\TypedArrays;

use InvalidArgumentException;
use OutOfBoundsException;

/**
* @template TValue
Expand Down Expand Up @@ -98,4 +99,12 @@ public function fill(int $startIndex, int $amount, $value): OrderedListInterface
* @psalm-mutation-free
*/
public function slice(int $offset, ?int $length = null): OrderedListInterface;

/**
* @psalm-param Closure(TValue $value):bool $callback
* @psalm-return TValue
* @psalm-mutation-free
* @throws OutOfBoundsException if value could not be found with provided callback.
*/
public function find(callable $callback);
}
51 changes: 51 additions & 0 deletions tests/GenericOrderedListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Generator;
use InvalidArgumentException;
use Lcobucci\Clock\FrozenClock;
use OutOfBoundsException;
use PHPUnit\Framework\TestCase;
use stdClass;
use Webmozart\Assert\Assert;
Expand Down Expand Up @@ -850,4 +851,54 @@ public function testSliceCanLimitResultForNegativeOffset(): void

self::assertEquals([2], $sliced->toNativeArray());
}

/**
* @template TValue
* @psalm-param list<TValue> $initial
* @psalm-param Closure(TValue $value):bool $callback
* @dataProvider findOutOfBoundExceptions
*/
public function testFindThrowsOutOfBoundsExceptionWhenValueNotFound(array $initial, callable $callback): void
{
$instance = new GenericOrderedList($initial);
$this->expectException(OutOfBoundsException::class);
$instance->find($callback);
}

/**
* @psalm-return Generator<string,array{0:list<mixed>,1:(Closure(mixed $value):bool)}>
*/
public function findOutOfBoundExceptions(): Generator
{
yield 'empty list' => [
[],
static function (): bool {
return true;
},
];

yield 'non-empty list but finding impossible' => [
[1, 2, 3],
static function (): bool {
return false;
},
];
}

public function testFindWillLocateFirstMatch(): void
{
$list = new GenericOrderedList([
['id' => 1, 'position' => 1],
['id' => 1, 'position' => 2],
]);

$value = $list->find(static function (array $value) {
return $value['id'] === 1;
});

self::assertEquals([
'id' => 1,
'position' => 1,
], $value);
}
}

0 comments on commit b57ccea

Please sign in to comment.