Skip to content

Commit

Permalink
[Arr] add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
azjezz committed Dec 25, 2019
1 parent 13128b5 commit 525f5cb
Show file tree
Hide file tree
Showing 45 changed files with 944 additions and 105 deletions.
14 changes: 11 additions & 3 deletions src/Psl/Arr/count_values.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@

namespace Psl\Arr;

use Psl;
use Psl\Iter;
use Psl\Str;

/**
* Returns a new array mapping each value to the number of times it appears
* in the given iterable.
*
* @psalm-template Tv as array-key
*
* @psalm-param iterable<Tv> $values
* @psalm-param iterable<Tv> $values
*
* @psalm-return array<Tv, int>
* @psalm-return array<Tv, int>
*
* @psalm-suppress InvalidReturnStatement
* @psalm-suppress InvalidReturnType
Expand All @@ -27,8 +29,14 @@ function count_values(iterable $values): array

/** @psalm-var Tv $value */
foreach ($values as $value) {
Psl\invariant(
Str\is_string($value) || is_numeric($value),
'Expected all values to be of type array-key, value of type (%s) provided.',
gettype($value)
);

/**
* @psalm-var int
* @psalm-var int
* @psalm-suppress InvalidArgument
*/
$result[$value] = idx($result, $value, 0) + 1;
Expand Down
8 changes: 4 additions & 4 deletions src/Psl/Arr/first_key.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
* Get the first key of an array, if the array is empty, null will be returned.
*
* @psalm-template Tk as array-key
* @psalm-template Tv
*
* @psalm-param array<Tk, Tv> $array
* @psalm-param array<Tk, mixed> $array
*
* @psalm-return null|Tk
* @psalm-return Tk|null
*
* @psalm-suppress MissingReturnType
* @psalm-ignore-nullable-return
* @psalm-pure
*/
function first_key(array $array)
{
Expand Down
9 changes: 8 additions & 1 deletion src/Psl/Arr/flatten.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
namespace Psl\Arr;

/**
* Returns a new dict formed by merging the iterable elements of the
* Returns a new array formed by merging the iterable elements of the
* given iterable. In the case of duplicate keys, later values will overwrite
* the previous ones.
*
* Example:
* Arr\flatten([[1, 2], [9, 8]])
* => Arr(0 => 9, 1 => 8)
*
* Arr\flatten([[0 => 1, 1 => 2], [2 => 9, 3 => 8]])
* => Arr(0 => 1, 1 => 2, 2 => 9, 3 => 8)
*
* @psalm-template Tk as array-key
* @psalm-template Tv
*
Expand Down
15 changes: 12 additions & 3 deletions src/Psl/Arr/flip.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Psl\Arr;

use Psl;
use Psl\Str;

/**
* Flips the keys and values of an iterable. In case of
* duplicate values, later keys will overwrite the previous ones.
Expand All @@ -16,14 +19,20 @@
* @psalm-template Tk as array-key
* @psalm-template Tv as array-key
*
* @psalm-param array<Tk, Tv> $array
* @psalm-param iterable<Tk, Tv> $iterable
*
* @psalm-return array<Tv, Tk>
*/
function flip(array $array): array
function flip(iterable $iterable): array
{
$result = [];
foreach ($array as $k => $v) {
foreach ($iterable as $k => $v) {
Psl\invariant(
Str\is_string($v) || is_numeric($v),
'Expected all values to be of type array-key, value of type (%s) provided.',
gettype($v)
);

$result[$v] = $k;
}

Expand Down
9 changes: 9 additions & 0 deletions src/Psl/Arr/group_by.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace Psl\Arr;

use Psl;
use Psl\Str;

/**
* Returns a new array where
* - keys are the results of the given function called on the given values.
Expand Down Expand Up @@ -41,6 +44,12 @@ function group_by(iterable $values, callable $key_func): array
continue;
}

Psl\invariant(
Str\is_string($key) || is_numeric($key),
'Expected $key_func to return a value of type array-key, value of type (%s) returned.',
gettype($key)
);

$result[$key] = $result[$key] ?? [];
$result[$key][] = $value;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Psl/Arr/lastx.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
function lastx(array $array)
{
/** @psalm-var null|Tk $last */
$last = first_key($array);
$last = last_key($array);
Psl\invariant(null !== $last, 'Expected a non-empty array.');

/** @psalm-var Tv */
Expand Down
14 changes: 1 addition & 13 deletions src/Psl/Arr/merge.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Psl\Arr;

use Psl\Iter;

/**
* Merges multiple iterables into a new array. In the case of duplicate
* keys, later values will overwrite the previous ones.
Expand All @@ -24,18 +22,8 @@
* @psalm-param iterable<Tk, Tv> ...$rest
*
* @psalm-return array<Tk, Tv>
*
* @psalm-suppress InvalidReturnType
* @psalm-suppress InvalidReturnStatement
*/
function merge(iterable $first, iterable ...$rest): array
{
$result = is_array($first) ? $first : Iter\to_array_with_keys($first);
foreach ($rest as $iterable) {
foreach ($iterable as $k => $v) {
$result[$k] = $v;
}
}

return $result;
return flatten([$first, ...$rest]);
}
2 changes: 1 addition & 1 deletion src/Psl/Arr/random.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
function random(array $values)
{
Psl\invariant(!Iter\is_empty($values), 'Expected non-empty-array');
Psl\invariant(!Iter\is_empty($values), 'Expected non-empty-array.');

/** @psalm-var array<int, Tv> $shuffled */
$shuffled = shuffle($values);
Expand Down
4 changes: 1 addition & 3 deletions src/Psl/Arr/sort_by.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ function sort_by(iterable $iterable, callable $scalar_func, ?callable $comparato
* @psalm-param Tk $k
* @psalm-param Ts $_
*/
static function ($k, $_) use ($values) {
return $values[$k];
}
fn ($k, $_) => $values[$k]
));
}
4 changes: 2 additions & 2 deletions src/Psl/Arr/sort_by_key.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
*
* @psalm-return array<Tk, Tv>
*/
function sort_by_key(iterable $traversable, ?callable $comparator = null): array
function sort_by_key(iterable $iterable, ?callable $comparator = null): array
{
$result = Iter\to_array($traversable);
$result = Iter\to_array_with_keys($iterable);
if ($comparator) {
\uksort($result, $comparator);
} else {
Expand Down
26 changes: 9 additions & 17 deletions src/Psl/Arr/sort_with_keys_by.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
* @psalm-template Tv
* @psalm-template Ts
*
* @psalm-param iterable<Tk, Tv> $iterable
* @psalm-param iterable<Tk, Tv> $iterable
* @psalm-param (callable(Tv): Ts) $scalar_func
* @psalm-param null|(callable(Ts, Ts): int) $comparator
* @psalm-param null|(callable(Ts, Ts): int) $comparator
*
* @plsam-return array<Tk, Tv>
* @plsam-return array<Tk, Tv>
*/
function sort_with_keys_by(iterable $iterable, callable $scalar_func, ?callable $comparator = null): array
{
Expand All @@ -30,43 +30,35 @@ function sort_with_keys_by(iterable $iterable, callable $scalar_func, ?callable
* @psalm-param array{0: Ts, 1: Tv} $a
* @psalm-param array{0: Ts, 1: Tv} $b
*/
static function ($a, $b) use ($comparator): int {
return $comparator($a[0], $b[0]);
};
fn ($a, $b) => $comparator($a[0], $b[0]);
} else {
$tuple_comparator =
/**
* @psalm-param array{0: Ts, 1: Tv} $a
* @psalm-param array{0: Ts, 1: Tv} $b
*/
static function ($a, $b): int {
return $a[0] <=> $b[0];
};
fn ($a, $b) => $a[0] <=> $b[0];
}

$result = Iter\map(
sort_with_keys(
Iter\map(
$iterable,
/**
* @psalm-param Tv $value
* @psalm-param Tv $value
*
* @psalm-return array{0: Ts, 1: Tv}
*/
static function ($value) use ($scalar_func): array {
return [$scalar_func($value), $value];
}
fn ($value) => [$scalar_func($value), $value],
),
$tuple_comparator
),
/**
* @psalm-param array{0: Ts, 1: Tv} $t
* @psalm-param array{0: Ts, 1: Tv} $t
*
* @psalm-return Tv
*/
static function ($t) {
return $t[1];
}
fn ($t) => $t[1]
);

return Iter\to_array($result);
Expand Down
24 changes: 12 additions & 12 deletions src/Psl/Arr/unique.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@

namespace Psl\Arr;

use Psl\Iter;

/**
* Returns a new array in which each value appears exactly once. In case of
* duplicate values, later keys will overwrite the previous ones.
*
* @psalm-template Tk as array-key
* @psalm-template Tv
*
* @psalm-param array<Tk, Tv> $iterable
* @psalm-param iterable<Tk, Tv> $iterable
*
* @psalm-return array<Tk, Tv>
*/
function unique(array $iterable): array
function unique(iterable $iterable): array
{
/** @psalm-var array<Tk, Tv> */
return Iter\to_array_with_keys(
/** @psalm-var iterable<Tk, Tv> */
Iter\flip(
/** @psalm-var iterable<Tv, Tk> */
Iter\flip($iterable)
)
);
/** @psalm-var array<Tk, Tv> $unique */
$unique = [];

foreach ($iterable as $value) {
if (!contains($unique, $value)) {
$unique[] = $value;
}
}

return $unique;
}
19 changes: 6 additions & 13 deletions src/Psl/Arr/unique_by.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,28 @@ function unique_by(array $iterable, callable $scalar_func): array
*
* @psalm-return Tk
*/
static function ($k, $_) {
return $k;
},
fn ($k, $_) => $k,

/**
* @psalm-param Tk $_
* @psalm-param Tv $v
*
* @psalm-return Ts
*/
static function ($_, $v) use ($scalar_func) {
return $scalar_func($v);
}
fn ($_, $v) => $scalar_func($v),
),
/**
* @psalm-param Tk $orig_key
*
* @psalm-return Tv
*/
static function ($orig_key) use ($iterable) {
/** @psalm-var Tv */
return $iterable[$orig_key];
},
fn ($orig_key) => $iterable[$orig_key],

/**
* @psalm-param Tk $x
*
* @psalm-return Tk
*/
static function ($x) {
return $x;
}
fn ($x) => $x
));
}
28 changes: 27 additions & 1 deletion tests/Psl/Arr/AtTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,34 @@
namespace Psl\Tests\Arr;

use PHPUnit\Framework\TestCase;
use Psl\Arr;
use Psl\Exception;

class AtTest extends TestCase
{
// TODO: add tests.
/**
* @dataProvider provideData
*/
public function testAt($expected, array $array, $key): void
{
static::assertSame($expected, Arr\at($array, $key));
}

public function provideData(): array
{
return [
[5, ['a' => 4, 'b' => 5], 'b'],
[0, [0, 1], 0],
[1, [1, 2], 0],
[null, [null], 0],
];
}

public function testAtThrowsForOutOfBoundKey(): void
{
$this->expectException(Exception\InvariantViolationException::class);
$this->expectExceptionMessage('key (5) was out-of-bound');

Arr\at([], 5);
}
}
Loading

0 comments on commit 525f5cb

Please sign in to comment.