[Iter] add more tests

This commit is contained in:
azjezz 2020-09-01 06:50:23 +01:00
parent 468971ea22
commit 0e70ce0af5
30 changed files with 462 additions and 54 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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'
* )
*
*

View File

@ -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

View File

@ -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);
}

View File

@ -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.');

View File

@ -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) {

View File

@ -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];
}
});
}

View File

@ -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) {

View File

@ -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;
})()];

View File

@ -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]];
}
}

View File

@ -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')()];
}
}

View File

@ -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;
})()];
}
}

View File

@ -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];
}
}

View File

@ -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];
}
}

View File

@ -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)];
}
}

View File

@ -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], [[], []]);
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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([]);
}
}

View File

@ -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);
}
}

View File

@ -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];
}
}

View File

@ -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];
}
}

View File

@ -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));
}
}

View File

@ -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());
}
}

View File

@ -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));
}
}

View File

@ -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];
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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];
}
}