from(); $limit = $pagination->pageSize(); $slice = array_slice($data, $offset, $limit); $paginationDto = new PaginationDto( page: $pagination->pageNumber(), pageSize: $limit, totalItems: count($data), totalPages: (int) ceil(count($data) / $limit), ); return new PageOf($paginationDto, $slice); }; $stream = new StreamOf($fetcher, new PageSize(10)); // WHEN $result = iterator_to_array($stream); // THEN expect($result)->toBe($data) ->and($stream->totalCount())->toBe(25) ->and($stream->totalPages())->toBe(3) ->and($stream->lastError())->toBeNull(); }); it('handles empty page result', function (): void { // GIVEN $fetcher = function (Pagination $_): PageOf { $paginationDto = new PaginationDto( page: 1, pageSize: 10, totalItems: 0, totalPages: 0, ); return new PageOf($paginationDto, []); }; $stream = new StreamOf($fetcher, new PageSize(10)); // WHEN $result = iterator_to_array($stream); // THEN expect($result)->toBeEmpty() ->and($stream->totalCount())->toBe(0) ->and($stream->totalPages())->toBe(0); }); it('stops iteration on error and captures lastError', function (): void { // GIVEN $fetcher = function (Pagination $_): NetworkError { return new NetworkError('Connection timed out'); }; $stream = new StreamOf($fetcher, new PageSize(10)); // WHEN $result = iterator_to_array($stream); // THEN expect($result)->toBeEmpty() ->and($stream->lastError())->toBeInstanceOf(NetworkError::class) ->and($stream->lastError()?->message())->toBe('Connection timed out'); }); });