diff --git a/framework/caching/RedisCache.php b/framework/caching/RedisCache.php index 3e45fe0..74432f4 100644 --- a/framework/caching/RedisCache.php +++ b/framework/caching/RedisCache.php @@ -21,6 +21,8 @@ use yii\db\redis\Connection; * authenticate with the server after connect. * * See [[Cache]] for common cache operations that RedisCache supports. + * Different from the description in [[Cache]] RedisCache allows the expire parameter of + * [[set]] and [[add]] to be a floating point number, so you may specify the time in milliseconds. * * To use RedisCache as the cache application component, configure the application as follows, * @@ -110,7 +112,7 @@ class RedisCache extends Cache */ protected function getValue($key) { - return $this->_connection->executeCommand('GET', $key); + return $this->_connection->executeCommand('GET', array($key)); } /** @@ -120,7 +122,13 @@ class RedisCache extends Cache */ protected function getValues($keys) { - return $this->_connection->executeCommand('MGET', $keys); + $response = $this->_connection->executeCommand('MGET', $keys); + $result = array(); + $i = 0; + foreach($keys as $key) { + $result[$key] = $response[$i++]; + } + return $result; } /** diff --git a/tests/unit/framework/caching/CacheTest.php b/tests/unit/framework/caching/CacheTest.php index f9db4f4..021a03c 100644 --- a/tests/unit/framework/caching/CacheTest.php +++ b/tests/unit/framework/caching/CacheTest.php @@ -13,18 +13,35 @@ abstract class CacheTest extends TestCase */ abstract protected function getCacheInstance(); + /** + * @return Cache + */ + public function prepare() + { + $cache = $this->getCacheInstance(); + + $cache->flush(); + $cache->set('string_test', 'string_test'); + $cache->set('number_test', 42); + $cache->set('array_test', array('array_test' => 'array_test')); + $cache['arrayaccess_test'] = new \stdClass(); + + return $cache; + } + public function testSet() { $cache = $this->getCacheInstance(); + $this->assertTrue($cache->set('string_test', 'string_test')); $this->assertTrue($cache->set('number_test', 42)); $this->assertTrue($cache->set('array_test', array('array_test' => 'array_test'))); - $cache['arrayaccess_test'] = new \stdClass(); } public function testGet() { - $cache = $this->getCacheInstance(); + $cache = $this->prepare(); + $this->assertEquals('string_test', $cache->get('string_test')); $this->assertEquals(42, $cache->get('number_test')); @@ -32,51 +49,81 @@ abstract class CacheTest extends TestCase $array = $cache->get('array_test'); $this->assertArrayHasKey('array_test', $array); $this->assertEquals('array_test', $array['array_test']); + } + + public function testArrayAccess() + { + $cache = $this->getCacheInstance(); + $cache['arrayaccess_test'] = new \stdClass(); $this->assertInstanceOf('stdClass', $cache['arrayaccess_test']); } - public function testMget() + public function testGetNonExistent() { $cache = $this->getCacheInstance(); + + $this->assertFalse($cache->get('non_existent_key')); + } + + public function testStoreSpecialValues() + { + $cache = $this->getCacheInstance(); + + $this->assertTrue($cache->set('null_value', null)); + $this->assertNull($cache->get('null_value')); + + $this->assertTrue($cache->set('bool_value', true)); + $this->assertTrue($cache->get('bool_value')); + } + + public function testMget() + { + $cache = $this->prepare(); + $this->assertEquals(array('string_test' => 'string_test', 'number_test' => 42), $cache->mget(array('string_test', 'number_test'))); + // ensure that order does not matter + $this->assertEquals(array('number_test' => 42, 'string_test' => 'string_test'), $cache->mget(array('number_test', 'string_test'))); + $this->assertEquals(array('number_test' => 42, 'non_existent_key' => null), $cache->mget(array('number_test', 'non_existent_key'))); } public function testExpire() { $cache = $this->getCacheInstance(); + $this->assertTrue($cache->set('expire_test', 'expire_test', 2)); sleep(1); $this->assertEquals('expire_test', $cache->get('expire_test')); sleep(2); - $this->assertEquals(false, $cache->get('expire_test')); + $this->assertFalse($cache->get('expire_test')); } public function testAdd() { - $cache = $this->getCacheInstance(); + $cache = $this->prepare(); // should not change existing keys $this->assertFalse($cache->add('number_test', 13)); $this->assertEquals(42, $cache->get('number_test')); - // should store data is it's not there yet + // should store data if it's not there yet $this->assertTrue($cache->add('add_test', 13)); $this->assertEquals(13, $cache->get('add_test')); } public function testDelete() { - $cache = $this->getCacheInstance(); + $cache = $this->prepare(); + $this->assertNotNull($cache->get('number_test')); $this->assertTrue($cache->delete('number_test')); - $this->assertEquals(null, $cache->get('number_test')); + $this->assertFalse($cache->get('number_test')); } public function testFlush() { - $cache = $this->getCacheInstance(); + $cache = $this->prepare(); $this->assertTrue($cache->flush()); - $this->assertEquals(null, $cache->get('add_test')); + $this->assertFalse($cache->get('number_test')); } } diff --git a/tests/unit/framework/caching/RedisCacheTest.php b/tests/unit/framework/caching/RedisCacheTest.php index cc6c304..a92be09 100644 --- a/tests/unit/framework/caching/RedisCacheTest.php +++ b/tests/unit/framework/caching/RedisCacheTest.php @@ -31,4 +31,15 @@ class RedisCacheTest extends CacheTest } return $this->_cacheInstance; } + + public function testExpireMilliseconds() + { + $cache = $this->getCacheInstance(); + + $this->assertTrue($cache->set('expire_test_ms', 'expire_test_ms', 0.2)); + usleep(100000); + $this->assertEquals('expire_test_ms', $cache->get('expire_test_ms')); + usleep(300000); + $this->assertFalse($cache->get('expire_test_ms')); + } } \ No newline at end of file