Skip to content

Commit

Permalink
Merge pull request #6 from boesing/qa/out-of-bounds-exception-in-favo…
Browse files Browse the repository at this point in the history
…r-of-null
  • Loading branch information
boesing committed Oct 21, 2020
2 parents b57ccea + 6ec46a2 commit cc3b0a0
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 15 deletions.
7 changes: 5 additions & 2 deletions src/ArrayInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Countable;
use IteratorAggregate;
use OutOfBoundsException;

/**
* @internal
Expand All @@ -23,14 +24,16 @@ interface ArrayInterface extends IteratorAggregate, Countable
public function contains($element): bool;

/**
* @psalm-return TValue|null
* @psalm-return TValue
* @psalm-mutation-free
* @throws OutOfBoundsException if there are no values available.
*/
public function first();

/**
* @psalm-return TValue|null
* @psalm-return TValue
* @psalm-mutation-free
* @throws OutOfBoundsException if there are no values available.
*/
public function last();

Expand Down
9 changes: 5 additions & 4 deletions src/Array_.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use ArrayIterator;
use DateTimeInterface;
use OutOfBoundsException;
use Traversable;
use Webmozart\Assert\Assert;

Expand Down Expand Up @@ -59,8 +60,8 @@ public function contains($element): bool
*/
public function first()
{
if ($this->data === []) {
return null;
if ($this->isEmpty()) {
throw new OutOfBoundsException('There are no values available.');
}

return reset($this->data);
Expand All @@ -71,8 +72,8 @@ public function first()
*/
public function last()
{
if ($this->data === []) {
return null;
if ($this->isEmpty()) {
throw new OutOfBoundsException('There are no values available.');
}

return end($this->data);
Expand Down
9 changes: 8 additions & 1 deletion src/Map.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace Boesing\TypedArrays;

use OutOfBoundsException;
use Webmozart\Assert\Assert;

use function array_diff_ukey;
use function array_filter;
use function array_intersect_ukey;
use function array_key_exists;
use function array_keys;
use function array_map;
use function array_merge;
Expand All @@ -17,6 +19,7 @@
use function array_uintersect_uassoc;
use function array_values;
use function asort;
use function sprintf;
use function uasort;
use function usort;

Expand Down Expand Up @@ -138,7 +141,11 @@ public function put($key, $value): MapInterface
*/
public function get($key)
{
return $this->data[$key] ?? null;
if (! array_key_exists($key, $this->data)) {
throw new OutOfBoundsException(sprintf('There is no value stored for provided key: %s', (string) $key));
}

return $this->data[$key];
}

public function intersect(MapInterface $other, ?callable $valueComparator = null): MapInterface
Expand Down
5 changes: 4 additions & 1 deletion src/MapInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Boesing\TypedArrays;

use OutOfBoundsException;

/**
* @template TValue
* @template-extends ArrayInterface<string,TValue>
Expand Down Expand Up @@ -91,7 +93,8 @@ public function put($key, $value): MapInterface;

/**
* @psalm-param string $key
* @psalm-return TValue|null
* @psalm-return TValue
* @throws OutOfBoundsException if key does not exist.
* @psalm-mutation-free
*/
public function get($key);
Expand Down
14 changes: 12 additions & 2 deletions src/OrderedList.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use function array_combine;
use function array_fill;
use function array_filter;
use function array_key_exists;
use function array_keys;
use function array_map;
use function array_merge;
Expand All @@ -23,6 +24,7 @@
use function is_callable;
use function serialize;
use function sort;
use function sprintf;
use function usort;

use const SORT_NATURAL;
Expand Down Expand Up @@ -76,7 +78,11 @@ public function add($element): OrderedListInterface
*/
public function at(int $position)
{
return $this->data[$position] ?? null;
if (! array_key_exists($position, $this->data)) {
throw new OutOfBoundsException(sprintf('There is no value stored in that position: %d', $position));
}

return $this->data[$position];
}

public function sort(?callable $callback = null): OrderedListInterface
Expand Down Expand Up @@ -187,7 +193,11 @@ public function unify(

foreach ($instance->data as $value) {
$identifier = $unificationIdentifierGenerator($value);
$unique = $unified->get($identifier) ?? $value;
try {
$unique = $unified->get($identifier);
} catch (OutOfBoundsException $exception) {
$unique = $value;
}

if ($callback) {
$unique = $callback($unique, $value);
Expand Down
3 changes: 2 additions & 1 deletion src/OrderedListInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ interface OrderedListInterface extends ArrayInterface
public function add($element): OrderedListInterface;

/**
* @psalm-return TValue|null
* @psalm-return TValue
* @throws OutOfBoundsException If position does not exist.
* @psalm-mutation-free
*/
public function at(int $position);
Expand Down
8 changes: 8 additions & 0 deletions tests/GenericMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use DateTimeImmutable;
use Generator;
use Lcobucci\Clock\FrozenClock;
use OutOfBoundsException;
use PHPUnit\Framework\TestCase;
use stdClass;

Expand Down Expand Up @@ -459,4 +460,11 @@ public function testCanIntersectWithUserFunctions(): void
->toNativeArray()
);
}

public function testGetThrowsOutOfBoundsExceptionWhenKeyDoesNotExist(): void
{
$map = new GenericMap([]);
$this->expectException(OutOfBoundsException::class);
$map->get('foo');
}
}
16 changes: 12 additions & 4 deletions tests/GenericOrderedListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ public function testReturnsNullWhenSpecificItemNotFound(): void
{
$list = new GenericOrderedList([]);

self::assertNull($list->at(0));
$this->expectException(OutOfBoundsException::class);
$list->at(0);
}

/**
Expand Down Expand Up @@ -631,11 +632,18 @@ public function testFirstAndLastElementReturnsIdenticalObject(): void
self::assertEquals($object2, $list->last());
}

public function testFirstAndLastReturnNullOnEmptyList(): void
public function testFirstThrowsOutOfBoundsExceptionWhenListIsEmpty(): void
{
$list = new GenericOrderedList([]);
self::assertNull($list->first());
self::assertNull($list->last());
$this->expectException(OutOfBoundsException::class);
$list->first();
}

public function testLastThrowsOutOfBoundsExceptionWhenListIsEmpty(): void
{
$list = new GenericOrderedList([]);
$this->expectException(OutOfBoundsException::class);
$list->last();
}

public function testContainsDoesExactMatch(): void
Expand Down

0 comments on commit cc3b0a0

Please sign in to comment.