Skip to content

Commit

Permalink
Merge pull request #13 from mmunz/bug/allow-date-interval-time-argument
Browse files Browse the repository at this point in the history
  • Loading branch information
sabbelasichon authored Jul 27, 2023
2 parents 1e05f8e + dc55f28 commit 752ec57
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Classes/Adapter/Psr6Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function save(CacheItemInterface $item): bool
$lifetime = null;

if (method_exists($item, 'getExpiry')) {
$lifetime = $item->getExpiry() ? (int) ($GLOBALS['EXEC_TIME'] - $item->getExpiry()) : null;
$lifetime = $item->getExpiry() ? (int) ($item->getExpiry() - $GLOBALS['EXEC_TIME']) : null;
}

$this->cache->set($this->hash($item->getKey()), $item->get(), [], $lifetime);
Expand Down
5 changes: 4 additions & 1 deletion Classes/CacheItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ public function expiresAfter($time): CacheItemInterface
$this->expiry = null;
} elseif (is_int($time)) {
$this->expiry = (int) ($GLOBALS['EXEC_TIME'] + $time);
} elseif ($time instanceof \DateInterval) {
$this->expiry = (new \DateTime('@0'))->add($time)
->getTimestamp() + $GLOBALS['EXEC_TIME'];
} else {
throw new InvalidArgumentException(sprintf(
'Expiration date must be an integer, "%s" given.',
'Expiration date must be null, integer or DateInterval, "%s" given.',
get_debug_type($time)
));
}
Expand Down
33 changes: 29 additions & 4 deletions Tests/Functional/Adapter/Psr16CacheAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Ssch\Cache\Tests\Functional\Adapter;

use DateInterval;
use Psr\SimpleCache\CacheInterface;
use Ssch\Cache\Tests\Functional\Fixtures\Extensions\typo3_psr_cache_adapter_test\Classes\Service\ServiceWithPsr16Cache;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
Expand Down Expand Up @@ -38,19 +39,41 @@ protected function tearDown(): void
$this->cacheAdapter->delete(ServiceWithPsr16Cache::CACHE_ITEM_KEY);
}

public function testThatFirstCalculationCreatesCacheEntry(): void
/**
* @return array[]
*/
public static function expiresAfterTimeProvider()
{
$this->serviceWithPsr16Cache->calculate();
return [
'null' => ['', null],
'int' => ['', 1],
'DateInterval' => ['', new \DateInterval('PT1S')],
];
}

/**
* @dataProvider expiresAfterTimeProvider
* @param DateInterval|int|null $input
*/
public function testThatFirstCalculationCreatesCacheEntry(string $expected, $input): void
{
$this->cacheAdapter->clear();
$this->serviceWithPsr16Cache->calculate($input);
self::assertTrue($this->cacheAdapter->has(ServiceWithPsr16Cache::CACHE_ITEM_KEY));
self::assertSame(
md5(ServiceWithPsr16Cache::CACHE_VALUE),
$this->cacheAdapter->get(ServiceWithPsr16Cache::CACHE_ITEM_KEY)
);
}

