From 40d96a8911b311090534c0a68d8797d0b59f1b79 Mon Sep 17 00:00:00 2001 From: Guillermo Dev Date: Thu, 11 Oct 2018 00:40:44 +0200 Subject: [PATCH] added test for configuration --- src/Config/Configuration.php | 143 +++++++++++++++++++++++++---- tests/Config/ConfigurationTest.php | 116 +++++++++++++++++++++++ 2 files changed, 240 insertions(+), 19 deletions(-) create mode 100644 tests/Config/ConfigurationTest.php diff --git a/src/Config/Configuration.php b/src/Config/Configuration.php index c15aeec..19bd720 100644 --- a/src/Config/Configuration.php +++ b/src/Config/Configuration.php @@ -2,6 +2,10 @@ namespace BSR\Config; class Configuration { + + /** + * @var BSR\Config\Configuration + */ private static $instance = null; /** @@ -19,28 +23,93 @@ class Configuration { */ private $values = array(); - private $custom_config_filename = 'configuration.local.php'; + private $customConfigFilename = 'configuration.local.php'; - private function __construct() { - // by default, set the session save path to the default value; - $this->values['session']['save_path'] = session_save_path(); + private function __construct() + { + 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.'); + if (!isset($this->values['session']['save_path'])) { + $this->values['session']['save_path'] = session_save_path(); } - - $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."); + /** + * + * @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(); + } - $this->values = array_replace_recursive($this->values, $configuration); + /** + * + * @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); } - private function dotNotationAccess($data, $key, $default=null) + /** + * @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) { if (!is_array($data)) { throw new \Exception("Try to access non-array as array, key '$key''"); @@ -48,26 +117,62 @@ class Configuration { if (!isset($data[$k])) { return $default; } - $data = $data[$k]; } 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 mixed $default the default value for your configuration option * @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)) { self::$instance = new Configuration(); } - - return self::$instance->value($name, $default); + return self::$instance; } } diff --git a/tests/Config/ConfigurationTest.php b/tests/Config/ConfigurationTest.php new file mode 100644 index 0000000..631965b --- /dev/null +++ b/tests/Config/ConfigurationTest.php @@ -0,0 +1,116 @@ + '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); + } +}