next(); $this->assertTrue($iterator->valid()); $this->assertSame(1, $iterator->key()); $this->assertSame('bar', $iterator->current()); } #[DataProvider('provideIterablesForNext')] public function testNextWhenNotValid(iterable $iterable): void { $iterator = new LoopIterator($iterable); $iterator->next(); $iterator->next(); $this->assertFalse($iterator->valid()); $this->assertNull($iterator->key()); $this->assertNull($iterator->current()); } public static function provideIterablesForNext() { yield [['foo', 'bar']]; yield [new \ArrayIterator(['foo', 'bar'])]; yield [new TypedArrayIterator(['foo', 'bar'])]; } #[DataProvider('provideIterablesForRewind')] public function testRewind(iterable $iterable): void { $iterator = new LoopIterator($iterable); $iterator->next(); $this->assertTrue($iterator->valid()); $this->assertSame(1, $iterator->key()); $this->assertSame('bar', $iterator->current()); $iterator->rewind(); $this->assertTrue($iterator->valid()); $this->assertSame(0, $iterator->key()); $this->assertSame('foo', $iterator->current()); } public static function provideIterablesForRewind() { yield [['foo', 'bar']]; yield [new \ArrayIterator(['foo', 'bar'])]; yield [new TypedArrayIterator(['foo', 'bar'])]; } } class TypedArrayIterator implements \Iterator { public function __construct( private array $values, ) { } public function current(): string { return current($this->values); } public function next(): void { next($this->values); } public function key(): int { return key($this->values); } public function valid(): bool { return null !== key($this->values); } public function rewind(): void { reset($this->values); } }