diff --git a/src/Map.php b/src/Map.php index 02035db..3fc3d43 100644 --- a/src/Map.php +++ b/src/Map.php @@ -139,10 +139,10 @@ public function put($key, $value): MapInterface /** * @psalm-mutation-free */ - public function get($key) + public function get(string $key) { - if (! array_key_exists($key, $this->data)) { - throw new OutOfBoundsException(sprintf('There is no value stored for provided key: %s', (string) $key)); + if (! $this->has($key)) { + throw new OutOfBoundsException(sprintf('There is no value stored for provided key: %s', $key)); } return $this->data[$key]; @@ -267,4 +267,12 @@ public function map(callable $callback): MapInterface { return new GenericMap(array_map($callback, $this->data)); } + + /** + * @psalm-mutation-free + */ + public function has(string $key): bool + { + return array_key_exists($key, $this->data); + } } diff --git a/src/MapInterface.php b/src/MapInterface.php index cdf402a..2ba39e7 100644 --- a/src/MapInterface.php +++ b/src/MapInterface.php @@ -92,12 +92,11 @@ public function keys(): OrderedListInterface; public function put($key, $value): MapInterface; /** - * @psalm-param string $key * @psalm-return TValue * @throws OutOfBoundsException if key does not exist. * @psalm-mutation-free */ - public function get($key); + public function get(string $key); /** * @psalm-param MapInterface $other @@ -124,4 +123,9 @@ public function intersectUserAssoc( ?callable $valueComparator = null, ?callable $keyComparator = null ): MapInterface; + + /** + * @psalm-mutation-free + */ + public function has(string $key): bool; } diff --git a/tests/GenericMapTest.php b/tests/GenericMapTest.php index f47c56d..0513d1d 100644 --- a/tests/GenericMapTest.php +++ b/tests/GenericMapTest.php @@ -467,4 +467,23 @@ public function testGetThrowsOutOfBoundsExceptionWhenKeyDoesNotExist(): void $this->expectException(OutOfBoundsException::class); $map->get('foo'); } + + public function testHasDetectsExistingKey(): void + { + $map = new GenericMap(['foo' => 'bar']); + + self::assertTrue($map->has('foo')); + } + + public function testHasReturnsFalseOnEmptyMap(): void + { + $map = new GenericMap([]); + self::assertFalse($map->has('foo')); + } + + public function testHasReturnsFalseForDueToCaseSensitivity(): void + { + $map = new GenericMap(['foo' => 'bar']); + self::assertFalse($map->has('Foo')); + } }