From 52ec4eed79d78758158c9812b34aa9d10e5fea4b Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 29 Sep 2024 14:57:34 +0300 Subject: [PATCH 01/17] Disable sort when limit is explicit --- .gitignore | 1 + src/Paginator/KeysetPaginator.php | 8 ++++++++ src/Paginator/OffsetPaginator.php | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index db6cb742..3f035ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ phpunit.phar /phpunit.xml # phpunit cache /.phpunit.cache/* +.phpunit.result.cache diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 6945ee59..3897044a 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -257,6 +257,10 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { + if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { + return false; + } + return true; } @@ -269,6 +273,10 @@ public function withSort(?Sort $sort): static public function getSort(): ?Sort { + if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { + return null; + } + return $this->dataReader->getSort(); } diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 90ffb2cc..fb6c4898 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -221,6 +221,10 @@ public function getTotalPages(): int public function isSortable(): bool { + if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { + return false; + } + return $this->dataReader instanceof SortableDataInterface; } @@ -237,6 +241,10 @@ public function withSort(?Sort $sort): static public function getSort(): ?Sort { + if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { + return null; + } + return $this->dataReader instanceof SortableDataInterface ? $this->dataReader->getSort() : null; } From 00a9fdd5135bb7cddf44164c7dbe37ac1e3c50cc Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 29 Sep 2024 11:58:01 +0000 Subject: [PATCH 02/17] Apply fixes from StyleCI --- src/Paginator/KeysetPaginator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 3897044a..c41b12bf 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -257,11 +257,11 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { - if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { - return false; - } + return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) - return true; + + + ; } public function withSort(?Sort $sort): static From 3e5f225db388ec408c3b7107b7b6c116027a39f7 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Mon, 30 Sep 2024 16:10:29 +0300 Subject: [PATCH 03/17] Update .gitignore Co-authored-by: Sergei Predvoditelev --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3f035ed2..db6cb742 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,3 @@ phpunit.phar /phpunit.xml # phpunit cache /.phpunit.cache/* -.phpunit.result.cache From 222aedf97ab2d4062bd6a073d5f6e3119f36a157 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 00:00:16 +0300 Subject: [PATCH 04/17] Add changelog, fix formatting --- CHANGELOG.md | 3 ++- src/Paginator/KeysetPaginator.php | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b813816..6b4e8f69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,8 @@ - Chg #163: Rename `FilterableDataInterface::withFilterHandlers()` to `FilterableDataInterface::withAddedFilterHandlers()` (@samdark) - Enh #190: Use `str_contains` for case-sensitive match in `LikeHandler` (@samdark) - Enh #194: Improve psalm annotations in `LimitableDataInterface` (@vjik) -- Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik) +- Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik) +- Enh #201: Disable sorting when limit is set explicitly in a paginator (@samdark) ## 1.0.1 January 25, 2023 diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index c41b12bf..4d29946b 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -257,11 +257,7 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { - return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) - - - - ; + return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null); } public function withSort(?Sort $sort): static From 8ee5aa6e71ffafada3f28aaac3ea4e844a648a4b Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 00:02:56 +0300 Subject: [PATCH 05/17] Review comments --- src/Paginator/KeysetPaginator.php | 4 ---- src/Paginator/OffsetPaginator.php | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 4d29946b..042512ab 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -269,10 +269,6 @@ public function withSort(?Sort $sort): static public function getSort(): ?Sort { - if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { - return null; - } - return $this->dataReader->getSort(); } diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index fb6c4898..be0b2d88 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -241,10 +241,6 @@ public function withSort(?Sort $sort): static public function getSort(): ?Sort { - if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { - return null; - } - return $this->dataReader instanceof SortableDataInterface ? $this->dataReader->getSort() : null; } From 6a01920206542ef0831ee2299b35e1f8fb5bc777 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:02:22 +0300 Subject: [PATCH 06/17] Fix --- src/Paginator/KeysetPaginator.php | 11 ++++++++++- src/Paginator/OffsetPaginator.php | 4 ++-- src/Paginator/PaginatorInterface.php | 10 +++++----- tests/Paginator/OffsetPaginatorTest.php | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 042512ab..5131d51d 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -6,6 +6,7 @@ use Closure; use InvalidArgumentException; +use LogicException; use RuntimeException; use Yiisoft\Arrays\ArrayHelper; use Yiisoft\Data\Reader\Filter\GreaterThan; @@ -257,11 +258,19 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { - return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null); + if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { + return false; + } + + return $this->dataReader instanceof SortableDataInterface; } public function withSort(?Sort $sort): static { + if (!$this->isSortable()) { + throw new InvalidArgumentException('Sorting is not supported.'); + } + $new = clone $this; $new->dataReader = $this->dataReader->withSort($sort); return $new; diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index be0b2d88..68ae6e3b 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -230,8 +230,8 @@ public function isSortable(): bool public function withSort(?Sort $sort): static { - if (!$this->dataReader instanceof SortableDataInterface) { - throw new LogicException('Data reader does not support sorting.'); + if (!$this->isSortable()) { + throw new InvalidArgumentException('Sorting is not supported.'); } $new = clone $this; diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 87be22de..72d933a6 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -4,7 +4,7 @@ namespace Yiisoft\Data\Paginator; -use LogicException; +use InvalidArgumentException; use Yiisoft\Data\Reader\FilterInterface; use Yiisoft\Data\Reader\ReadableDataInterface; use Yiisoft\Data\Reader\Sort; @@ -95,7 +95,7 @@ public function getPageSize(): int; public function getCurrentPageSize(): int; /** - * @return bool Whether sorting is supported. + * @return bool Whether changing sorting via {@see withSorting()} is supported. */ public function isSortable(): bool; @@ -104,7 +104,7 @@ public function isSortable(): bool; * * @param Sort|null $sort Sorting criteria or null for no sorting. * - * @throws LogicException When sorting isn't supported. + * @throws InvalidArgumentException When sorting isn't supported. * @return static New instance. */ public function withSort(?Sort $sort): static; @@ -117,7 +117,7 @@ public function withSort(?Sort $sort): static; public function getSort(): ?Sort; /** - * @return bool Whether filtering is supported. + * @return bool Whether changing filter via {@see withFilter()} is supported. */ public function isFilterable(): bool; @@ -126,7 +126,7 @@ public function isFilterable(): bool; * * @param FilterInterface $filter Data reading criteria. * - * @throws LogicException When filtering isn't supported. + * @throws InvalidArgumentException When filtering isn't supported. * @return static New instance. */ public function withFilter(FilterInterface $filter): static; diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index d91f791b..5209bcfa 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -562,7 +562,7 @@ public function testWithSortNonSortableData(): void $paginator = new OffsetPaginator(new StubOffsetData()); $this->expectException(LogicException::class); - $this->expectExceptionMessage('Data reader does not support sorting.'); + $this->expectExceptionMessage('Sorting is not supported.'); $paginator->withSort(null); } From 9b739c513efba146bb32558fa1e6c5f632dd4077 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 18 Oct 2024 20:02:44 +0000 Subject: [PATCH 07/17] Apply fixes from StyleCI --- src/Paginator/KeysetPaginator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 5131d51d..f075586b 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -6,7 +6,6 @@ use Closure; use InvalidArgumentException; -use LogicException; use RuntimeException; use Yiisoft\Arrays\ArrayHelper; use Yiisoft\Data\Reader\Filter\GreaterThan; From 299e1855fb157409ec969676fed30be25cff86cd Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:14:08 +0300 Subject: [PATCH 08/17] Fix --- CHANGELOG.md | 3 ++- src/Paginator/KeysetPaginator.php | 8 ++------ src/Paginator/OffsetPaginator.php | 4 ++-- tests/Paginator/OffsetPaginatorTest.php | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b4e8f69..e2cdc1ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,8 @@ - Enh #190: Use `str_contains` for case-sensitive match in `LikeHandler` (@samdark) - Enh #194: Improve psalm annotations in `LimitableDataInterface` (@vjik) - Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik) -- Enh #201: Disable sorting when limit is set explicitly in a paginator (@samdark) +- Enh #201: Disable sorting when limit is set explicitly in a paginator, use `InvalidArgumentException` when sorting + is supplied in this case (@samdark) ## 1.0.1 January 25, 2023 diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index f075586b..9b7a34d8 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -257,17 +257,13 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { - if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { - return false; - } - - return $this->dataReader instanceof SortableDataInterface; + return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null); } public function withSort(?Sort $sort): static { if (!$this->isSortable()) { - throw new InvalidArgumentException('Sorting is not supported.'); + throw new InvalidArgumentException('Data reader does not support sorting.'); } $new = clone $this; diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 68ae6e3b..293d687c 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -231,7 +231,7 @@ public function isSortable(): bool public function withSort(?Sort $sort): static { if (!$this->isSortable()) { - throw new InvalidArgumentException('Sorting is not supported.'); + throw new InvalidArgumentException('Data reader does not support sorting.'); } $new = clone $this; @@ -251,7 +251,7 @@ public function isFilterable(): bool public function withFilter(FilterInterface $filter): static { - if (!$this->dataReader instanceof FilterableDataInterface) { + if (!$this->isFilterable()) { throw new LogicException('Data reader does not support filtering.'); } diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 5209bcfa..d91f791b 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -562,7 +562,7 @@ public function testWithSortNonSortableData(): void $paginator = new OffsetPaginator(new StubOffsetData()); $this->expectException(LogicException::class); - $this->expectExceptionMessage('Sorting is not supported.'); + $this->expectExceptionMessage('Data reader does not support sorting.'); $paginator->withSort(null); } From b297d21ba5ebbdd59d205292dd937b3d10a24721 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:18:22 +0300 Subject: [PATCH 09/17] Fix psalm --- src/Paginator/OffsetPaginator.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 293d687c..60e5b4cb 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -235,6 +235,7 @@ public function withSort(?Sort $sort): static } $new = clone $this; + /** @psalm-suppress UndefinedInterfaceMethod */ $new->dataReader = $this->dataReader->withSort($sort); return $new; } @@ -256,6 +257,7 @@ public function withFilter(FilterInterface $filter): static } $new = clone $this; + /** @psalm-suppress UndefinedInterfaceMethod */ $new->dataReader = $this->dataReader->withFilter($filter); return $new; } From 66f53dc16cadb33988e12df7ccd0134beed9271d Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:48:07 +0300 Subject: [PATCH 10/17] Simplify impossible cases --- src/Paginator/KeysetPaginator.php | 6 +- src/Paginator/OffsetPaginator.php | 3 +- tests/Paginator/KeysetPaginatorTest.php | 4 ++ tests/Paginator/OffsetPaginatorTest.php | 5 +- tests/Support/StubKeysetData.php | 80 +++++++++++++++++++++++++ tests/Support/StubOffsetData.php | 2 +- 6 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 tests/Support/StubKeysetData.php diff --git a/src/Paginator/KeysetPaginator.php b/src/Paginator/KeysetPaginator.php index 9b7a34d8..6945ee59 100644 --- a/src/Paginator/KeysetPaginator.php +++ b/src/Paginator/KeysetPaginator.php @@ -257,15 +257,11 @@ public function getNextToken(): ?PageToken public function isSortable(): bool { - return !($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null); + return true; } public function withSort(?Sort $sort): static { - if (!$this->isSortable()) { - throw new InvalidArgumentException('Data reader does not support sorting.'); - } - $new = clone $this; $new->dataReader = $this->dataReader->withSort($sort); return $new; diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 60e5b4cb..2c56a76d 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -6,7 +6,6 @@ use Generator; use InvalidArgumentException; -use LogicException; use Yiisoft\Data\Reader\CountableDataInterface; use Yiisoft\Data\Reader\FilterableDataInterface; use Yiisoft\Data\Reader\FilterInterface; @@ -253,7 +252,7 @@ public function isFilterable(): bool public function withFilter(FilterInterface $filter): static { if (!$this->isFilterable()) { - throw new LogicException('Data reader does not support filtering.'); + throw new InvalidArgumentException('Data reader does not support filtering.'); } $new = clone $this; diff --git a/tests/Paginator/KeysetPaginatorTest.php b/tests/Paginator/KeysetPaginatorTest.php index 1a3317ec..a7f21c8e 100644 --- a/tests/Paginator/KeysetPaginatorTest.php +++ b/tests/Paginator/KeysetPaginatorTest.php @@ -6,12 +6,14 @@ use ArrayIterator; use InvalidArgumentException; +use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use RuntimeException; use stdClass; use Yiisoft\Arrays\ArrayHelper; use Yiisoft\Data\Paginator\KeysetFilterContext; use Yiisoft\Data\Paginator\KeysetPaginator; +use Yiisoft\Data\Paginator\OffsetPaginator; use Yiisoft\Data\Paginator\PageToken; use Yiisoft\Data\Reader\Filter\Equals; use Yiisoft\Data\Reader\Filter\GreaterThan; @@ -27,6 +29,8 @@ use Yiisoft\Data\Reader\Sort; use Yiisoft\Data\Reader\SortableDataInterface; use Yiisoft\Data\Tests\Support\MutationDataReader; +use Yiisoft\Data\Tests\Support\StubKeysetData; +use Yiisoft\Data\Tests\Support\StubOffsetData; use Yiisoft\Data\Tests\TestCase; use function array_values; diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index d91f791b..00bdcf21 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -5,7 +5,6 @@ namespace Yiisoft\Data\Tests\Paginator; use InvalidArgumentException; -use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use Yiisoft\Data\Paginator\OffsetPaginator; use Yiisoft\Data\Paginator\PageNotFoundException; @@ -561,7 +560,7 @@ public function testWithSortNonSortableData(): void { $paginator = new OffsetPaginator(new StubOffsetData()); - $this->expectException(LogicException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Data reader does not support sorting.'); $paginator->withSort(null); } @@ -600,7 +599,7 @@ public function testWithFilterNonFilterableData(): void { $paginator = new OffsetPaginator(new StubOffsetData()); - $this->expectException(LogicException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Data reader does not support filtering.'); $paginator->withFilter(new Equals('id', 2)); } diff --git a/tests/Support/StubKeysetData.php b/tests/Support/StubKeysetData.php new file mode 100644 index 00000000..6ff2c3b3 --- /dev/null +++ b/tests/Support/StubKeysetData.php @@ -0,0 +1,80 @@ +limit = $limit; + return $new; + } + + public function getLimit(): ?int + { + return $this->limit; + } + + public function withFilter(?FilterInterface $filter): static + { + return clone $this; + } + + public function getFilter(): ?FilterInterface + { + return null; + } + + public function withAddedFilterHandlers(FilterHandlerInterface ...$filterHandlers): static + { + return clone $this; + } + + public function withSort(?Sort $sort): static + { + return clone $this; + } + + public function getSort(): ?Sort + { + return Sort::only(['id'])->withOrderString('id'); + } +} diff --git a/tests/Support/StubOffsetData.php b/tests/Support/StubOffsetData.php index e756dac6..f5571a2f 100644 --- a/tests/Support/StubOffsetData.php +++ b/tests/Support/StubOffsetData.php @@ -40,7 +40,7 @@ public function withOffset(int $offset): static return $this; } - public function getLimit(): int + public function getLimit(): ?int { return 0; } From cce49c7c48ee5229ced35e5f4c38cf417b4a2598 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Fri, 18 Oct 2024 20:48:18 +0000 Subject: [PATCH 11/17] Apply fixes from StyleCI --- tests/Paginator/KeysetPaginatorTest.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/Paginator/KeysetPaginatorTest.php b/tests/Paginator/KeysetPaginatorTest.php index a7f21c8e..1a3317ec 100644 --- a/tests/Paginator/KeysetPaginatorTest.php +++ b/tests/Paginator/KeysetPaginatorTest.php @@ -6,14 +6,12 @@ use ArrayIterator; use InvalidArgumentException; -use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use RuntimeException; use stdClass; use Yiisoft\Arrays\ArrayHelper; use Yiisoft\Data\Paginator\KeysetFilterContext; use Yiisoft\Data\Paginator\KeysetPaginator; -use Yiisoft\Data\Paginator\OffsetPaginator; use Yiisoft\Data\Paginator\PageToken; use Yiisoft\Data\Reader\Filter\Equals; use Yiisoft\Data\Reader\Filter\GreaterThan; @@ -29,8 +27,6 @@ use Yiisoft\Data\Reader\Sort; use Yiisoft\Data\Reader\SortableDataInterface; use Yiisoft\Data\Tests\Support\MutationDataReader; -use Yiisoft\Data\Tests\Support\StubKeysetData; -use Yiisoft\Data\Tests\Support\StubOffsetData; use Yiisoft\Data\Tests\TestCase; use function array_values; From 7d2334eaf1a719de27a72867d561d973869fce24 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:51:26 +0300 Subject: [PATCH 12/17] Cleanup --- tests/Support/StubKeysetData.php | 80 -------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 tests/Support/StubKeysetData.php diff --git a/tests/Support/StubKeysetData.php b/tests/Support/StubKeysetData.php deleted file mode 100644 index 6ff2c3b3..00000000 --- a/tests/Support/StubKeysetData.php +++ /dev/null @@ -1,80 +0,0 @@ -limit = $limit; - return $new; - } - - public function getLimit(): ?int - { - return $this->limit; - } - - public function withFilter(?FilterInterface $filter): static - { - return clone $this; - } - - public function getFilter(): ?FilterInterface - { - return null; - } - - public function withAddedFilterHandlers(FilterHandlerInterface ...$filterHandlers): static - { - return clone $this; - } - - public function withSort(?Sort $sort): static - { - return clone $this; - } - - public function getSort(): ?Sort - { - return Sort::only(['id'])->withOrderString('id'); - } -} From 84dc4646ab4b14a9b537e69688c1cad8a4dbe231 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 18 Oct 2024 23:59:12 +0300 Subject: [PATCH 13/17] Eliminate mutants --- tests/Paginator/OffsetPaginatorTest.php | 5 +++-- tests/Support/StubOffsetData.php | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 00bdcf21..044866c9 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -529,8 +529,9 @@ public function testImmutability(): void public static function dataIsSupportSorting(): array { return [ - [true, new IterableDataReader([])], - [false, new StubOffsetData()], + 'IterableDataReader' => [true, new IterableDataReader([])], + 'StubOffsetData' => [false, new StubOffsetData()], + 'StubOffsetDataWithLimit' => [false, (new StubOffsetData())->withLimit(10)], ]; } diff --git a/tests/Support/StubOffsetData.php b/tests/Support/StubOffsetData.php index f5571a2f..0dcbc36e 100644 --- a/tests/Support/StubOffsetData.php +++ b/tests/Support/StubOffsetData.php @@ -15,6 +15,12 @@ final class StubOffsetData implements CountableDataInterface, LimitableDataInterface { + /** + * @var int|null + * @psalm-var non-negative-int + */ + private ?int $limit = null; + public function read(): iterable { return []; @@ -32,7 +38,9 @@ public function count(): int public function withLimit(?int $limit): static { - return $this; + $new = clone $this; + $new->limit = $limit; + return $new; } public function withOffset(int $offset): static @@ -42,7 +50,7 @@ public function withOffset(int $offset): static public function getLimit(): ?int { - return 0; + return $this->limit; } public function getOffset(): int From 752790ca4c13cb66cd5d0b12c69c0a11ef00e2d6 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 20 Oct 2024 13:53:04 +0300 Subject: [PATCH 14/17] Apply suggestions --- CHANGELOG.md | 3 +-- src/Paginator/OffsetPaginator.php | 15 +++++++++++---- tests/Paginator/OffsetPaginatorTest.php | 5 +++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fb236fd..8e139205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,8 +37,7 @@ - Enh #190: Use `str_contains` for case-sensitive match in `LikeHandler` (@samdark) - Enh #194: Improve psalm annotations in `LimitableDataInterface` (@vjik) - Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik) -- Enh #201: Disable sorting when limit is set explicitly in a paginator, use `InvalidArgumentException` when sorting - is supplied in this case (@samdark) +- Enh #201: Disable sorting when limit is set explicitly in a paginator (@samdark) - Enh #202: Check that correct sort is passed to `withSort()` of keyset paginator (@samdark) - Enh #207: More secific Psalm type for OffsetPaginator::withCurrentPage() (@samdark) diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 53b0fd80..97972429 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -5,7 +5,10 @@ namespace Yiisoft\Data\Paginator; use Generator; +use Hoa\Iterator\Filter; use InvalidArgumentException; +use LogicException; +use RuntimeException; use Yiisoft\Data\Reader\CountableDataInterface; use Yiisoft\Data\Reader\FilterableDataInterface; use Yiisoft\Data\Reader\FilterInterface; @@ -223,6 +226,9 @@ public function getTotalPages(): int return (int) ceil($this->getTotalItems() / $this->pageSize); } + /** + * @psalm-assert-if-true SortableDataInterface $this->dataReader + */ public function isSortable(): bool { if ($this->dataReader instanceof LimitableDataInterface && $this->dataReader->getLimit() !== null) { @@ -235,11 +241,10 @@ public function isSortable(): bool public function withSort(?Sort $sort): static { if (!$this->isSortable()) { - throw new InvalidArgumentException('Data reader does not support sorting.'); + throw new LogicException('Data reader does not support sorting.'); } $new = clone $this; - /** @psalm-suppress UndefinedInterfaceMethod */ $new->dataReader = $this->dataReader->withSort($sort); return $new; } @@ -249,6 +254,9 @@ public function getSort(): ?Sort return $this->dataReader instanceof SortableDataInterface ? $this->dataReader->getSort() : null; } + /** + * @psalm-assert-if-true FilterableDataInterface $this->dataReader + */ public function isFilterable(): bool { return $this->dataReader instanceof FilterableDataInterface; @@ -257,11 +265,10 @@ public function isFilterable(): bool public function withFilter(FilterInterface $filter): static { if (!$this->isFilterable()) { - throw new InvalidArgumentException('Data reader does not support filtering.'); + throw new LogicException('Data reader does not support filtering.'); } $new = clone $this; - /** @psalm-suppress UndefinedInterfaceMethod */ $new->dataReader = $this->dataReader->withFilter($filter); return $new; } diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 044866c9..14764d37 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -5,6 +5,7 @@ namespace Yiisoft\Data\Tests\Paginator; use InvalidArgumentException; +use LogicException; use PHPUnit\Framework\Attributes\DataProvider; use Yiisoft\Data\Paginator\OffsetPaginator; use Yiisoft\Data\Paginator\PageNotFoundException; @@ -561,7 +562,7 @@ public function testWithSortNonSortableData(): void { $paginator = new OffsetPaginator(new StubOffsetData()); - $this->expectException(InvalidArgumentException::class); + $this->expectException(LogicException::class); $this->expectExceptionMessage('Data reader does not support sorting.'); $paginator->withSort(null); } @@ -600,7 +601,7 @@ public function testWithFilterNonFilterableData(): void { $paginator = new OffsetPaginator(new StubOffsetData()); - $this->expectException(InvalidArgumentException::class); + $this->expectException(LogicException::class); $this->expectExceptionMessage('Data reader does not support filtering.'); $paginator->withFilter(new Equals('id', 2)); } From f17d842676e956ae616565ed70d83aa3324f6c62 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sun, 20 Oct 2024 10:53:23 +0000 Subject: [PATCH 15/17] Apply fixes from StyleCI --- src/Paginator/OffsetPaginator.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index 97972429..e514f069 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -5,10 +5,8 @@ namespace Yiisoft\Data\Paginator; use Generator; -use Hoa\Iterator\Filter; use InvalidArgumentException; use LogicException; -use RuntimeException; use Yiisoft\Data\Reader\CountableDataInterface; use Yiisoft\Data\Reader\FilterableDataInterface; use Yiisoft\Data\Reader\FilterInterface; From e04dfd0d3726e3de80dbbd5664ddd29b1362d1ca Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 20 Oct 2024 13:55:32 +0300 Subject: [PATCH 16/17] Revert interface changes --- src/Paginator/PaginatorInterface.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 72d933a6..1c436b63 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -4,7 +4,7 @@ namespace Yiisoft\Data\Paginator; -use InvalidArgumentException; +use LogicException; use Yiisoft\Data\Reader\FilterInterface; use Yiisoft\Data\Reader\ReadableDataInterface; use Yiisoft\Data\Reader\Sort; @@ -104,7 +104,7 @@ public function isSortable(): bool; * * @param Sort|null $sort Sorting criteria or null for no sorting. * - * @throws InvalidArgumentException When sorting isn't supported. + * @throws LogicException When sorting isn't supported. * @return static New instance. */ public function withSort(?Sort $sort): static; @@ -126,7 +126,7 @@ public function isFilterable(): bool; * * @param FilterInterface $filter Data reading criteria. * - * @throws InvalidArgumentException When filtering isn't supported. + * @throws LogicException When filtering isn't supported. * @return static New instance. */ public function withFilter(FilterInterface $filter): static; From 879907036e615ebf6a7cfda3897c7fca56d698c2 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 20 Oct 2024 23:16:00 +0300 Subject: [PATCH 17/17] Improve exception messages --- src/Paginator/OffsetPaginator.php | 4 ++-- src/Paginator/PaginatorInterface.php | 4 ++-- tests/Paginator/OffsetPaginatorTest.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Paginator/OffsetPaginator.php b/src/Paginator/OffsetPaginator.php index e514f069..80211977 100644 --- a/src/Paginator/OffsetPaginator.php +++ b/src/Paginator/OffsetPaginator.php @@ -239,7 +239,7 @@ public function isSortable(): bool public function withSort(?Sort $sort): static { if (!$this->isSortable()) { - throw new LogicException('Data reader does not support sorting.'); + throw new LogicException('Changing sorting is not supported.'); } $new = clone $this; @@ -263,7 +263,7 @@ public function isFilterable(): bool public function withFilter(FilterInterface $filter): static { if (!$this->isFilterable()) { - throw new LogicException('Data reader does not support filtering.'); + throw new LogicException('Changing filtering is not supported.'); } $new = clone $this; diff --git a/src/Paginator/PaginatorInterface.php b/src/Paginator/PaginatorInterface.php index 1c436b63..6c9bd065 100644 --- a/src/Paginator/PaginatorInterface.php +++ b/src/Paginator/PaginatorInterface.php @@ -104,7 +104,7 @@ public function isSortable(): bool; * * @param Sort|null $sort Sorting criteria or null for no sorting. * - * @throws LogicException When sorting isn't supported. + * @throws LogicException When changing sorting isn't supported. * @return static New instance. */ public function withSort(?Sort $sort): static; @@ -126,7 +126,7 @@ public function isFilterable(): bool; * * @param FilterInterface $filter Data reading criteria. * - * @throws LogicException When filtering isn't supported. + * @throws LogicException When changing filter isn't supported. * @return static New instance. */ public function withFilter(FilterInterface $filter): static; diff --git a/tests/Paginator/OffsetPaginatorTest.php b/tests/Paginator/OffsetPaginatorTest.php index 14764d37..03419c57 100644 --- a/tests/Paginator/OffsetPaginatorTest.php +++ b/tests/Paginator/OffsetPaginatorTest.php @@ -563,7 +563,7 @@ public function testWithSortNonSortableData(): void $paginator = new OffsetPaginator(new StubOffsetData()); $this->expectException(LogicException::class); - $this->expectExceptionMessage('Data reader does not support sorting.'); + $this->expectExceptionMessage('Changing sorting is not supported.'); $paginator->withSort(null); } @@ -602,7 +602,7 @@ public function testWithFilterNonFilterableData(): void $paginator = new OffsetPaginator(new StubOffsetData()); $this->expectException(LogicException::class); - $this->expectExceptionMessage('Data reader does not support filtering.'); + $this->expectExceptionMessage('Changing filtering is not supported.'); $paginator->withFilter(new Equals('id', 2)); }