Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/DbPager.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public function __construct(
/** @param array<string, mixed> $values */
public function __invoke(string $queryId, array $values, Pager $pager, string|null $entity): PagesInterface
{
// Clone the Pager attribute to avoid mutating the caller's instance in dynamicPager().
$pager = clone $pager;
if (is_string($pager->perPage)) {
$values = $this->dynamicPager($pager, $values);
}
Expand Down
28 changes: 28 additions & 0 deletions tests/DbPagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Ray\MediaQuery;

use PHPUnit\Framework\TestCase;
use Ray\MediaQuery\Annotation\Pager;

final class DbPagerTest extends TestCase
{
public function testPagerInstanceIsNotMutatedAcrossCalls(): void
{
$sqlQuery = new FakeSqlQuery();
$dbPager = new DbPager(new FakeMediaQueryLogger(), $sqlQuery);

// The Pager attribute instance is shared across multiple calls,
// mirroring how a cached annotation would be reused in production code.
$pager = new Pager(perPage: 'perPage', template: '/{?page}');

foreach ([2, 1, 3] as $perPage) {
($dbPager)('todo_list', ['perPage' => $perPage], $pager, null);
}

$this->assertSame('perPage', $pager->perPage, 'Pager::$perPage must remain the original key string');
$this->assertSame([2, 1, 3], $sqlQuery->perPageHistory, 'Each call must forward its own perPage to SqlQuery::getPages()');
}
}
43 changes: 43 additions & 0 deletions tests/Fake/FakeEmptyPages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Ray\MediaQuery;

use ArrayIterator;

final class FakeEmptyPages implements PagesInterface
{
/** @var ArrayIterator<int, mixed> */
private ArrayIterator $iter;

public function __construct()
{
$this->iter = new ArrayIterator([]);
}

public function offsetExists(mixed $offset): bool
{
return $this->iter->offsetExists($offset);
}

public function offsetGet(mixed $offset): mixed
{
return $this->iter->offsetGet($offset);
}

public function offsetSet(mixed $offset, mixed $value): void
{
$this->iter->offsetSet($offset, $value);
}

public function offsetUnset(mixed $offset): void
{
$this->iter->offsetUnset($offset);
}

public function count(): int
{
return $this->iter->count();
}
}
26 changes: 26 additions & 0 deletions tests/Fake/FakeMediaQueryLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Ray\MediaQuery;

final class FakeMediaQueryLogger implements MediaQueryLoggerInterface
{
public function start(): void
{
}

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function log(string $queryId, array $values): void
{
}

public function __toString(): string
{
return '';
}
}
62 changes: 62 additions & 0 deletions tests/Fake/FakeSqlQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Ray\MediaQuery;

final class FakeSqlQuery implements SqlQueryInterface
{
/** @var list<int> */
public array $perPageHistory = [];

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function getRow(string $sqlId, array $values = [], FetchInterface|null $fetch = null): array|object|null
{
return null;
}

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function getRowList(string $sqlId, array $values = [], FetchInterface|null $fetch = null): array
{
return [];
}

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function exec(string $sqlId, array $values = [], FetchInterface|null $fetch = null): void
{
}

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function getCount(string $sqlId, array $values): int
{
return 0;
}

/**
* {@inheritDoc}
*
* @param array<string, mixed> $values
*/
public function getPages(string $sqlId, array $values, int $perPage, string $queryTemplate = '/{?page}', string|null $entity = null): PagesInterface
{
$this->perPageHistory[] = $perPage;

return new FakeEmptyPages();
}
}
Loading