added test for configuration
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
namespace BSR\Config;
|
namespace BSR\Config;
|
||||||
|
|
||||||
class Configuration {
|
class Configuration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var BSR\Config\Configuration
|
||||||
|
*/
|
||||||
private static $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,28 +23,93 @@ class Configuration {
|
|||||||
*/
|
*/
|
||||||
private $values = array();
|
private $values = array();
|
||||||
|
|
||||||
private $custom_config_filename = 'configuration.local.php';
|
private $customConfigFilename = 'configuration.local.php';
|
||||||
|
|
||||||
private function __construct() {
|
private function __construct()
|
||||||
// by default, set the session save path to the default value;
|
{
|
||||||
$this->values['session']['save_path'] = session_save_path();
|
if (!isset($this->values['session'])) {
|
||||||
|
$this->values['session'] = array();
|
||||||
if(!file_exists($this->custom_config_filename)) {
|
|
||||||
throw new \RuntimeException('No configuration.local.php file was found. Create it with the proper config.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$configuration = include_once realpath(dirname(__FILE__) . '/../config/') . $this->custom_config_filename;
|
|
||||||
|
|
||||||
if(!is_array($configuration)) {
|
|
||||||
throw new \RuntimeException("You custom configuration in '{$this->custom_config_filename}' must be in a variable named '\$configuration' and be an array.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->values = array_replace_recursive($this->values, $configuration);
|
if (!isset($this->values['session']['save_path'])) {
|
||||||
|
$this->values['session']['save_path'] = session_save_path();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function dotNotationAccess($data, $key, $default=null)
|
/**
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public function getCustomConfigFilePath()
|
||||||
|
{
|
||||||
|
return realpath(dirname(__FILE__) . '/../../../../../config/') . $this->customConfigFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function getCustomConfigFromFile()
|
||||||
|
{
|
||||||
|
if (!file_exists($this->getCustomConfigFilePath())) {
|
||||||
|
throw new \RuntimeException("The file : {$this->getCustomConfigFilePath()} does not exist");
|
||||||
|
}
|
||||||
|
return include $this->getCustomConfigFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function loadCustomConfigFromFile()
|
||||||
|
{
|
||||||
|
$this->setCustomConfig($this->getCustomConfigFromFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $config
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setCustomConfig(array $config)
|
||||||
|
{
|
||||||
|
$this->values = array_replace_recursive($this->values, $config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getConfig()
|
||||||
|
{
|
||||||
|
return $this->values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the nested key exists
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @param array $keys
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function existsKeys(array $data, array $keys)
|
||||||
|
{
|
||||||
|
foreach ($keys as $k) {
|
||||||
|
if (!isset($data[$k])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$data = $data[$k];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param array $keys
|
||||||
|
* @param any $default
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function fetchRecursive(array $data, array $keys, $default = null)
|
||||||
{
|
{
|
||||||
$keys = explode('.', $key);
|
|
||||||
foreach ($keys as $k) {
|
foreach ($keys as $k) {
|
||||||
if (!is_array($data)) {
|
if (!is_array($data)) {
|
||||||
throw new \Exception("Try to access non-array as array, key '$key''");
|
throw new \Exception("Try to access non-array as array, key '$key''");
|
||||||
@@ -48,26 +117,62 @@ class Configuration {
|
|||||||
if (!isset($data[$k])) {
|
if (!isset($data[$k])) {
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $data[$k];
|
$data = $data[$k];
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function value($name, $default) {
|
/**
|
||||||
return $this->dotNotationAccess($this->values, $name, $default);
|
* Return array of keys if dot notation string is passed
|
||||||
|
* @param string|array $keys
|
||||||
|
*/
|
||||||
|
public static function parseKeys($keys)
|
||||||
|
{
|
||||||
|
if (is_string($keys)) {
|
||||||
|
$keys = explode('.', $keys);
|
||||||
|
} else if (!is_array($keys)) {
|
||||||
|
throw new \RuntimeException('Unsupported $keys paramater type');
|
||||||
|
}
|
||||||
|
return $keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function value($keys, $default)
|
||||||
|
{
|
||||||
|
return self::fetchRecursive($this->values, self::parseKeys($keys), $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public static function has($keys)
|
||||||
|
{
|
||||||
|
return self::existsKeys(self::get(), self::parseKeys($keys));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param $name
|
* @param $name
|
||||||
* @param mixed $default the default value for your configuration option
|
* @param mixed $default the default value for your configuration option
|
||||||
* @return mixed return the configuration value if the key is find, the default otherwise
|
* @return mixed return the configuration value if the key is find, the default otherwise
|
||||||
*/
|
*/
|
||||||
public static function get($name, $default = null) {
|
public static function get($name = null, $default = null)
|
||||||
|
{
|
||||||
|
if (null === $name) {
|
||||||
|
return self::getInstance()->getConfig();
|
||||||
|
}
|
||||||
|
return self::getInstance()->value($name, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BSR\Config\Configuration
|
||||||
|
*/
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
if(is_null(self::$instance)) {
|
if(is_null(self::$instance)) {
|
||||||
self::$instance = new Configuration();
|
self::$instance = new Configuration();
|
||||||
}
|
}
|
||||||
|
return self::$instance;
|
||||||
return self::$instance->value($name, $default);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
tests/Config/ConfigurationTest.php
Normal file
116
tests/Config/ConfigurationTest.php
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
namespace BSR\Config;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ConfigurationTest extends TestCase
|
||||||
|
{
|
||||||
|
protected $testConfig = array(
|
||||||
|
'session' => 'override',
|
||||||
|
'a' => array(
|
||||||
|
'b' => array(
|
||||||
|
'c' => 'C',
|
||||||
|
'c2' => 'D'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $defaultConfig;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->defaultConfig = array('session' => array('save_path' => session_save_path()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConfigurationInstanceIsTheSame()
|
||||||
|
{
|
||||||
|
$this->assertSame(Configuration::getInstance(), Configuration::getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInitialDefaultConfigContainsOnlyDefaultSessionSavePath()
|
||||||
|
{
|
||||||
|
$this->assertSame(Configuration::getInstance()->getConfig(), $this->defaultConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testConfigChangesAfterSettingCustomConfig()
|
||||||
|
{
|
||||||
|
$preConfig = Configuration::getInstance()->getConfig();
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->testConfig);
|
||||||
|
$postConfig = Configuration::getInstance()->getConfig();
|
||||||
|
$this->assertNotSame($preConfig, $postConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCustomConfigGetsMergedProperly()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->testConfig);
|
||||||
|
$this->assertSame(Configuration::getInstance()->getConfig(), $this->testConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReturnsFalseIfHasKeyButNotMostNestedKey()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->testConfig);
|
||||||
|
$this->assertEquals(Configuration::has(array('session', 'save_path')), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReturnsFalseIfHasNotInitialKeyButHasNestedKey()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
$this->assertEquals(Configuration::has(array('z', 'save_path')), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReturnsFalseIfHasNoneOfKeyPath()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
$this->assertEquals(Configuration::has(array('z', 'w')), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReturnsTrueIfHasKeyPath()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
$this->assertEquals(Configuration::has(array('session', 'save_path')), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanGetNestedKeyValueFromKeysList()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
$this->assertSame(
|
||||||
|
Configuration::get(array('session', 'save_path')),
|
||||||
|
$this->defaultConfig['session']['save_path']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReturnsDefaultParamIfKeyNotSet()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
$default = "some_random_thing";
|
||||||
|
$this->assertSame(
|
||||||
|
Configuration::get(array('x', 'y'), $default),
|
||||||
|
$default
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testKeysInDotNotationGetConvertedToKeysArray()
|
||||||
|
{
|
||||||
|
$this->assertSame(
|
||||||
|
Configuration::parseKeys('a.b.c'),
|
||||||
|
array('a', 'b', 'c')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testKeysInDotNotationGetsSameResult()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->defaultConfig);
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->testConfig);
|
||||||
|
$this->assertSame(
|
||||||
|
Configuration::get('a.b.c'),
|
||||||
|
Configuration::get(array('a', 'b', 'c'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetWithoutParamReturnsFullConfigArray()
|
||||||
|
{
|
||||||
|
Configuration::getInstance()->setCustomConfig($this->testConfig);
|
||||||
|
$this->assertSame(Configuration::get(), $this->testConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user