public function testThatGetItemsReturnsCorrectResults(): void
/**
* @dataProvider expiresAfterTimeProvider
* @param DateInterval|int|null $input
*/
public function testThatGetItemsReturnsCorrectResults(string $expected, $input): void
{
$this->serviceWithPsr16Cache->calculate();
$this->cacheAdapter->clear();
$this->serviceWithPsr16Cache->calculate($input);
$items = $this->cacheAdapter->getMultiple([ServiceWithPsr16Cache::CACHE_ITEM_KEY]);

foreach ($items as $item) {
Expand All @@ -60,6 +83,7 @@ public function testThatGetItemsReturnsCorrectResults(): void

public function testThatCacheIsTruncatedCorrectly(): void
{
$this->cacheAdapter->clear();
$this->serviceWithPsr16Cache->calculate();
self::assertTrue($this->cacheAdapter->has(ServiceWithPsr16Cache::CACHE_ITEM_KEY));
$this->cacheAdapter->clear();
Expand All @@ -68,6 +92,7 @@ public function testThatCacheIsTruncatedCorrectly(): void

public function testThatDeletingItemsIsSuccessful(): void
{
$this->cacheAdapter->clear();
$this->serviceWithPsr16Cache->calculate();
self::assertTrue($this->cacheAdapter->has(ServiceWithPsr16Cache::CACHE_ITEM_KEY));
$this->cacheAdapter->deleteMultiple([ServiceWithPsr16Cache::CACHE_ITEM_KEY]);
Expand Down
70 changes: 59 additions & 11 deletions Tests/Functional/Adapter/Psr6AdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Ssch\Cache\Tests\Functional\Adapter;

use DateInterval;
use Psr\Cache\CacheItemPoolInterface;
use Ssch\Cache\Tests\Functional\Fixtures\Extensions\typo3_psr_cache_adapter_test\Classes\Service\ServiceWithPsr6Cache;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
Expand Down Expand Up @@ -38,26 +39,80 @@ protected function tearDown(): void
$this->cacheAdapter->deleteItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY);
}

public function testThatFirstCalculationCreatesCacheEntry(): void
/**
* @return array[]
*/
public static function lifetimeProvider()
{
$this->serviceWithPsr6Cache->calculate();
return [
'null' => ['', null],
'int' => ['', 1],
'DateInterval' => ['', new \DateInterval('PT1S')],
];
}

/**
* @dataProvider lifetimeProvider
* @param DateInterval|int|null $input
*/
public function testThatFirstCalculationCreatesCacheEntry(string $expected, $input): void
{
$this->cacheAdapter->clear();
$this->serviceWithPsr6Cache->calculate($input);
self::assertTrue($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
self::assertSame(
md5(ServiceWithPsr6Cache::CACHE_VALUE),
$this->cacheAdapter->getItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY)->get()
);
}

public function testThatGetItemsReturnsCorrectResults(): void
/**
* @dataProvider lifetimeProvider
* @param DateInterval|int|null $input
*/
public function testThatGetItemsReturnsCorrectResults(string $expected, $input): void
{
$this->serviceWithPsr6Cache->calculate();
$this->cacheAdapter->clear();
$this->serviceWithPsr6Cache->calculate($input);
$items = $this->cacheAdapter->getItems([ServiceWithPsr6Cache::CACHE_ITEM_KEY]);

foreach ($items as $item) {
self::assertSame(md5(ServiceWithPsr6Cache::CACHE_VALUE), $item->get());
}
}

/**
* @return array[]
*/
public static function expiresAfterTimeProvider()
{
return [
'int' => ['', 1],
'DateInterval' => ['', new \DateInterval('PT1S')],
];
}

/**
* @dataProvider expiresAfterTimeProvider
* @param DateInterval|int|null $input
*/
public function testThatLifetimeIsCorrectlySet(string $expected, $input): void
{
$this->cacheAdapter->clear();
self::assertFalse($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
$this->serviceWithPsr6Cache->calculate($input);
self::assertTrue($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
/*
Expiry, when given as integer, is set as timestamp: $GLOBALS['EXEC_TIME'] + lifetime
FileBackend calculates the expiry based on $GLOBALS['EXEC_TIME']:
It is expired when: $expiryTime !== 0 && $expiryTime < $GLOBALS['EXEC_TIME'];
Because we set and query the cache item in the same request $GLOBALS['EXEC_TIME'] is the same
when setting the expiry time and when checking for its expiry in FileBackend.
As a workaround we manipulate $GLOBALS['EXEC_TIME'] */
$GLOBALS['EXEC_TIME'] = $GLOBALS['EXEC_TIME'] + 2;
self::assertFalse($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
}

public function testThatCacheIsTruncatedCorrectly(): void
{
$this->serviceWithPsr6Cache->calculate();
Expand All @@ -73,11 +128,4 @@ public function testThatDeletingItemsIsSuccessful(): void
$this->cacheAdapter->deleteItems([ServiceWithPsr6Cache::CACHE_ITEM_KEY]);
self::assertFalse($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
}

public function testThatLifetimeIsCorrectlySet(): void
{
$this->serviceWithPsr6Cache->calculate(1);
sleep(2);
self::assertFalse($this->cacheAdapter->hasItem(ServiceWithPsr6Cache::CACHE_ITEM_KEY));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Ssch\Cache\Tests\Functional\Fixtures\Extensions\typo3_psr_cache_adapter_test\Classes\Service;

use DateInterval;
use Psr\SimpleCache\CacheInterface;

final class ServiceWithPsr16Cache
Expand All @@ -26,7 +27,10 @@ public function __construct(CacheInterface $cache)
$this->cache = $cache;
}

public function calculate(int $lifetime = null): void
/**
* @param DateInterval|int|null $lifetime
*/
public function calculate($lifetime = null): void
{
if (! $this->cache->has(self::CACHE_ITEM_KEY)) {
$this->cache->set(self::CACHE_ITEM_KEY, md5(self::CACHE_VALUE), $lifetime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Ssch\Cache\Tests\Functional\Fixtures\Extensions\typo3_psr_cache_adapter_test\Classes\Service;

use DateInterval;
use Psr\Cache\CacheItemPoolInterface;

final class ServiceWithPsr6Cache
Expand All @@ -26,7 +27,10 @@ public function __construct(CacheItemPoolInterface $cacheItemPool)
$this->cacheItemPool = $cacheItemPool;
}

public function calculate(int $lifetime = null): void
/**
* @param DateInterval|int|null $lifetime
*/
public function calculate($lifetime = null): void
{
$cacheItem = $this->cacheItemPool->getItem(self::CACHE_ITEM_KEY);
if (! $cacheItem->isHit()) {
Expand Down

0 comments on commit 752ec57

Please sign in to comment.