From: Kunal Mehta Date: Mon, 11 Aug 2014 12:17:37 +0000 (+0100) Subject: Add MultiConfig for fallback logic X-Git-Tag: 1.31.0-rc.0~13964^2 X-Git-Url: http://git.cyclocoop.org/%28?a=commitdiff_plain;h=412c4668f132a1ea8b9998b4d34435656d5303c4;p=lhc%2Fweb%2Fwiklou.git Add MultiConfig for fallback logic This change adds MultiConfig and HashConfig classes, but does not actually use them anywhere. In a future change, we can convert DefaultSettings.php into a HashConfig instance and use MultiConfig as the 'main' config instance. Bug: 69418 Change-Id: I0ef2fbb86d5c27602d70240219ee08be31e2d09b --- diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 4c35bfd384..41443255e2 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -374,6 +374,8 @@ $wgAutoloadLocalClasses = array( 'ConfigException' => 'includes/config/ConfigException.php', 'ConfigFactory' => 'includes/config/ConfigFactory.php', 'GlobalVarConfig' => 'includes/config/GlobalVarConfig.php', + 'HashConfig' => 'includes/config/HashConfig.php', + 'MultiConfig' => 'includes/config/MultiConfig.php', 'MutableConfig' => 'includes/config/MutableConfig.php', # includes/content diff --git a/includes/config/Config.php b/includes/config/Config.php index 03d2cb990f..38f589dcd0 100644 --- a/includes/config/Config.php +++ b/includes/config/Config.php @@ -35,4 +35,13 @@ interface Config { * @throws ConfigException */ public function get( $name ); + + /** + * Check whether a configuration option is set for the given name + * + * @param string $name Name of configuration option + * @return bool + * @since 1.24 + */ + public function has( $name ); } diff --git a/includes/config/GlobalVarConfig.php b/includes/config/GlobalVarConfig.php index 1144384beb..39d6e8e1db 100644 --- a/includes/config/GlobalVarConfig.php +++ b/includes/config/GlobalVarConfig.php @@ -49,9 +49,19 @@ class GlobalVarConfig implements Config { * @see Config::get */ public function get( $name ) { + if ( !$this->has( $name ) ) { + throw new ConfigException( __METHOD__ . ": undefined option: '$name'" ); + } return $this->getWithPrefix( $this->prefix, $name ); } + /** + * @see Config::has + */ + public function has( $name ) { + return $this->hasWithPrefix( $this->prefix, $name ); + } + /** * @see MutableConfig::set * @deprecated since 1.24 @@ -66,15 +76,22 @@ class GlobalVarConfig implements Config { * * @param string $prefix Prefix to use on the variable, if one. * @param string $name Variable name without prefix - * @throws ConfigException * @return mixed */ protected function getWithPrefix( $prefix, $name ) { + return $GLOBALS[$prefix . $name]; + } + + /** + * Check if a variable with a given prefix is set + * + * @param string $prefix Prefix to use on the variable + * @param string $name Variable name without prefix + * @return bool + */ + protected function hasWithPrefix( $prefix, $name ) { $var = $prefix . $name; - if ( !array_key_exists( $var, $GLOBALS ) ) { - throw new ConfigException( __METHOD__ . ": undefined variable: '$var'" ); - } - return $GLOBALS[$var]; + return array_key_exists( $var, $GLOBALS ); } /** diff --git a/includes/config/HashConfig.php b/includes/config/HashConfig.php new file mode 100644 index 0000000000..a09a0a433f --- /dev/null +++ b/includes/config/HashConfig.php @@ -0,0 +1,75 @@ +settings = $settings; + } + + /** + * @see Config::get + */ + public function get( $name ) { + if ( !$this->has( $name ) ) { + throw new ConfigException( __METHOD__ . ": undefined option: '$name'" ); + } + + return $this->settings[$name]; + } + + /** + * @see Config::has + */ + public function has( $name ) { + return array_key_exists( $name, $this->settings ); + } + + /** + * @see Config::set + */ + public function set( $name, $value ) { + $this->settings[$name] = $value; + } +} diff --git a/includes/config/MultiConfig.php b/includes/config/MultiConfig.php new file mode 100644 index 0000000000..cbb65aa609 --- /dev/null +++ b/includes/config/MultiConfig.php @@ -0,0 +1,72 @@ +configs = $configs; + } + + /** + * @see Config::get + */ + public function get( $name ) { + foreach ( $this->configs as $config ) { + if ( $config->has( $name ) ) { + return $config->get( $name ); + } + } + + throw new ConfigException( __METHOD__ . ": undefined option: '$name'" ); + } + + /** + * @see Config::has + */ + public function has( $name ) { + foreach ( $this->configs as $config ) { + if ( $config->has( $name ) ) { + return true; + } + } + + return false; + } +} diff --git a/tests/phpunit/includes/config/GlobalVarConfigTest.php b/tests/phpunit/includes/config/GlobalVarConfigTest.php index b15ffa7210..275019615e 100644 --- a/tests/phpunit/includes/config/GlobalVarConfigTest.php +++ b/tests/phpunit/includes/config/GlobalVarConfigTest.php @@ -38,6 +38,18 @@ class GlobalVarConfigTest extends MediaWikiTestCase { ); } + /** + * @covers GlobalVarConfig::has + */ + public function testHas() { + $this->maybeStashGlobal( 'wgGlobalVarConfigTestHas' ); + $GLOBALS['wgGlobalVarConfigTestHas'] = wfRandomString(); + $this->maybeStashGlobal( 'wgGlobalVarConfigTestNotHas' ); + $config = new GlobalVarConfig(); + $this->assertTrue( $config->has( 'GlobalVarConfigTestHas' ) ); + $this->assertFalse( $config->has( 'GlobalVarConfigTestNotHas' ) ); + } + public function provideGet() { $set = array( 'wgSomething' => 'default1', @@ -70,7 +82,7 @@ class GlobalVarConfigTest extends MediaWikiTestCase { public function testGet( $name, $prefix, $expected ) { $config = new GlobalVarConfig( $prefix ); if ( $expected === false ) { - $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::getWithPrefix: undefined variable:' ); + $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::get: undefined option:' ); } $this->assertEquals( $config->get( $name ), $expected ); } diff --git a/tests/phpunit/includes/config/HashConfigTest.php b/tests/phpunit/includes/config/HashConfigTest.php new file mode 100644 index 0000000000..3ad3bfbd66 --- /dev/null +++ b/tests/phpunit/includes/config/HashConfigTest.php @@ -0,0 +1,63 @@ +assertInstanceOf( 'HashConfig', $conf ); + } + + /** + * @covers HashConfig::__construct + */ + public function testConstructor() { + $conf = new HashConfig(); + $this->assertInstanceOf( 'HashConfig', $conf ); + + // Test passing arguments to the constructor + $conf2 = new HashConfig( array( + 'one' => '1', + ) ); + $this->assertEquals( '1', $conf2->get( 'one' ) ); + } + + /** + * @covers HashConfig::get + */ + public function testGet() { + $conf = new HashConfig( array( + 'one' => '1', + )); + $this->assertEquals( '1', $conf->get( 'one' ) ); + $this->setExpectedException( 'ConfigException', 'HashConfig::get: undefined option' ); + $conf->get( 'two' ); + } + + /** + * @covers HashConfig::has + */ + public function testHas() { + $conf = new HashConfig( array( + 'one' => '1', + ) ); + $this->assertTrue( $conf->has( 'one' ) ); + $this->assertFalse( $conf->has( 'two' ) ); + } + + /** + * @covers HashConfig::set + */ + public function testSet() { + $conf = new HashConfig( array( + 'one' => '1', + ) ); + $conf->set( 'two', '2' ); + $this->assertEquals( '2', $conf->get( 'two' ) ); + // Check that set overwrites + $conf->set( 'one', '3' ); + $this->assertEquals( '3', $conf->get( 'one' ) ); + } +} \ No newline at end of file diff --git a/tests/phpunit/includes/config/MultiConfigTest.php b/tests/phpunit/includes/config/MultiConfigTest.php new file mode 100644 index 0000000000..158da466ef --- /dev/null +++ b/tests/phpunit/includes/config/MultiConfigTest.php @@ -0,0 +1,38 @@ + 'bar' ) ), + new HashConfig( array( 'foo' => 'baz', 'bar' => 'foo' ) ), + new HashConfig( array( 'bar' => 'baz' ) ), + ) ); + + $this->assertEquals( 'bar', $multi->get( 'foo' ) ); + $this->assertEquals( 'foo', $multi->get( 'bar' ) ); + $this->setExpectedException( 'ConfigException', 'MultiConfig::get: undefined option:' ); + $multi->get( 'notset' ); + } + + /** + * @covers MultiConfig::has + */ + public function testHas() { + $conf = new MultiConfig( array( + new HashConfig( array( 'foo' => 'foo' ) ), + new HashConfig( array( 'something' => 'bleh' ) ), + new HashConfig( array( 'meh' => 'eh' ) ), + ) ); + + $this->assertTrue( $conf->has( 'foo' ) ); + $this->assertTrue( $conf->has( 'something' ) ); + $this->assertTrue( $conf->has( 'meh' ) ); + $this->assertFalse( $conf->has( 'what' ) ); + } +}