mirror of
https://github.com/danog/endtoend-test-psl.git
synced 2024-12-02 09:38:32 +01:00
[Iter] add more tests
This commit is contained in:
parent
468971ea22
commit
0e70ce0af5
@ -56,6 +56,10 @@ final class Iterator implements SeekableIterator, Countable
|
||||
*/
|
||||
public static function create(iterable $iterable): Iterator
|
||||
{
|
||||
if ($iterable instanceof Generator) {
|
||||
return new self($iterable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-var (callable(): Generator<Tsk, Tsv, mixed, void>) $factory
|
||||
*/
|
||||
@ -143,7 +147,8 @@ final class Iterator implements SeekableIterator, Countable
|
||||
*/
|
||||
public function rewind(): void
|
||||
{
|
||||
$this->position = 0;
|
||||
/** @psalm-suppress MissingThrowsDocblock - 0 is within bound. */
|
||||
$this->seek(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,16 +157,15 @@ final class Iterator implements SeekableIterator, Countable
|
||||
public function seek(int $position): void
|
||||
{
|
||||
Psl\invariant($position >= 0, 'Position is out-of-bounds.');
|
||||
|
||||
if ($position <= $this->position) {
|
||||
if (0 === $position || $position <= $this->position) {
|
||||
$this->position = $position;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->generator) {
|
||||
while ($this->position !== $position) {
|
||||
Psl\invariant($this->generator->valid(), 'Position is out-of-bounds.');
|
||||
$this->next();
|
||||
Psl\invariant($this->valid(), 'Position is out-of-bounds.');
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -35,7 +35,7 @@ function product(iterable ...$iterables): Iterator
|
||||
/** @psalm-var list<Iterator<Tk, Tv>> $iterators */
|
||||
$iterators = to_array(map(
|
||||
$iterables,
|
||||
fn (iterable $iterable) => new Iterator((fn () => yield from $iterable)())
|
||||
fn (iterable $iterable) => Iterator::create($iterable)
|
||||
));
|
||||
|
||||
$numIterators = count($iterators);
|
||||
@ -54,9 +54,11 @@ function product(iterable ...$iterables): Iterator
|
||||
while (true) {
|
||||
while (++$i < $numIterators - 1) {
|
||||
$iterators[$i]->rewind();
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!$iterators[$i]->valid()) {
|
||||
return;
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$keyTuple[$i] = $iterators[$i]->key();
|
||||
$valueTuple[$i] = $iterators[$i]->current();
|
||||
|
@ -20,8 +20,8 @@ use Psl\Internal;
|
||||
* fn($i) => 2**$i,
|
||||
* )
|
||||
* => Iter(
|
||||
* 0 => 'A', 2 => 'C', 4 => 'D', 8 => 'E', 16 => 'F', 32 => 'G',
|
||||
* 64 => 'H', 124 => 'I', 256 => 'J', 512 => 'K', 1024 => 'L'
|
||||
* 1 => 'A', 2 => 'B', 4 => 'C', 8 => 'D', 16 => 'E', 32 => 'F',
|
||||
* 64 => 'G', 128 => 'H', 256 => 'I', 512 => 'J', 1024 => 'K'
|
||||
* )
|
||||
*
|
||||
*
|
||||
|
@ -14,14 +14,14 @@ use Psl\Internal;
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Iter\pull(
|
||||
* Iter\pull_with_key(
|
||||
* Iter\range(0, 10),
|
||||
* fn($k, $v) => Str\chr($v + 65),
|
||||
* fn($k, $v) => $k + (2**$v),
|
||||
* fn($k, $v) => Str\chr($v + $k + 65),
|
||||
* fn($k, $v) => 2**($v+$k)
|
||||
* )
|
||||
* => Iter(
|
||||
* 0 => 'A', 3 => 'C', 6 => 'D', 11 => 'E', 20 => 'F', 37 => 'G',
|
||||
* 70 => 'H', 131 => 'I', 264 => 'J', 521 => 'K', 1034 => 'L'
|
||||
* 1 => 'A', 4 => 'C', 16 => 'E', 64 => 'G', 256 => 'I', 1024 => 'K',
|
||||
* 4096 => 'M', 16384 => 'O', 65536 => 'Q', 262144 => 'S', 1048576 => 'U'
|
||||
* )
|
||||
*
|
||||
* @psalm-template Tk1
|
||||
|
@ -21,8 +21,14 @@ use Psl\Arr;
|
||||
*/
|
||||
function random(iterable $iterable)
|
||||
{
|
||||
Psl\invariant(!is_empty($iterable), 'Expected a non-empty iterable.');
|
||||
// We convert the iterable to an array before checking if it is empty,
|
||||
// this helps us avoids an issue when the iterable is a generator where
|
||||
// would exhaust it when calling `is_empty`, which results in an
|
||||
// exception at the `to_array` call.
|
||||
$array = to_array($iterable);
|
||||
|
||||
Psl\invariant(!is_empty($array), 'Expected a non-empty iterable.');
|
||||
|
||||
/** @psalm-var Tv */
|
||||
return Arr\random(to_array($iterable));
|
||||
return Arr\random($array);
|
||||
}
|
||||
|
@ -40,6 +40,14 @@ use Psl\Internal;
|
||||
*/
|
||||
function range($start, $end, $step = null): Iterator
|
||||
{
|
||||
if ($start < $end) {
|
||||
Psl\invariant($step === null || $step > 0, 'If start < end, the step must be positive.');
|
||||
}
|
||||
|
||||
if ($start > $end) {
|
||||
Psl\invariant($step === null || $step < 0, 'If start > end, the step must be negative.');
|
||||
}
|
||||
|
||||
return Internal\lazy_iterator(
|
||||
/**
|
||||
* @return Generator<int, T, mixed, void>
|
||||
@ -58,8 +66,6 @@ function range($start, $end, $step = null): Iterator
|
||||
if (null === $step) {
|
||||
/** @psalm-var T $step */
|
||||
$step = 1;
|
||||
} else {
|
||||
Psl\invariant($step > 0, 'If start < end, the step must be positive');
|
||||
}
|
||||
|
||||
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
|
||||
@ -72,8 +78,6 @@ function range($start, $end, $step = null): Iterator
|
||||
if (null === $step) {
|
||||
/** @psalm-var T $step */
|
||||
$step = -1;
|
||||
} else {
|
||||
Psl\invariant($step < 0, 'If start > end, the step must be negative');
|
||||
}
|
||||
|
||||
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
|
||||
|
@ -32,7 +32,7 @@ use Psl\Math;
|
||||
*/
|
||||
function repeat($value, ?int $num = null): Iterator
|
||||
{
|
||||
Psl\invariant(null === $num || $num >= 0, 'Number of repetitions must be non-negative');
|
||||
Psl\invariant(null === $num || $num >= 0, 'Number of repetitions must be non-negative.');
|
||||
|
||||
return Internal\lazy_iterator(static function () use ($value, $num): Generator {
|
||||
if (null === $num) {
|
||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace Psl\Iter;
|
||||
|
||||
use Generator;
|
||||
use Psl\Arr;
|
||||
use Psl\Internal;
|
||||
|
||||
/**
|
||||
@ -23,18 +24,14 @@ use Psl\Internal;
|
||||
function reverse(iterable $iterable): Iterator
|
||||
{
|
||||
return Internal\lazy_iterator(static function () use ($iterable): Generator {
|
||||
$size = count($iterable);
|
||||
$values = to_array($iterable);
|
||||
$size = Arr\count($values);
|
||||
if (0 === $size) {
|
||||
return;
|
||||
}
|
||||
|
||||
$values = to_array($iterable);
|
||||
for ($lo = 0, $hi = $size - 1; $lo < $hi; $lo++, $hi--) {
|
||||
yield $values[$hi];
|
||||
}
|
||||
|
||||
for (; $lo >= 0; --$lo) {
|
||||
yield $values[$lo];
|
||||
for($i = $size - 1; $i >= 0; $i--) {
|
||||
yield $values[$i];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ use Psl\Internal;
|
||||
* => Iter(0, 1, 2, 3, 4, 5)
|
||||
*
|
||||
* Iter\slice([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], 5, 3)
|
||||
* => Iter(0, 1, 2, 3)
|
||||
* => Iter(0, 1, 2)
|
||||
*
|
||||
* @psalm-template Tk
|
||||
* @psalm-template Tv
|
||||
@ -32,8 +32,8 @@ use Psl\Internal;
|
||||
*/
|
||||
function slice(iterable $iterable, int $start, ?int $length = null): Iterator
|
||||
{
|
||||
Psl\invariant($start >= 0, 'Start offset must be non-negative');
|
||||
Psl\invariant(null === $length || $length >= 0, 'Length must be non-negative');
|
||||
Psl\invariant($start >= 0, 'Start offset must be non-negative.');
|
||||
Psl\invariant(null === $length || $length >= 0, 'Length must be non-negative.');
|
||||
|
||||
return Internal\lazy_iterator(static function () use ($iterable, $start, $length): Generator {
|
||||
if (0 === $length) {
|
||||
|
@ -13,7 +13,7 @@ class FirstTest extends TestCase
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testFirstKey($expected, iterable $iterable): void
|
||||
public function testFirst($expected, iterable $iterable): void
|
||||
{
|
||||
$result = Iter\first($iterable);
|
||||
|
||||
@ -24,11 +24,11 @@ class FirstTest extends TestCase
|
||||
{
|
||||
yield [null, []];
|
||||
yield [null, new \SplDoublyLinkedList()];
|
||||
yield ['b', ['a' => 'b']];
|
||||
yield ['b', ['a' => 'b', 'c' => 'd']];
|
||||
yield ['a', ['a', 'b']];
|
||||
yield ['a', new Collection\Vector(['a', 'b'])];
|
||||
yield ['b', new Collection\Vector(['a' => 'b'])];
|
||||
yield ['b', new Collection\Map(['a' => 'b'])];
|
||||
yield ['b', new Collection\Vector(['b'])];
|
||||
yield ['b', new Collection\Map(['a' => 'b', 'c' => 'd'])];
|
||||
yield [null, (static function () {
|
||||
yield null => null;
|
||||
})()];
|
||||
|
@ -5,8 +5,28 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class KeysTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testKeys(array $expected, iterable $iterable): void
|
||||
{
|
||||
$result = Iter\keys($iterable);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[0, 1, 2, 3], [1, 2, 3, 4]];
|
||||
yield [[0, 1, 2, 3], Iter\to_iterator([1, 2, 3, 4])];
|
||||
yield [[0, 1, 2, 3], Iter\range(1, 4)];
|
||||
yield [[0, 1, 2, 3, 4], Iter\range(4, 8)];
|
||||
yield [[], []];
|
||||
yield [[0], [null]];
|
||||
yield [[0, 1], [null, null]];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,29 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class LastKeyTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testLastKey($expected, iterable $iterable): void
|
||||
{
|
||||
$result = Iter\last_key($iterable);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [3, [1, 2, 3, 4]];
|
||||
yield [3, Iter\to_iterator([1, 2, 3, 4])];
|
||||
yield [3, Iter\range(1, 4)];
|
||||
yield [4, Iter\range(4, 8)];
|
||||
yield [null, []];
|
||||
yield [0, [null]];
|
||||
yield [1, [null, null]];
|
||||
yield [[1, 2], (fn() => yield [1, 2] => 'hello')()];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,36 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Collection;
|
||||
use Psl\Iter;
|
||||
|
||||
class LastTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testLast($expected, iterable $iterable): void
|
||||
{
|
||||
$result = Iter\last($iterable);
|
||||
|
||||
self::assertSame($expected, $result);
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [null, []];
|
||||
yield [null, new \SplDoublyLinkedList()];
|
||||
yield ['d', ['a' => 'b', 'c' => 'd']];
|
||||
yield ['b', ['a', 'b']];
|
||||
yield ['b', new Collection\Vector(['a', 'b'])];
|
||||
yield ['b', new Collection\Vector(['b'])];
|
||||
yield ['d', new Collection\Map(['a' => 'b', 'c' => 'd'])];
|
||||
yield [null, (static function () {
|
||||
yield null => null;
|
||||
})()];
|
||||
yield [null, (static function () {
|
||||
return;
|
||||
yield;
|
||||
})()];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,27 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class MapKeysTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testMapKeys(array $expected, iterable $iterable, callable $function): void
|
||||
{
|
||||
$result = Iter\map_keys($iterable, $function);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[1, 2, 3], [1, 2, 3], fn(int $k): int => $k];
|
||||
yield [[1, 2 => 2, 4 => 3], [1, 2, 3], fn(int $k): int => $k * 2];
|
||||
yield [['0' => 1, '1' => 2, '2' => 3], [1, 2, 3], fn(int $k): string => (string) $k];
|
||||
yield [[], [], fn(int $k): string => (string) $k];
|
||||
yield [[], Iter\Iterator::create([]), fn(int $k): string => (string) $k];
|
||||
yield [['0' => 1, '1' => 2], Iter\Iterator::create([1, 2]), fn(int $k): string => (string) $k];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,27 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class MapTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testMap(array $expected, iterable $iterable, callable $function): void
|
||||
{
|
||||
$result = Iter\map($iterable, $function);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[1, 2, 3], [1, 2, 3], fn(int $v): int => $v];
|
||||
yield [[2, 4, 6], [1, 2, 3], fn(int $v): int => $v * 2];
|
||||
yield [['1', '2', '3'], [1, 2, 3], fn(int $v): string => (string) $v];
|
||||
yield [[], [], fn(int $k): string => (string) $v];
|
||||
yield [[], Iter\Iterator::create([]), fn(int $v): string => (string) $v];
|
||||
yield [['1', '2'], Iter\Iterator::create([1, 2]), fn(int $v): string => (string) $v];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,27 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class MapWithKeyTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testMapWithKey(array $expected, iterable $iterable, callable $function): void
|
||||
{
|
||||
$result = Iter\map_with_key($iterable, $function);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[1, 3, 5], [1, 2, 3], fn(int $k, int $v): int => $k + $v];
|
||||
yield [[0, 4, 16], [1, 2, 3], fn(int $k, int $v): int => $k * (2**$v)];
|
||||
yield [['1', '3', '5'], [1, 2, 3], fn(int $k, int $v): string => (string) ($k+$v)];
|
||||
yield [[], [], fn(int $k, int $v): string => (string) ($k+$v)];
|
||||
yield [[], Iter\Iterator::create([]), fn(int $k, int $v): string => (string) ($k+$v)];
|
||||
yield [['1', '3'], Iter\Iterator::create([1, 2]), fn(int $k, int $v): string => (string) ($k+$v)];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,30 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class ProductTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testProduct(): void
|
||||
{
|
||||
$result = Iter\product(Iter\range(1, 2), Iter\range(3, 4));
|
||||
$entries = Iter\to_array(Iter\enumerate($result));
|
||||
|
||||
self::assertCount(4, $entries);
|
||||
|
||||
self::assertSame($entries[0], [[0, 0], [1, 3]]);
|
||||
self::assertSame($entries[1], [[0, 1], [1, 4]]);
|
||||
self::assertSame($entries[2], [[1, 0], [2, 3]]);
|
||||
self::assertSame($entries[3], [[1, 1], [2, 4]]);
|
||||
}
|
||||
|
||||
public function testProductEmpty(): void
|
||||
{
|
||||
$result = Iter\product(...[]);
|
||||
$entries = Iter\to_array(Iter\enumerate($result));
|
||||
|
||||
self::assertCount(1, $entries);
|
||||
|
||||
self::assertSame($entries[0], [[], []]);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,22 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
use Psl\Str;
|
||||
|
||||
class PullTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testPull(): void
|
||||
{
|
||||
$result = Iter\pull(
|
||||
Iter\range(0, 10),
|
||||
fn($i) => Str\chr($i + 65),
|
||||
fn($i) => 2**$i
|
||||
);
|
||||
|
||||
self::assertSame([
|
||||
1 => 'A', 2 => 'B', 4 => 'C', 8 => 'D', 16 => 'E', 32 => 'F',
|
||||
64 => 'G', 128 => 'H', 256 => 'I', 512 => 'J', 1024 => 'K'
|
||||
], Iter\to_array_with_keys($result));
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,22 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
use Psl\Str;
|
||||
|
||||
class PullWithKeyTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testPull(): void
|
||||
{
|
||||
$result = Iter\pull_with_key(
|
||||
Iter\range(0, 10),
|
||||
fn($k, $v) => Str\chr($v + $k + 65),
|
||||
fn($k, $v) => 2**($v+$k)
|
||||
);
|
||||
|
||||
self::assertSame([
|
||||
1 => 'A', 4 => 'C', 16 => 'E', 64 => 'G', 256 => 'I', 1024 => 'K',
|
||||
4096 => 'M', 16384 => 'O', 65536 => 'Q', 262144 => 'S', 1048576 => 'U'
|
||||
], Iter\to_array_with_keys($result));
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,29 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl;
|
||||
use Psl\Iter;
|
||||
|
||||
class RandomTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testRandom(): void
|
||||
{
|
||||
$iterable = [1, 2, 3, 4, 5];
|
||||
$value = Iter\random($iterable);
|
||||
|
||||
self::assertTrue(Iter\contains($iterable, $value));
|
||||
|
||||
$iterable = Iter\to_iterator([1, 2, 3, 4, 5]);
|
||||
$value = Iter\random($iterable);
|
||||
|
||||
self::assertTrue(Iter\contains($iterable, $value));
|
||||
}
|
||||
|
||||
public function testRandomWithEmptyIterator(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('Expected a non-empty iterable.');
|
||||
|
||||
Iter\random([]);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,33 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl;
|
||||
use Psl\Iter;
|
||||
|
||||
class RangeTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testRange(): void
|
||||
{
|
||||
self::assertSame([1], Iter\to_array(Iter\range(1, 1, 1)));
|
||||
self::assertSame([0, 1, 2, 3, 4, 5], Iter\to_array(Iter\range(0, 5)));
|
||||
self::assertSame([5, 4, 3, 2, 1, 0], Iter\to_array(Iter\range(5, 0)));
|
||||
self::assertSame([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0], Iter\to_array(Iter\range(0.0, 3.0, 0.5)));
|
||||
self::assertSame([3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0], Iter\to_array(Iter\range(3.0, 0.0, -0.5)));
|
||||
}
|
||||
|
||||
public function testRandomThrowsIfEndIsGreaterThanStartAndStepIsNegative(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('If start < end, the step must be positive.');
|
||||
|
||||
Iter\range(0, 10, -2);
|
||||
}
|
||||
|
||||
public function testRandomThrowsIfStartIsGreaterThanEndAndStepIsPositive(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('If start > end, the step must be negative.');
|
||||
|
||||
Iter\range(20, 10, 2);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,22 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class ReduceTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testReduce($expected, iterable $iterable, callable $function, $initial = null): void
|
||||
{
|
||||
self::assertSame($expected, Iter\reduce($iterable, $function, $initial));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [null, [], fn($accumulator, $k, $v) => $accumulator, null];
|
||||
yield [6, [1, 2, 3], fn($accumulator, $k, $v) => $accumulator + $v, 0];
|
||||
yield [6, Iter\to_iterator([1, 2, 3]), fn($accumulator, $k, $v) => $accumulator + $v, 0];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,24 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class ReductionsTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testReductions(array $expected, iterable $iterable, callable $function, $initial = null): void
|
||||
{
|
||||
$result = Iter\reductions($iterable, $function, $initial);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[], [], fn($accumulator, $k, $v) => $accumulator, null];
|
||||
yield [[1, 3, 6], [1, 2, 3], fn($accumulator, $k, $v) => $accumulator + $v, 0];
|
||||
yield [[1, 3, 6], Iter\to_iterator([1, 2, 3]), fn($accumulator, $k, $v) => $accumulator + $v, 0];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,14 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class ReindexTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testReindex(): void
|
||||
{
|
||||
$result = Iter\reindex([1, 2, 3], fn(int $value): int => $value);
|
||||
|
||||
self::assertSame([1 => 1, 2 => 2, 3 => 3], Iter\to_array_with_keys($result));
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,34 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl;
|
||||
use Psl\Iter;
|
||||
use Psl\Math;
|
||||
|
||||
class RepeatTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testRepeat(): void
|
||||
{
|
||||
$result = Iter\repeat(42, 5);
|
||||
|
||||
self::assertSame([42, 42, 42, 42, 42], Iter\to_array($result));
|
||||
}
|
||||
|
||||
public function testRepeatThrowsIfNumIsNegative(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('Number of repetitions must be non-negative.');
|
||||
|
||||
Iter\repeat(4, -1);
|
||||
}
|
||||
|
||||
public function testRepeatToInfinityIfNumIsNotProvided(): void
|
||||
{
|
||||
$result = Iter\repeat('hello');
|
||||
$result->seek((int) Math\INFINITY);
|
||||
|
||||
self::assertTrue($result->valid());
|
||||
self::assertSame('hello', $result->current());
|
||||
self::assertSame((int) Math\INFINITY, $result->key());
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,21 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class ReverseTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testReverse(): void
|
||||
{
|
||||
$result = Iter\reverse(['foo', 'bar', 'baz', 'qux']);
|
||||
|
||||
self::assertSame(['qux', 'baz', 'bar', 'foo'], Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function testReverseEarlyReturnForEmptyIterables(): void
|
||||
{
|
||||
$result = Iter\reverse(Iter\to_iterator([]));
|
||||
|
||||
self::assertSame([], Iter\to_array($result));
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,26 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class SearchTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testSearch($expected, iterable $iterable, callable $predicate): void
|
||||
{
|
||||
self::assertSame($expected, Iter\search($iterable, $predicate));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield ['baz', ['foo', 'bar', 'baz'], fn(string $v): bool => 'baz' === $v];
|
||||
yield [null, ['foo', 'bar', 'baz'], fn(string $v): bool => 'qux' === $v];
|
||||
yield [null, [], fn(string $v): bool => 'qux' === $v];
|
||||
|
||||
yield ['baz', Iter\to_iterator(['foo', 'bar', 'baz']), fn(string $v): bool => 'baz' === $v];
|
||||
yield [null, Iter\to_iterator(['foo', 'bar', 'baz']), fn(string $v): bool => 'qux' === $v];
|
||||
yield [null, Iter\to_iterator([]), fn(string $v): bool => 'qux' === $v];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,45 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
use Psl;
|
||||
|
||||
class SliceTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
public function testSlice(): void
|
||||
{
|
||||
$result = Iter\slice([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], 5);
|
||||
|
||||
self::assertSame([0, 1, 2, 3, 4, 5], Iter\to_array($result));
|
||||
}
|
||||
|
||||
public function testSliceWithLength(): void
|
||||
{
|
||||
$result = Iter\slice([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], 5, 3);
|
||||
|
||||
self::assertSame([0, 1, 2], Iter\to_array($result));
|
||||
}
|
||||
|
||||
public function testSliceWithZeroLength(): void
|
||||
{
|
||||
$result = Iter\slice([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], 5, 0);
|
||||
|
||||
self::assertSame([], Iter\to_array($result));
|
||||
}
|
||||
|
||||
public function testSliceThrowsIfStartIsNegative(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('Start offset must be non-negative.');
|
||||
|
||||
Iter\slice([1, 2, 3], -3);
|
||||
}
|
||||
|
||||
public function testSliceThrowsIfLengthIsNegative(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('Length must be non-negative.');
|
||||
|
||||
Iter\slice([1, 2, 3], 1, -3);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,24 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
use Psl;
|
||||
|
||||
class TakeTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
|
||||
public function testTake(): void
|
||||
{
|
||||
$result = Iter\take(Iter\to_iterator([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]), 3);
|
||||
|
||||
self::assertSame([-5, -4, -3], Iter\to_array($result));
|
||||
}
|
||||
|
||||
public function testTakeThrowsIfLengthIsNegative(): void
|
||||
{
|
||||
$this->expectException(Psl\Exception\InvariantViolationException::class);
|
||||
$this->expectExceptionMessage('Length must be non-negative.');
|
||||
|
||||
Iter\take([1, 2, 3], -3);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,35 @@ declare(strict_types=1);
|
||||
namespace Psl\Tests\Iter;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psl\Iter;
|
||||
|
||||
class TakeWhileTest extends TestCase
|
||||
{
|
||||
// TODO: add tests.
|
||||
/**
|
||||
* @dataProvider provideData
|
||||
*/
|
||||
public function testTakeWhile(array $expected, iterable $iterable, callable $callable): void
|
||||
{
|
||||
$result = Iter\take_while($iterable, $callable);
|
||||
|
||||
self::assertSame($expected, Iter\to_array_with_keys($result));
|
||||
}
|
||||
|
||||
public function provideData(): iterable
|
||||
{
|
||||
yield [[], [1, 2, 3, 4, 5], fn (int $_): bool => false];
|
||||
yield [[1, 2, 3], [1, 2, 3, 4, 5], fn (int $i) => $i <= 3];
|
||||
yield [[1, 2], [1, 2, 3, 4, 5], fn (int $i) => $i <= 2];
|
||||
yield [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], fn (int $_) => true];
|
||||
|
||||
yield [[], Iter\range(1, 5), fn (int $_): bool => false];
|
||||
yield [[1, 2, 3], Iter\range(1, 5), fn (int $i) => $i <= 3];
|
||||
yield [[1, 2], Iter\range(1, 5), fn (int $i) => $i <= 2];
|
||||
yield [[1, 2, 3, 4, 5], Iter\range(1, 5), fn (int $_) => true];
|
||||
|
||||
yield [[], Iter\range(1, 5), fn (int $_): bool => false];
|
||||
yield [[1, 2 , 3], Iter\range(1, 5), fn (int $i) => $i <= 3];
|
||||
yield [[1, 2], Iter\range(1, 5), fn (int $i) => $i <= 2];
|
||||
yield [[1, 2, 3, 4, 5], Iter\range(1, 5), fn (int $_) => true];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user