204 lines
No EOL
6.1 KiB
PHP
204 lines
No EOL
6.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types = 1);
|
|
|
|
namespace Foundation\Tests\Unit\Core\Cache;
|
|
|
|
use DateInterval;
|
|
use Foundation\Core\Cache\ArrayCache;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\SimpleCache\InvalidArgumentException;
|
|
use stdClass;
|
|
|
|
class ArrayCacheTest extends TestCase
|
|
{
|
|
private ArrayCache $cache;
|
|
|
|
protected function setUp(): void {
|
|
$this->cache = new ArrayCache();
|
|
}
|
|
|
|
public function testCanSetAndGetValue(): void {
|
|
$setResult = $this->cache->set('key1', 'value1');
|
|
|
|
self::assertSame('value1', $this->cache->get('key1'));
|
|
self::assertTrue($setResult);
|
|
}
|
|
|
|
public function testReturnsDefaultWhenKeyNotExists(): void {
|
|
self::assertNull($this->cache->get('nonexistent'));
|
|
self::assertSame('default', $this->cache->get('nonexistent', 'default'));
|
|
}
|
|
|
|
public function testReturnsExistsStateForCacheKeys(): void {
|
|
$this->cache->set('key1', 'value1');
|
|
|
|
self::assertTrue($this->cache->has('key1'));
|
|
self::assertFalse($this->cache->has('nonexistent'));
|
|
}
|
|
|
|
public function testCanDeleteAKey(): void {
|
|
$this->cache->set('key1', 'value1');
|
|
self::assertTrue($this->cache->has('key1'));
|
|
|
|
$deleteResult = $this->cache->delete('key1');
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertTrue($deleteResult);
|
|
}
|
|
|
|
public function testReturnsTrueForDeletionEvenForNonExistentKey(): void {
|
|
$result = $this->cache->delete('nonexistent');
|
|
|
|
self::assertTrue($result);
|
|
}
|
|
|
|
public function testCanClearAllKeys(): void {
|
|
$this->cache->set('key1', 'value1');
|
|
$this->cache->set('key2', 'value2');
|
|
|
|
$this->cache->clear();
|
|
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertFalse($this->cache->has('key2'));
|
|
}
|
|
|
|
public function testConsidersTtlForCacheItemsWithIntegers(): void {
|
|
$this->cache->set('key1', 'value1', 1);
|
|
|
|
self::assertTrue($this->cache->has('key1'));
|
|
self::assertSame('value1', $this->cache->get('key1'));
|
|
|
|
// Sleep to let TTL expire
|
|
sleep(2);
|
|
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertNull($this->cache->get('key1'));
|
|
}
|
|
|
|
public function testConsidersTtlForCacheItemsWithDateIntervals(): void {
|
|
$interval = new DateInterval('PT1S'); // 1 second
|
|
$this->cache->set('key1', 'value1', $interval);
|
|
|
|
self::assertTrue($this->cache->has('key1'));
|
|
self::assertSame('value1', $this->cache->get('key1'));
|
|
|
|
// Sleep to let TTL expire
|
|
sleep(2);
|
|
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertNull($this->cache->get('key1'));
|
|
}
|
|
|
|
public function testReturnsArrayIfMultipleItemsAreRequested(): void {
|
|
$this->cache->set('key1', 'value1');
|
|
$this->cache->set('key2', 'value2');
|
|
|
|
$result = $this->cache->getMultiple(['key1', 'key2', 'key3'], 'default');
|
|
|
|
self::assertSame(
|
|
[
|
|
'key1' => 'value1',
|
|
'key2' => 'value2',
|
|
'key3' => 'default',
|
|
],
|
|
$result,
|
|
);
|
|
}
|
|
|
|
public function testCanSetMultipleItems(): void {
|
|
$values = [
|
|
'key1' => 'value1',
|
|
'key2' => 'value2',
|
|
'key3' => 'value3',
|
|
];
|
|
|
|
$result = $this->cache->setMultiple($values);
|
|
|
|
self::assertTrue($result);
|
|
self::assertSame('value1', $this->cache->get('key1'));
|
|
self::assertSame('value2', $this->cache->get('key2'));
|
|
self::assertSame('value3', $this->cache->get('key3'));
|
|
}
|
|
|
|
public function testCanSetMultipleItemsWithTtl(): void {
|
|
$values = [
|
|
'key1' => 'value1',
|
|
'key2' => 'value2',
|
|
];
|
|
|
|
$this->cache->setMultiple($values, 1);
|
|
|
|
self::assertTrue($this->cache->has('key1'));
|
|
self::assertTrue($this->cache->has('key2'));
|
|
|
|
sleep(2);
|
|
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertFalse($this->cache->has('key2'));
|
|
}
|
|
|
|
public function testCanDeleteMultipleItemsByKey(): void {
|
|
$this->cache->set('key1', 'value1');
|
|
$this->cache->set('key2', 'value2');
|
|
$this->cache->set('key3', 'value3');
|
|
|
|
$result = $this->cache->deleteMultiple(['key1', 'key3']);
|
|
|
|
self::assertTrue($result);
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertTrue($this->cache->has('key2'));
|
|
self::assertFalse($this->cache->has('key3'));
|
|
}
|
|
|
|
public function testCanStoreComplexDataTypes(): void {
|
|
$array = ['nested' => ['data' => 'value']];
|
|
$object = new stdClass();
|
|
$object->property = 'test';
|
|
|
|
$this->cache->set('array', $array);
|
|
$this->cache->set('object', $object);
|
|
|
|
self::assertSame($array, $this->cache->get('array'));
|
|
self::assertEquals($object, $this->cache->get('object'));
|
|
}
|
|
|
|
public function testThrowsExceptionOnInvalidKeys(): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
|
|
$this->cache->set('invalid{key}', 'value');
|
|
}
|
|
|
|
public function testThrowsExceptionOnEmptyKeys(): void {
|
|
$this->expectException(InvalidArgumentException::class);
|
|
|
|
$this->cache->set('', 'value');
|
|
}
|
|
|
|
public function testThrowsExceptionOnKeysWithInvalidCharacters(): void {
|
|
$invalidKeys = ['key{', 'key}', 'key(', 'key)', 'key/', 'key\\', 'key@', 'key:'];
|
|
|
|
foreach ($invalidKeys as $key) {
|
|
try {
|
|
$this->cache->set($key, 'value');
|
|
self::fail("Expected InvalidArgumentException for key: $key");
|
|
} catch (InvalidArgumentException $e) {
|
|
// Expected exception
|
|
self::assertTrue(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function testExpiredKeysAreRemovedOnAccess(): void {
|
|
$this->cache->set('key1', 'value1', 1);
|
|
|
|
// Verify it exists initially
|
|
self::assertTrue($this->cache->has('key1'));
|
|
|
|
// Wait for expiry
|
|
sleep(2);
|
|
|
|
// Access should trigger cleanup
|
|
self::assertFalse($this->cache->has('key1'));
|
|
self::assertNull($this->cache->get('key1'));
|
|
}
|
|
} |