Skip to content

Commit

Permalink
Implement redis storage
Browse files Browse the repository at this point in the history
  • Loading branch information
jadb committed Jun 17, 2016
1 parent 29a64b0 commit 2ca3854
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 1 deletion.
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"php": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0"
"phpunit/phpunit": "^5.0",
"predis/predis": "^1.1"
},
"autoload": {
"psr-4": {
Expand All @@ -43,5 +44,8 @@
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"suggest": {
"predis/predis": "If you want to use the `RedisStorage`"
}
}
91 changes: 91 additions & 0 deletions src/Storage/RedisStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php declare(strict_types=1);

/*
* This file is part of the FeatureToggle package.
*
* (c) Jad Bitar <jadbitar@mac.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FeatureToggle\Storage;

use FeatureToggle\Feature\FeatureInterface;
use Predis\Client;

/**
* Redis storage (requires `predis/predis` package).
*/
class RedisStorage extends AbstractStorage
{
/**
* Redis client instance.
*
* @var \Predis\Client
*/
protected $redis;

protected $prefix;

/**
* Constructor.
*
* @param \Predis\Client $redis Redis client.
* @param string $prefix Prefix for all keys.
*/
public function __construct(Client $redis, string $prefix = 'ft_')
{
$this->redis = $redis;
$this->prefix = $prefix;
}

/**
* {@inheritdoc}
*/
public function add(string $alias, FeatureInterface $feature): StorageInterface
{
$this->redis->hset($this->prefix, $alias, $this->feature($feature));
return $this;
}

/**
* {@inheritdoc}
*/
public function get(string $alias): FeatureInterface
{
return unserialize($this->redis->hget($this->prefix, $alias));
}

/**
* {@inheritdoc}
*/
public function index(): array
{
$features = [];

foreach ($this->redis->hgetall($this->prefix) as $alias => $feature) {
$features[$alias] = unserialize($feature);
}

return $features;
}

/**
* {@inheritdoc}
*/
public function remove(string $alias): StorageInterface
{
$this->redis->hdel($this->prefix, [$alias]);
return $this;
}

/**
* {@inheritdoc}
*/
public function flush(): StorageInterface
{
$this->redis->del([$this->prefix]);
return $this;
}
}
102 changes: 102 additions & 0 deletions tests/FeatureToggle/Storage/RedisStorageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php declare(strict_types=1);

/*
* This file is part of the FeatureToggle package.
*
* (c) Jad Bitar <jadbitar@mac.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FeatureToggle\Test\Storage;

use FeatureToggle\Feature\BooleanFeature;
use FeatureToggle\Feature\EnabledFeature;
use FeatureToggle\Storage\RedisStorage;
use Predis\Client;

class RedisStorageTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Predis\Client
*/
private $redis;

/**
* @var \FeatureToggle\Storage\RedisStorage
*/
private $storage;

public function setUp()
{
$this->redis = $this->getMockBuilder(Client::class)
->setMethods(['hset', 'hget', 'hgetall', 'hdel', 'del'])
->getMock();

$this->storage = new RedisStorage($this->redis, 'customPrefix');
}

public function tearDown()
{
unset($this->redis, $this->storage);
}

public function testAdd()
{
$feature = new BooleanFeature('foo');

$this->redis->expects($this->once())
->method('hset')
->with('customPrefix', 'testAlias', serialize($feature));

$result = $this->storage->add('testAlias', $feature);
$this->assertInstanceOf('FeatureToggle\Storage\RedisStorage', $result);
}

public function testGet()
{
$expected = new BooleanFeature('foo');

$this->redis->expects($this->once())
->method('hget')
->with('customPrefix', 'testAlias')
->will($this->returnValue(serialize($expected)));

$result = $this->storage->get('testAlias');
$this->assertEquals($expected, $result);
}

public function testIndex()
{
$boolean = new BooleanFeature('foo');
$enabled = new EnabledFeature('bar');
$expected = compact('boolean', 'enabled');

$this->redis->expects($this->once())
->method('hgetall')
->with('customPrefix')
->will($this->returnValue(array_map('serialize', $expected)));

$result = $this->storage->index();
$this->assertEquals($expected, $result);
}

public function testRemove()
{
$this->redis->expects($this->once())
->method('hdel')
->with('customPrefix', ['testAlias']);

$this->assertInstanceOf(RedisStorage::class, $this->storage->remove('testAlias'));
}

public function testFlush()
{
$this->redis->expects($this->once())
->method('del')
->with(['customPrefix']);

$this->assertInstanceOf(RedisStorage::class, $this->storage->flush());
}
}

0 comments on commit 2ca3854

Please sign in to comment.