mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-04-08 17:15:08 +02:00
Do not extend Zend_Config in Icinga\Application\Config
refs #7147 fixes #7580
This commit is contained in:
parent
f8724c504b
commit
83f386f92a
library/Icinga/Application
test/php/library/Icinga/Application
@ -4,14 +4,18 @@
|
||||
|
||||
namespace Icinga\Application;
|
||||
|
||||
use Zend_Config;
|
||||
use Zend_Config_Ini;
|
||||
use Countable;
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use IteratorAggregate;
|
||||
use LogicException;
|
||||
use UnexpectedValueException;
|
||||
use Icinga\Exception\NotReadableError;
|
||||
|
||||
/**
|
||||
* Global registry of application and module configuration.
|
||||
* Container for configuration values and global registry of application and module related configuration.
|
||||
*/
|
||||
class Config extends Zend_Config
|
||||
class Config implements Countable, ArrayAccess, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Configuration directory where ALL (application and module) configuration is located
|
||||
@ -20,13 +24,6 @@ class Config extends Zend_Config
|
||||
*/
|
||||
public static $configDir;
|
||||
|
||||
/**
|
||||
* The INI file this configuration has been loaded from or should be written to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $configFile;
|
||||
|
||||
/**
|
||||
* Application config instances per file
|
||||
*
|
||||
@ -42,95 +39,34 @@ class Config extends Zend_Config
|
||||
protected static $modules = array();
|
||||
|
||||
/**
|
||||
* Load configuration from the given INI file
|
||||
* This config's data
|
||||
*
|
||||
* @param string $file The file to parse
|
||||
*
|
||||
* @throws NotReadableError When the file does not exist or cannot be read
|
||||
* @var array
|
||||
*/
|
||||
public static function fromIni($file)
|
||||
{
|
||||
$config = new static(array(), true);
|
||||
$filepath = realpath($file);
|
||||
|
||||
if ($filepath === false) {
|
||||
$config->setConfigFile($file);
|
||||
} elseif (is_readable($filepath)) {
|
||||
$config->setConfigFile($filepath);
|
||||
$config->merge(new Zend_Config_Ini($filepath));
|
||||
} else {
|
||||
throw new NotReadableError('Cannot read config file "%s". Permission denied', $filepath);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Retrieve a application config instance
|
||||
* The INI file this configuration has been loaded from or should be written to
|
||||
*
|
||||
* @param string $configname The configuration name (without ini suffix) to read and return
|
||||
* @param bool $fromDisk When set true, the configuration will be read from the disk, even
|
||||
* if it already has been read
|
||||
*
|
||||
* @return Config The configuration object that has been requested
|
||||
* @var string
|
||||
*/
|
||||
public static function app($configname = 'config', $fromDisk = false)
|
||||
{
|
||||
if (!isset(self::$app[$configname]) || $fromDisk) {
|
||||
self::$app[$configname] = Config::fromIni(self::resolvePath($configname . '.ini'));
|
||||
}
|
||||
return self::$app[$configname];
|
||||
}
|
||||
protected $configFile;
|
||||
|
||||
/**
|
||||
* Set module config
|
||||
* Create a new config
|
||||
*
|
||||
* @param string $moduleName
|
||||
* @param string $configName
|
||||
* @param Zend_Config $config
|
||||
* @param array $data The data to initialize the new config with
|
||||
*/
|
||||
public static function setModuleConfig($moduleName, $configName, Zend_Config $config)
|
||||
public function __construct(array $data = array())
|
||||
{
|
||||
self::$modules[$moduleName][$configName] = $config;
|
||||
}
|
||||
$this->data = array();
|
||||
|
||||
/**
|
||||
* Retrieve a module config instance
|
||||
*
|
||||
* @param string $modulename The name of the module to look for configurations
|
||||
* @param string $configname The configuration name (without ini suffix) to read and return
|
||||
* @param string $fromDisk Whether to read the configuration from disk
|
||||
*
|
||||
* @return Config The configuration object that has been requested
|
||||
*/
|
||||
public static function module($modulename, $configname = 'config', $fromDisk = false)
|
||||
{
|
||||
if (!isset(self::$modules[$modulename])) {
|
||||
self::$modules[$modulename] = array();
|
||||
}
|
||||
$moduleConfigs = self::$modules[$modulename];
|
||||
if (!isset($moduleConfigs[$configname]) || $fromDisk) {
|
||||
$moduleConfigs[$configname] = Config::fromIni(
|
||||
self::resolvePath('modules/' . $modulename . '/' . $configname . '.ini')
|
||||
);
|
||||
}
|
||||
return $moduleConfigs[$configname];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve names of accessible sections or properties
|
||||
*
|
||||
* @param $name
|
||||
* @return array
|
||||
*/
|
||||
public function keys($name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
return array_keys($this->toArray());
|
||||
} elseif ($this->$name === null) {
|
||||
return array();
|
||||
} else {
|
||||
return array_keys($this->$name->toArray());
|
||||
foreach ($data as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$this->data[$key] = new static($value);
|
||||
} else {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,13 +94,335 @@ class Config extends Zend_Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend configuration base dir if input is relative
|
||||
* Deep clone this config
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->data as $key => $value) {
|
||||
if ($value instanceof self) {
|
||||
$array[$key] = clone $value;
|
||||
} else {
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$this->data = $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the count of available sections and properties
|
||||
*
|
||||
* @param string $path Input path
|
||||
* @return string Absolute path
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a iterator for this config's data
|
||||
*
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given section or property is set
|
||||
*
|
||||
* @param string $key The name of the section or property
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the given property or the config for the given section
|
||||
*
|
||||
* @param string $key The name of the property or section
|
||||
*
|
||||
* @return mixed|NULL The value or NULL in case $key does not exist
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->data)) {
|
||||
return $this->data[$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new property or section
|
||||
*
|
||||
* @param string $key The name of the new property or section
|
||||
* @param mixed $value The value to set for the new property or section
|
||||
*/
|
||||
public function __set($key, $value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$this->data[$key] = new static($value);
|
||||
} else {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given property or section
|
||||
*
|
||||
* @param string $key The property or section to remove
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the given section or property is set
|
||||
*
|
||||
* @param string $key The name of the section or property
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($key)
|
||||
{
|
||||
return isset($this->$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the given property or the config for the given section
|
||||
*
|
||||
* @param string $key The name of the property or section
|
||||
*
|
||||
* @return mixed|NULL The value or NULL in case $key does not exist
|
||||
*/
|
||||
public function offsetGet($key)
|
||||
{
|
||||
return $this->$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new property or section
|
||||
*
|
||||
* @param string $key The name of the new property or section
|
||||
* @param mixed $value The value to set for the new property or section
|
||||
*/
|
||||
public function offsetSet($key, $value)
|
||||
{
|
||||
if ($key === null) {
|
||||
throw new LogicException('Appending values without an explicit key is not supported');
|
||||
}
|
||||
|
||||
$this->$key = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given property or section
|
||||
*
|
||||
* @param string $key The property or section to remove
|
||||
*/
|
||||
public function offsetUnset($key)
|
||||
{
|
||||
unset($this->$key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this config has any data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->count() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for the given property or the config for the given section
|
||||
*
|
||||
* @param string $key The name of the property or section
|
||||
* @param mixed $default The value to return in case the property or section is missing
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$value = $this->$key;
|
||||
if ($default !== null && $value === null) {
|
||||
$value = $default;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all section and property names
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function keys()
|
||||
{
|
||||
return array_keys($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this config's data as associative array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->data as $key => $value) {
|
||||
if ($value instanceof self) {
|
||||
$array[$key] = $value->toArray();
|
||||
} else {
|
||||
$array[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the given data with this config
|
||||
*
|
||||
* @param array|Config $data An array or a config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function merge($data)
|
||||
{
|
||||
if ($data instanceof self) {
|
||||
$data = $data->toArray();
|
||||
}
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (array_key_exists($key, $this->data)) {
|
||||
if (is_array($value)) {
|
||||
if ($this->data[$key] instanceof self) {
|
||||
$this->data[$key]->merge($value);
|
||||
} else {
|
||||
$this->data[$key] = new static($value);
|
||||
}
|
||||
} else {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
} else {
|
||||
$this->data[$key] = is_array($value) ? new static($value) : $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value from a section's property
|
||||
*
|
||||
* @param string $section The section where the given property can be found
|
||||
* @param string $key The section's property to fetch the value from
|
||||
* @param mixed $default The value to return in case the section or the property is missing
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws UnexpectedValueException In case the given section does not hold any configuration
|
||||
*/
|
||||
public function fromSection($section, $key, $default = null)
|
||||
{
|
||||
$value = $this->$section;
|
||||
if ($value instanceof self) {
|
||||
$value = $value->$key;
|
||||
} elseif ($value !== null) {
|
||||
throw new UnexpectedValueException(
|
||||
sprintf('Value "%s" is not of type "Config" or a sub-type of it', $value)
|
||||
);
|
||||
}
|
||||
|
||||
if ($default !== null) {
|
||||
$value = $default;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load configuration from the given INI file
|
||||
*
|
||||
* @param string $file The file to parse
|
||||
*
|
||||
* @throws NotReadableError When the file does not exist or cannot be read
|
||||
*/
|
||||
public static function fromIni($file)
|
||||
{
|
||||
$config = new static();
|
||||
|
||||
$filepath = realpath($file);
|
||||
if ($filepath === false) {
|
||||
$config->setConfigFile($file);
|
||||
} elseif (is_readable($filepath)) {
|
||||
$config->setConfigFile($filepath);
|
||||
$config->merge(parse_ini_file($filepath, true, INI_SCANNER_RAW));
|
||||
} else {
|
||||
throw new NotReadableError(t('Cannot read config file "%s". Permission denied'), $filepath);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend configuration base dir to the given relative path
|
||||
*
|
||||
* @param string $path A relative path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function resolvePath($path)
|
||||
{
|
||||
return self::$configDir . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a application config
|
||||
*
|
||||
* @param string $configname The configuration name (without ini suffix) to read and return
|
||||
* @param bool $fromDisk When set true, the configuration will be read from disk, even
|
||||
* if it already has been read
|
||||
*
|
||||
* @return Config The requested configuration
|
||||
*/
|
||||
public static function app($configname = 'config', $fromDisk = false)
|
||||
{
|
||||
if (!isset(self::$app[$configname]) || $fromDisk) {
|
||||
self::$app[$configname] = static::fromIni(static::resolvePath($configname . '.ini'));
|
||||
}
|
||||
|
||||
return self::$app[$configname];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a module config
|
||||
*
|
||||
* @param string $modulename The name of the module where to look for the requested configuration
|
||||
* @param string $configname The configuration name (without ini suffix) to read and return
|
||||
* @param string $fromDisk When set true, the configuration will be read from disk, even
|
||||
* if it already has been read
|
||||
*
|
||||
* @return Config The requested configuration
|
||||
*/
|
||||
public static function module($modulename, $configname = 'config', $fromDisk = false)
|
||||
{
|
||||
if (!isset(self::$modules[$modulename])) {
|
||||
self::$modules[$modulename] = array();
|
||||
}
|
||||
|
||||
$moduleConfigs = self::$modules[$modulename];
|
||||
if (!isset($moduleConfigs[$configname]) || $fromDisk) {
|
||||
$moduleConfigs[$configname] = static::fromIni(
|
||||
static::resolvePath('modules/' . $modulename . '/' . $configname . '.ini')
|
||||
);
|
||||
}
|
||||
|
||||
return $moduleConfigs[$configname];
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
namespace Tests\Icinga\Application;
|
||||
|
||||
use Icinga\Test\BaseTestCase;
|
||||
use Icinga\Application\Config as IcingaConfig;
|
||||
use Icinga\Application\Config;
|
||||
|
||||
class ConfigTest extends BaseTestCase
|
||||
{
|
||||
@ -15,8 +15,8 @@ class ConfigTest extends BaseTestCase
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->configDir = IcingaConfig::$configDir;
|
||||
IcingaConfig::$configDir = dirname(__FILE__) . '/ConfigTest/files';
|
||||
$this->oldConfigDir = Config::$configDir;
|
||||
Config::$configDir = dirname(__FILE__) . '/ConfigTest/files';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,77 +25,327 @@ class ConfigTest extends BaseTestCase
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
IcingaConfig::$configDir = $this->configDir;
|
||||
Config::$configDir = $this->oldConfigDir;
|
||||
}
|
||||
|
||||
public function testAppConfig()
|
||||
public function testWhetherInitializingAConfigWithAssociativeArraysCreatesHierarchicalConfigObjects()
|
||||
{
|
||||
$config = IcingaConfig::app('config', true);
|
||||
$this->assertEquals(1, $config->logging->enable, 'Unexpected value retrieved from config file');
|
||||
// Test non-existent property where null is the default value
|
||||
$this->assertEquals(
|
||||
null,
|
||||
$config->logging->get('disable'),
|
||||
'Unexpected default value for non-existent properties'
|
||||
$config = new Config(array(
|
||||
'a' => 'b',
|
||||
'c' => 'd',
|
||||
'e' => array(
|
||||
'f' => 'g',
|
||||
'h' => 'i',
|
||||
'j' => array(
|
||||
'k' => 'l',
|
||||
'm' => 'n'
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
$this->assertInstanceOf(
|
||||
get_class($config),
|
||||
$config->e,
|
||||
'Config::__construct() does not accept two dimensional arrays'
|
||||
);
|
||||
// Test non-existent property using zero as the default value
|
||||
$this->assertEquals(0, $config->logging->get('disable', 0));
|
||||
// Test retrieve full section
|
||||
$this->assertInstanceOf(
|
||||
get_class($config),
|
||||
$config->e->j,
|
||||
'Config::__construct() does not accept multi dimensional arrays'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherInitializingAConfigWithAssociativeArraysCreatesHierarchicalConfigObjects
|
||||
*/
|
||||
public function testWhetherItIsPossibleToCloneConfigObjects()
|
||||
{
|
||||
$config = new Config(array(
|
||||
'a' => 'b',
|
||||
'c' => array(
|
||||
'd' => 'e'
|
||||
)
|
||||
));
|
||||
$newConfig = clone $config;
|
||||
|
||||
$this->assertNotSame(
|
||||
$config,
|
||||
$newConfig,
|
||||
'Shallow cloning objects of type Config does not seem to work properly'
|
||||
);
|
||||
$this->assertNotSame(
|
||||
$config->c,
|
||||
$newConfig->c,
|
||||
'Deep cloning objects of type Config does not seem to work properly'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherConfigObjectsAreCountable()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => array('d' => 'e')));
|
||||
|
||||
$this->assertInstanceOf('Countable', $config, 'Config objects do not implement interface `Countable\'');
|
||||
$this->assertEquals(2, $config->count(), 'Config objects do not count properties and sections correctly');
|
||||
}
|
||||
|
||||
public function testWhetherOneCanCheckWhetherConfigObjectsHaveACertainPropertyOrSection()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => array('d' => 'e')));
|
||||
|
||||
$this->assertTrue(isset($config->a), 'Config objects do not seem to implement __isset() properly');
|
||||
$this->assertTrue(isset($config->c->d), 'Config objects do not seem to implement __isset() properly');
|
||||
$this->assertFalse(isset($config->d), 'Config objects do not seem to implement __isset() properly');
|
||||
$this->assertFalse(isset($config->c->e), 'Config objects do not seem to implement __isset() properly');
|
||||
$this->assertTrue(isset($config['a']), 'Config object do not seem to implement offsetExists() properly');
|
||||
$this->assertFalse(isset($config['d']), 'Config object do not seem to implement offsetExists() properly');
|
||||
}
|
||||
|
||||
public function testWhetherItIsPossibleToAccessProperties()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => null));
|
||||
|
||||
$this->assertEquals('b', $config->a, 'Config objects do not allow property access');
|
||||
$this->assertNull($config['c'], 'Config objects do not allow offset access');
|
||||
$this->assertNull($config->d, 'Config objects do not return NULL as default');
|
||||
}
|
||||
|
||||
public function testWhetherItIsPossibleToSetPropertiesAndSections()
|
||||
{
|
||||
$config = new Config();
|
||||
$config->a = 'b';
|
||||
$config['c'] = array('d' => 'e');
|
||||
|
||||
$this->assertTrue(isset($config->a), 'Config objects do not allow to set properties');
|
||||
$this->assertTrue(isset($config->c), 'Config objects do not allow to set offsets');
|
||||
$this->assertInstanceOf(
|
||||
get_class($config),
|
||||
$config->c,
|
||||
'Config objects do not convert arrays to config objects when set'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testWhetherItIsNotPossibleToAppendProperties()
|
||||
{
|
||||
$config = new Config();
|
||||
$config[] = 'test';
|
||||
}
|
||||
|
||||
public function testWhetherItIsPossibleToUnsetPropertiesAndSections()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => array('d' => 'e')));
|
||||
unset($config->a);
|
||||
unset($config['c']);
|
||||
|
||||
$this->assertFalse(isset($config->a), 'Config objects do not allow to unset properties');
|
||||
$this->assertFalse(isset($config->c), 'Config objects do not allow to unset sections');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherConfigObjectsAreCountable
|
||||
*/
|
||||
public function testWhetherOneCanCheckIfAConfigObjectHasAnyPropertiesOrSections()
|
||||
{
|
||||
$config = new Config();
|
||||
$this->assertTrue($config->isEmpty(), 'Config objects do not report that they are empty');
|
||||
|
||||
$config->test = 'test';
|
||||
$this->assertFalse($config->isEmpty(), 'Config objects do report that they are empty although they are not');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherItIsPossibleToAccessProperties
|
||||
*/
|
||||
public function testWhetherItIsPossibleToRetrieveDefaultValuesForNonExistentPropertiesOrSections()
|
||||
{
|
||||
$config = new Config(array('a' => 'b'));
|
||||
|
||||
$this->assertEquals(
|
||||
'b',
|
||||
$config->get('a'),
|
||||
'Config objects do not return the actual value of existing properties'
|
||||
);
|
||||
$this->assertNull(
|
||||
$config->get('b'),
|
||||
'Config objects do not return NULL as default for non-existent properties'
|
||||
);
|
||||
$this->assertEquals(
|
||||
'test',
|
||||
$config->get('test', 'test'),
|
||||
'Config objects do not allow to define the default value to return for non-existent properties'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherItIsPossibleToRetrieveAllPropertyAndSectionNames()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => array('d' => 'e')));
|
||||
|
||||
$this->assertEquals(
|
||||
array('a', 'c'),
|
||||
$config->keys(),
|
||||
'Config objects do not list property and section names correctly'
|
||||
);
|
||||
}
|
||||
|
||||
public function testWhetherConfigObjectsCanBeConvertedToArrays()
|
||||
{
|
||||
$config = new Config(array('a' => 'b', 'c' => array('d' => 'e')));
|
||||
|
||||
$this->assertEquals(
|
||||
array('a' => 'b', 'c' => array('d' => 'e')),
|
||||
$config->toArray(),
|
||||
'Config objects cannot be correctly converted to arrays'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherConfigObjectsCanBeConvertedToArrays
|
||||
*/
|
||||
public function testWhetherItIsPossibleToMergeConfigObjects()
|
||||
{
|
||||
$config = new Config(array('a' => 'b'));
|
||||
|
||||
$config->merge(array('a' => 'bb', 'c' => 'd', 'e' => array('f' => 'g')));
|
||||
$this->assertEquals(
|
||||
array('a' => 'bb', 'c' => 'd', 'e' => array('f' => 'g')),
|
||||
$config->toArray(),
|
||||
'Config objects cannot be extended with arrays'
|
||||
);
|
||||
|
||||
$config->merge(new Config(array('c' => array('d' => 'ee'), 'e' => array('h' => 'i'))));
|
||||
$this->assertEquals(
|
||||
array('a' => 'bb', 'c' => array('d' => 'ee'), 'e' => array('f' => 'g', 'h' => 'i')),
|
||||
$config->toArray(),
|
||||
'Config objects cannot be extended with other Config objects'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherItIsPossibleToAccessProperties
|
||||
*/
|
||||
public function testWhetherItIsPossibleToDirectlyRetrieveASectionProperty()
|
||||
{
|
||||
$config = new Config(array('a' => array('b' => 'c')));
|
||||
|
||||
$this->assertEquals(
|
||||
'c',
|
||||
$config->fromSection('a', 'b'),
|
||||
'Config::fromSection does not return the actual value of a section\'s property'
|
||||
);
|
||||
$this->assertNull(
|
||||
$config->fromSection('a', 'c'),
|
||||
'Config::fromSection does not return NULL as default for non-existent section properties'
|
||||
);
|
||||
$this->assertNull(
|
||||
$config->fromSection('b', 'c'),
|
||||
'Config::fromSection does not return NULL as default for non-existent sections'
|
||||
);
|
||||
$this->assertEquals(
|
||||
'test',
|
||||
$config->fromSection('a', 'c', 'test'),
|
||||
'Config::fromSection does not return the given default value for non-existent section properties'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException UnexpectedValueException
|
||||
* @depends testWhetherItIsPossibleToAccessProperties
|
||||
*/
|
||||
public function testWhetherAnExceptionIsThrownWhenTryingToAccessASectionPropertyOnANonSection()
|
||||
{
|
||||
$config = new Config(array('a' => 'b'));
|
||||
$config->fromSection('a', 'b');
|
||||
}
|
||||
|
||||
public function testWhetherConfigResolvePathReturnsValidAbsolutePaths()
|
||||
{
|
||||
$this->assertEquals(
|
||||
Config::$configDir . DIRECTORY_SEPARATOR . 'a' . DIRECTORY_SEPARATOR . 'b.ini',
|
||||
Config::resolvePath(DIRECTORY_SEPARATOR . 'a' . DIRECTORY_SEPARATOR . 'b.ini'),
|
||||
'Config::resolvePath does not produce valid absolute paths'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherConfigObjectsCanBeConvertedToArrays
|
||||
* @depends testWhetherConfigResolvePathReturnsValidAbsolutePaths
|
||||
*/
|
||||
public function testWhetherItIsPossibleToInitializeAConfigObjectFromAIniFile()
|
||||
{
|
||||
$config = Config::fromIni(Config::resolvePath('config.ini'));
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'disable' => 1,
|
||||
'db' => array(
|
||||
'user' => 'user',
|
||||
'password' => 'password'
|
||||
'logging' => array(
|
||||
'enable' => 1
|
||||
),
|
||||
'backend' => array(
|
||||
'type' => 'db',
|
||||
'user' => 'user',
|
||||
'password' => 'password',
|
||||
'disable' => 1
|
||||
)
|
||||
),
|
||||
$config->backend->toArray()
|
||||
$config->toArray(),
|
||||
'Config::fromIni does not load INI files correctly'
|
||||
);
|
||||
// Test non-existent section using 'default' as default value
|
||||
$this->assertEquals('default', $config->get('magic', 'default'));
|
||||
// Test sub-properties
|
||||
$this->assertEquals('user', $config->backend->db->user);
|
||||
// Test non-existent sub-property using 'UTF-8' as the default value
|
||||
$this->assertEquals('UTF-8', $config->backend->db->get('encoding', 'UTF-8'));
|
||||
// Test invalid property names using false as default value
|
||||
$this->assertEquals(false, $config->backend->get('.', false));
|
||||
$this->assertEquals(false, $config->backend->get('db.', false));
|
||||
$this->assertEquals(false, $config->backend->get('.user', false));
|
||||
// Test retrieve array of sub-properties
|
||||
|
||||
$this->assertInstanceOf(
|
||||
get_class($config),
|
||||
Config::fromIni('nichda'),
|
||||
'Config::fromIni does not return empty configs for non-existent configuration files'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Icinga\Exception\NotReadableError
|
||||
*/
|
||||
public function testWhetherFromIniThrowsAnExceptionOnInsufficientPermission()
|
||||
{
|
||||
Config::fromIni('/etc/shadow');
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testWhetherItIsPossibleToInitializeAConfigObjectFromAIniFile
|
||||
*/
|
||||
public function testWhetherItIsPossibleToRetrieveApplicationConfiguration()
|
||||
{
|
||||
$config = Config::app();
|
||||
|
||||
$this->assertEquals(
|
||||
array(
|
||||
'user' => 'user',
|
||||
'password' => 'password'
|
||||
'logging' => array(
|
||||
'enable' => 1
|
||||
),
|
||||
'backend' => array(
|
||||
'type' => 'db',
|
||||
'user' => 'user',
|
||||
'password' => 'password',
|
||||
'disable' => 1
|
||||
)
|
||||
),
|
||||
$config->backend->db->toArray()
|
||||
$config->toArray(),
|
||||
'Config::app does not load INI files correctly'
|
||||
);
|
||||
// Test singleton
|
||||
$this->assertEquals($config, IcingaConfig::app('config'));
|
||||
$this->assertEquals(array('logging', 'backend'), $config->keys());
|
||||
$this->assertEquals(array('enable'), $config->keys('logging'));
|
||||
}
|
||||
|
||||
public function testAppExtraConfig()
|
||||
/**
|
||||
* @depends testWhetherItIsPossibleToInitializeAConfigObjectFromAIniFile
|
||||
*/
|
||||
public function testWhetherItIsPossibleToRetrieveModuleConfiguration()
|
||||
{
|
||||
$extraConfig = IcingaConfig::app('extra', true);
|
||||
$this->assertEquals(1, $extraConfig->meta->version);
|
||||
$this->assertEquals($extraConfig, IcingaConfig::app('extra'));
|
||||
}
|
||||
$config = Config::module('amodule');
|
||||
|
||||
public function testModuleConfig()
|
||||
{
|
||||
$moduleConfig = IcingaConfig::module('amodule', 'config', true);
|
||||
$this->assertEquals(1, $moduleConfig->menu->get('breadcrumb'));
|
||||
$this->assertEquals($moduleConfig, IcingaConfig::module('amodule'));
|
||||
}
|
||||
|
||||
public function testModuleExtraConfig()
|
||||
{
|
||||
$moduleExtraConfig = IcingaConfig::module('amodule', 'extra', true);
|
||||
$this->assertEquals(
|
||||
'inetOrgPerson',
|
||||
$moduleExtraConfig->ldap->user->get('ldap_object_class')
|
||||
array(
|
||||
'menu' => array(
|
||||
'breadcrumb' => 1
|
||||
)
|
||||
),
|
||||
$config->toArray(),
|
||||
'Config::module does not load INI files correctly'
|
||||
);
|
||||
$this->assertEquals($moduleExtraConfig, IcingaConfig::module('amodule', 'extra'));
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
enable = 1
|
||||
|
||||
[backend]
|
||||
db.user = 'user'
|
||||
db.password = 'password'
|
||||
type = "db"
|
||||
user = "user"
|
||||
password = "password"
|
||||
disable = 1
|
||||
|
@ -1,2 +0,0 @@
|
||||
[meta]
|
||||
version = 1
|
@ -1,2 +0,0 @@
|
||||
[ldap]
|
||||
user.ldap_object_class = inetOrgPerson
|
Loading…
x
Reference in New Issue
Block a user