From 609ae4655440426141099bdf62823c09c71330ef Mon Sep 17 00:00:00 2001 From: barbosa89 Date: Tue, 16 Dec 2025 16:18:26 -0500 Subject: [PATCH 1/2] feat(Paginator): handle empty dataset gracefully and update return types --- src/Database/Paginator.php | 16 ++++++++++++-- tests/Unit/Database/PaginatorTest.php | 32 +++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/Database/Paginator.php b/src/Database/Paginator.php index 42a0d0c8..9417e11f 100644 --- a/src/Database/Paginator.php +++ b/src/Database/Paginator.php @@ -72,8 +72,12 @@ public function hasNextPage() return $this->currentPage < $this->lastPage; } - public function from(): int + public function from(): int|null { + if ($this->total === 0) { + return null; + } + return (($this->currentPage - 1) * $this->perPage) + 1; } @@ -88,6 +92,10 @@ public function to(): int public function links(): array { + if ($this->total === 0 || $this->lastPage === 0) { + return []; + } + $links = []; $separator = ['url' => null, 'label' => '...']; @@ -179,8 +187,12 @@ private function getFirstPageUrl(): string return $this->buildPageUrl(1); } - private function getLastPageUrl(): string + private function getLastPageUrl(): string|null { + if ($this->lastPage === 0) { + return null; + } + return $this->buildPageUrl($this->lastPage); } diff --git a/tests/Unit/Database/PaginatorTest.php b/tests/Unit/Database/PaginatorTest.php index 8472a271..b079181e 100644 --- a/tests/Unit/Database/PaginatorTest.php +++ b/tests/Unit/Database/PaginatorTest.php @@ -196,3 +196,35 @@ 'links' => $links, ]); }); + +it('handles empty dataset gracefully', function () { + $uri = Http::new(URL::build('users', ['page' => 1])); + + $paginator = new Paginator($uri, new Collection('array'), 0, 1, 15); + + expect($paginator->data()->toArray())->toBe([]); + expect($paginator->total())->toBe(0); + expect($paginator->lastPage())->toBe(0); + expect($paginator->currentPage())->toBe(1); + expect($paginator->perPage())->toBe(15); + expect($paginator->hasPreviousPage())->toBeFalse(); + expect($paginator->hasNextPage())->toBeFalse(); + expect($paginator->from())->toBe(0); + expect($paginator->to())->toBe(0); + + expect($paginator->toArray())->toBe([ + 'path' => URL::build('users'), + 'current_page' => 1, + 'last_page' => 0, + 'per_page' => 15, + 'total' => 0, + 'first_page_url' => URL::build('users', ['page' => 1]), + 'last_page_url' => null, + 'prev_page_url' => null, + 'next_page_url' => null, + 'from' => 0, + 'to' => 0, + 'data' => [], + 'links' => [], + ]); +}); From 386038572db8aee93995cc00058ee1ae0ffb2154 Mon Sep 17 00:00:00 2001 From: barbosa89 Date: Tue, 16 Dec 2025 17:47:04 -0500 Subject: [PATCH 2/2] feat(Paginator): improve pagination links logic and update test assertions for empty dataset --- src/Database/Paginator.php | 38 +++++++++++---------------- tests/Unit/Database/PaginatorTest.php | 4 +-- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/Database/Paginator.php b/src/Database/Paginator.php index 9417e11f..25006c16 100644 --- a/src/Database/Paginator.php +++ b/src/Database/Paginator.php @@ -99,39 +99,31 @@ public function links(): array $links = []; $separator = ['url' => null, 'label' => '...']; - $prepend = ($this->currentPage + 1) - $this->itemsEachSide; - $prepend = $prepend < 0 ? 0 : $prepend; + $start = max(1, $this->currentPage - $this->itemsEachSide); + $end = min($this->lastPage, $this->currentPage + $this->itemsEachSide); - if ($prepend > ($this->itemsEachSide + 1)) { - $prepend = $this->itemsEachSide; - - $links[] = $this->buildLink(1); - $links[] = $separator; + if ($this->currentPage <= ($this->linksNumber - 1)) { + $start = 1; + $end = min($this->lastPage, $this->linksNumber); } - $start = $this->currentPage - $prepend; + if ($start > 1) { + $links[] = $this->buildLink(1); - for ($i = $start; $i < $this->currentPage; $i++) { - $links[] = $this->buildLink($i); + if ($start > 2) { + $links[] = $separator; + } } - $append = $this->linksNumber - $prepend; - $append = ($this->currentPage + $append) > $this->lastPage - ? ($this->lastPage - $this->currentPage) + 1 - : $append; - - $limit = $this->currentPage + $append; - - for ($i = $this->currentPage; $i < $limit; $i++) { + for ($i = $start; $i <= $end; $i++) { $links[] = $this->buildLink($i); } - if (($this->lastPage - ($this->currentPage + $append)) >= 1) { - $links[] = $separator; - $links[] = $this->buildLink($this->lastPage); - } + if ($end < $this->lastPage) { + if ($end < ($this->lastPage - 1)) { + $links[] = $separator; + } - if (($this->lastPage - ($this->currentPage + $append)) === 0) { $links[] = $this->buildLink($this->lastPage); } diff --git a/tests/Unit/Database/PaginatorTest.php b/tests/Unit/Database/PaginatorTest.php index b079181e..e2d7e39a 100644 --- a/tests/Unit/Database/PaginatorTest.php +++ b/tests/Unit/Database/PaginatorTest.php @@ -209,7 +209,7 @@ expect($paginator->perPage())->toBe(15); expect($paginator->hasPreviousPage())->toBeFalse(); expect($paginator->hasNextPage())->toBeFalse(); - expect($paginator->from())->toBe(0); + expect($paginator->from())->toBeNull(); expect($paginator->to())->toBe(0); expect($paginator->toArray())->toBe([ @@ -222,7 +222,7 @@ 'last_page_url' => null, 'prev_page_url' => null, 'next_page_url' => null, - 'from' => 0, + 'from' => null, 'to' => 0, 'data' => [], 'links' => [],