2019-12-24 01:52:07 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Psl\Tests\Iter;
|
|
|
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
2020-09-01 03:03:19 +02:00
|
|
|
use Psl\Collection\MutableVector;
|
2020-07-07 15:17:36 +02:00
|
|
|
use Psl\Exception\InvariantViolationException;
|
|
|
|
use Psl\Iter;
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2020-10-09 17:57:10 +02:00
|
|
|
final class IteratorTest extends TestCase
|
2019-12-24 01:52:07 +01:00
|
|
|
{
|
2020-09-01 07:51:23 +02:00
|
|
|
public function testCreateFromGenerator(): void
|
|
|
|
{
|
2020-10-09 17:57:10 +02:00
|
|
|
$iterator = Iter\Iterator::create((static fn () => yield from [1, 2, 3])());
|
2020-09-01 07:51:23 +02:00
|
|
|
|
|
|
|
static::assertCount(3, $iterator);
|
|
|
|
}
|
|
|
|
|
2020-10-09 17:57:10 +02:00
|
|
|
public function testCreateFromFactory(): void
|
|
|
|
{
|
|
|
|
$iterator = Iter\Iterator::from((fn () => yield from [1, 2, 3]));
|
|
|
|
|
|
|
|
static::assertCount(3, $iterator);
|
|
|
|
}
|
|
|
|
|
2020-07-07 15:17:36 +02:00
|
|
|
public function testSeek(): void
|
2019-12-24 01:52:07 +01:00
|
|
|
{
|
2020-09-01 03:03:19 +02:00
|
|
|
$iterator = new Iter\Iterator((fn () => yield from [1, 2, 3, 4, 5])());
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2020-07-12 16:51:18 +02:00
|
|
|
self::assertSame(1, $iterator->current());
|
2020-07-07 15:17:36 +02:00
|
|
|
$iterator->next();
|
2020-07-12 16:51:18 +02:00
|
|
|
self::assertSame(2, $iterator->current());
|
2020-07-07 15:17:36 +02:00
|
|
|
$iterator->next();
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2020-07-07 15:17:36 +02:00
|
|
|
$iterator->seek(0);
|
2020-07-12 16:51:18 +02:00
|
|
|
self::assertSame(1, $iterator->current());
|
2020-09-01 07:51:23 +02:00
|
|
|
|
|
|
|
$iterator->seek(4);
|
|
|
|
self::assertSame(5, $iterator->current());
|
|
|
|
|
|
|
|
self::assertSame(5, $iterator->count());
|
|
|
|
|
|
|
|
$iterator->seek(1);
|
|
|
|
self::assertSame(2, $iterator->current());
|
|
|
|
|
|
|
|
$iterator->seek(4);
|
|
|
|
self::assertSame(5, $iterator->current());
|
|
|
|
|
|
|
|
self::assertSame(5, $iterator->count());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
2020-07-07 15:17:36 +02:00
|
|
|
public function testSeekThrowsForOutOfBoundIndex(): void
|
2019-12-24 01:52:07 +01:00
|
|
|
{
|
2020-09-01 03:03:19 +02:00
|
|
|
$iterator = new Iter\Iterator((fn () => yield from [1, 2, 3, 4, 5])());
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2020-07-07 15:17:36 +02:00
|
|
|
$this->expectException(InvariantViolationException::class);
|
2020-07-16 17:11:54 +02:00
|
|
|
$this->expectExceptionMessage('Position is out-of-bounds.');
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2020-07-07 15:17:36 +02:00
|
|
|
$iterator->seek(30);
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
2020-09-01 03:03:19 +02:00
|
|
|
|
|
|
|
public function testIterating(): void
|
|
|
|
{
|
|
|
|
$spy = new MutableVector([]);
|
|
|
|
|
|
|
|
$generator = (static function () use ($spy): iterable {
|
|
|
|
for ($i = 0; $i < 3; $i++) {
|
|
|
|
$spy->add('generator (' . $i . ')');
|
|
|
|
|
|
|
|
yield ['foo', 'bar'] => $i;
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
|
|
$rewindable = Iter\rewindable($generator);
|
|
|
|
for ($i = 0; $i < 3; $i++) {
|
|
|
|
foreach ($rewindable as $k => $v) {
|
|
|
|
$spy->add('foreach (' . $v . ')');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Assert supports non-array-key keys. ( in this case, keys are arrays )
|
|
|
|
*/
|
|
|
|
self::assertSame(['foo', 'bar'], $k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$rewindable->rewind();
|
|
|
|
while ($rewindable->valid()) {
|
|
|
|
$spy->add('while (' . $rewindable->current() . ')');
|
|
|
|
|
|
|
|
$rewindable->next();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The following proves that :
|
|
|
|
* - The iterator is capable of rewinding a generator.
|
|
|
|
* - The generator is not exhausted immediately on construction.
|
|
|
|
*/
|
|
|
|
self::assertSame([
|
|
|
|
'generator (0)',
|
|
|
|
'foreach (0)',
|
|
|
|
'generator (1)',
|
|
|
|
'foreach (1)',
|
|
|
|
'generator (2)',
|
|
|
|
'foreach (2)',
|
|
|
|
'foreach (0)',
|
|
|
|
'foreach (1)',
|
|
|
|
'foreach (2)',
|
|
|
|
'foreach (0)',
|
|
|
|
'foreach (1)',
|
|
|
|
'foreach (2)',
|
|
|
|
'while (0)',
|
|
|
|
'while (1)',
|
|
|
|
'while (2)',
|
|
|
|
], $spy->toArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRewindingValidGenerator(): void
|
|
|
|
{
|
|
|
|
$spy = new MutableVector([]);
|
|
|
|
|
|
|
|
$generator = (static function () use ($spy): iterable {
|
|
|
|
for ($i = 0; $i < 3; $i++) {
|
|
|
|
$spy->add($e = 'generator (' . $i . ')');
|
|
|
|
yield $i;
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
|
|
$rewindable = Iter\rewindable($generator);
|
|
|
|
foreach ($rewindable as $k => $v) {
|
|
|
|
$spy->add('foreach (' . $v . ')');
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$rewindable->rewind();
|
|
|
|
do {
|
|
|
|
$spy->add('do while (' . $rewindable->current() . ')');
|
|
|
|
break;
|
|
|
|
} while ($rewindable->valid());
|
|
|
|
|
|
|
|
$rewindable->rewind();
|
|
|
|
while ($rewindable->valid()) {
|
|
|
|
$spy->add('while (' . $rewindable->current() . ')');
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
for ($rewindable->rewind(); $rewindable->valid(); $rewindable->next()) {
|
|
|
|
$spy->add('for (' . $rewindable->current() . ')');
|
|
|
|
}
|
|
|
|
|
|
|
|
self::assertSame([
|
|
|
|
'generator (0)',
|
|
|
|
'foreach (0)',
|
|
|
|
'do while (0)',
|
|
|
|
'while (0)',
|
|
|
|
'for (0)',
|
|
|
|
'generator (1)',
|
|
|
|
'for (1)',
|
|
|
|
'generator (2)',
|
|
|
|
'for (2)',
|
|
|
|
], $spy->toArray());
|
|
|
|
}
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|