From 915005a789108413d03261c190fef05264696c6d Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 29 Jan 2024 11:16:51 +0300 Subject: [PATCH 1/5] improve psalm --- src/Paginator/KeysetPaginator.php | 3 +++ src/Paginator/OffsetPaginator.php | 10 ++++++++++ src/Paginator/PaginatorInterface.php | 4 ++++ src/Reader/CountableDataInterface.php | 2 ++ 4 files changed, 19 insertions(+) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 512d6c2c..3e5e0917 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -152,6 +152,9 @@ public function getToken(): ?PageToken public function withPageSize(int $pageSize): static { + /** + * @psalm-suppress DocblockTypeContradiction We don't believe in psalm annotations. + */ if ($pageSize < 1) { throw new InvalidArgumentException('Page size should be at least 1.'); } diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 97a595c0..19154549 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -46,6 +46,7 @@ final class OffsetPaginator implements PaginatorInterface /** * @var int Maximum number of items per page. + * @psalm-var positive-int */ private int $pageSize = self::DEFAULT_PAGE_SIZE; @@ -95,6 +96,9 @@ public function withToken(?PageToken $token): static public function withPageSize(int $pageSize): static { + /** + * @psalm-suppress DocblockTypeContradiction We don't believe in psalm annotations. + */ if ($pageSize < 1) { throw new PaginatorException('Page size should be at least 1.'); } @@ -169,6 +173,7 @@ public function getCurrentPageSize(): int } if ($currentPage === $pages) { + /** @psalm-var positive-int Because total items is more than offset */ return $this->getTotalItems() - $this->getOffset(); } @@ -189,6 +194,8 @@ public function getOffset(): int * Get total number of items in the whole data reader being paginated. * * @return int Total items number. + * + * @psalm-return non-negative-int */ public function getTotalItems(): int { @@ -268,6 +275,9 @@ public function isPaginationRequired(): bool return $this->getTotalPages() > 1; } + /** + * @psalm-return non-negative-int + */ private function getInternalTotalPages(): int { return max(1, $this->getTotalPages()); diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 65574fe1..88251b27 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -44,6 +44,8 @@ public function withToken(?PageToken $token): static; * @throws PaginatorException If page size is incorrect. * * @return static New instance. + * + * @psalm-param positive-int $pageSize */ public function withPageSize(int $pageSize): static; @@ -87,6 +89,8 @@ public function getPageSize(): int; * @throws PaginatorException If page specified is not found. * * @return int Current page size. + * + * @psalm-return non-negative-int */ public function getCurrentPageSize(): int; diff --git a/src/Reader/CountableDataInterface.php b/src/Reader/CountableDataInterface.php index 72335189..605d7602 100644 --- a/src/Reader/CountableDataInterface.php +++ b/src/Reader/CountableDataInterface.php @@ -13,6 +13,8 @@ interface CountableDataInterface extends Countable { /** * @return int Number of items in the data. + * + * @psalm-return non-negative-int */ public function count(): int; } From 009a5c3a3c99e56161b16c5434c9578c0f556857 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 29 Jan 2024 11:46:34 +0300 Subject: [PATCH 2/5] Add `PageNotFoundException` --- src/Paginator/OffsetPaginator.php | 6 +++--- src/Paginator/PageNotFoundException.php | 13 +++++++++++++ src/Paginator/PaginatorInterface.php | 6 +++--- tests/Paginator/OffsetPaginatorTest.php | 7 ++++--- 4 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 src/Paginator/PageNotFoundException.php diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 19154549..2d5c38c9 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -177,7 +177,7 @@ public function getCurrentPageSize(): int return $this->getTotalItems() - $this->getOffset(); } - throw new PaginatorException('Page not found.'); + throw new PageNotFoundException(); } /** @@ -239,7 +239,7 @@ public function getSort(): ?Sort public function read(): iterable { if ($this->getCurrentPage() > $this->getInternalTotalPages()) { - throw new PaginatorException('Page not found.'); + throw new PageNotFoundException(); } yield from $this->dataReader @@ -264,7 +264,7 @@ public function isOnFirstPage(): bool public function isOnLastPage(): bool { if ($this->getCurrentPage() > $this->getInternalTotalPages()) { - throw new PaginatorException('Page not found.'); + throw new PageNotFoundException(); } return $this->getCurrentPage() === $this->getInternalTotalPages(); diff --git a/src/Paginator/PageNotFoundException.php b/src/Paginator/PageNotFoundException.php new file mode 100644 index 00000000..279967fb --- /dev/null +++ b/src/Paginator/PageNotFoundException.php @@ -0,0 +1,13 @@ + @@ -130,7 +130,7 @@ public function read(): iterable; /** * Get whether current page is the last one. * - * @throws PaginatorException If page specified is not found. + * @throws PageNotFoundException If page specified is not found. * * @return bool Whether current page is the last one. */ diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 24a47f8c..7957875e 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -8,6 +8,7 @@ use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use Yiisoft\Data\Paginator\OffsetPaginator; +use Yiisoft\Data\Paginator\PageNotFoundException; use Yiisoft\Data\Paginator\PageToken; use Yiisoft\Data\Paginator\PaginatorException; use Yiisoft\Data\Paginator\PaginatorInterface; @@ -222,7 +223,7 @@ public function testReadCurrentPageCannotBeLargerThanMaxPages(): void ; $this->assertSame(3, $paginator->getTotalPages()); - $this->expectException(PaginatorException::class); + $this->expectException(PageNotFoundException::class); $this->expectExceptionMessage('Page not found.'); $this->iterableToArray($paginator->read()); @@ -397,7 +398,7 @@ public function testIsLastPageBeyondMaxPages(): void ; $this->assertSame(3, $paginator->getTotalPages()); - $this->expectException(PaginatorException::class); + $this->expectException(PageNotFoundException::class); $this->expectExceptionMessage('Page not found.'); $paginator->isOnLastPage(); @@ -450,7 +451,7 @@ public function testGetCurrentPageCannotBeLargerThanMaxPages(): void ; $this->assertSame(5, $paginator->getTotalItems()); - $this->expectException(PaginatorException::class); + $this->expectException(PageNotFoundException::class); $this->expectExceptionMessage('Page not found.'); $paginator->getCurrentPageSize(); From f6d673cc684454197fec593bce2342341928c8b7 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 29 Jan 2024 11:50:46 +0300 Subject: [PATCH 3/5] `PaginatorInterface::getCurrentPageSize()` don't throw PaginatorException --- src/Paginator/OffsetPaginator.php | 2 +- src/Paginator/PaginatorInterface.php | 2 -- tests/Paginator/OffsetPaginatorTest.php | 8 ++------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 2d5c38c9..90fa461c 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -177,7 +177,7 @@ public function getCurrentPageSize(): int return $this->getTotalItems() - $this->getOffset(); } - throw new PageNotFoundException(); + return 0; } /** diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 330c065a..96d7202c 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -86,8 +86,6 @@ public function getPageSize(): int; * * @see getPageSize() * - * @throws PageNotFoundException If page specified is not found. - * * @return int Current page size. * * @psalm-return non-negative-int diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 7957875e..6411d433 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -447,14 +447,10 @@ public function testGetCurrentPageCannotBeLargerThanMaxPages(): void $dataReader = new IterableDataReader(self::DEFAULT_DATASET); $paginator = (new OffsetPaginator($dataReader)) ->withPageSize(2) - ->withCurrentPage(4) - ; + ->withCurrentPage(4); $this->assertSame(5, $paginator->getTotalItems()); - $this->expectException(PageNotFoundException::class); - $this->expectExceptionMessage('Page not found.'); - - $paginator->getCurrentPageSize(); + $this->assertSame(0, $paginator->getCurrentPageSize()); } public function testEmptyDataSet(): void From 666e1d560e5da514dd3b2c6589b236c4a141fa47 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 29 Jan 2024 11:52:42 +0300 Subject: [PATCH 4/5] fix --- src/Paginator/KeysetPaginator.php | 3 --- src/Paginator/OffsetPaginator.php | 3 --- src/Paginator/PaginatorInterface.php | 2 -- 3 files changed, 8 deletions(-) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 3e5e0917..512d6c2c 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -152,9 +152,6 @@ public function getToken(): ?PageToken public function withPageSize(int $pageSize): static { - /** - * @psalm-suppress DocblockTypeContradiction We don't believe in psalm annotations. - */ if ($pageSize < 1) { throw new InvalidArgumentException('Page size should be at least 1.'); } diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 90fa461c..85fe4933 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -96,9 +96,6 @@ public function withToken(?PageToken $token): static public function withPageSize(int $pageSize): static { - /** - * @psalm-suppress DocblockTypeContradiction We don't believe in psalm annotations. - */ if ($pageSize < 1) { throw new PaginatorException('Page size should be at least 1.'); } diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 96d7202c..eee45647 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -44,8 +44,6 @@ public function withToken(?PageToken $token): static; * @throws PaginatorException If page size is incorrect. * * @return static New instance. - * - * @psalm-param positive-int $pageSize */ public function withPageSize(int $pageSize): static; From 21764a61c8296d5c95b15cb7a61abcf37caed185 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 29 Jan 2024 11:57:52 +0300 Subject: [PATCH 5/5] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d5039d4..3a6a0fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ `getNextPageToken()` with `getNextToken()`, `getPreviousPageToken()` with `getPreviousToken()`, and add `getToken()`. These methods use new `PageToken` class (@vjik) - New #160: Add `Sort::hasFieldInConfig()` method that checks for the presence of a field in the sort config (@vjik) +- New #161: Add `PageNotFoundException` (@vjik) +- Chg #161: `PaginatorInterface::getCurrentPageSize()` returns 0 instead throws exception if page specified is + not found (@vjik) +- Enh #161: Add more specified psalm annotations to `CountableDataInterface::count()`, + `PaginatorInterface::getCurrentPageSize()` and `OffsetPaginator::getTotalItems()` (@vjik) ## 1.0.1 January 25, 2023