diff --git a/CHANGELOG.md b/CHANGELOG.md index 110270a..5895cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file, in reverse * [#8](https://github.com/sandrokeil/interop-config/issues/8): Introducing HasOptionalOptions Interface * [#9](https://github.com/sandrokeil/interop-config/issues/9): Introducing HasDefaultOptions Interface +* [#13](https://github.com/sandrokeil/interop-config/issues/13): Support for recursive mandatory options check * Benchmark suite ### Deprecated diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d558bd4..5172cf4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,3 +30,11 @@ To do so: - Copy `TestConfig.php.dist` file to `TestConfig.php` - Edit `TestConfig.php` to enable any specific functionality you want to test, as well as to provide test values to utilize. + +## RUNNING BENCHMARKS + +To run benchmarks execute phpbench + + ```sh + $ ./vendor/bin/phpbench run --report=aggregate + ``` diff --git a/benchmark/HasMandatoryOptionsRecursiveContainerIdBench.php b/benchmark/HasMandatoryOptionsRecursiveContainerIdBench.php new file mode 100644 index 0000000..2af3297 --- /dev/null +++ b/benchmark/HasMandatoryOptionsRecursiveContainerIdBench.php @@ -0,0 +1,59 @@ +config = $this->getTestConfig(); + $this->factory = new ConnectionMandatoryRecursiveContainerIdConfiguration(); + } + + /** + * Retrieve options + * + * @revs 1000 + * @iterations 10 + */ + public function options() + { + $this->factory->options($this->config); + } + + /** + * Returns test config + * + * @return array + */ + private function getTestConfig() + { + // Load the user-defined test configuration file, if it exists; otherwise, load default + if (is_readable('test/TestConfig.php')) { + $testConfig = require 'test/testing.config.php'; + } else { + $testConfig = require 'test/testing.config.php.dist'; + } + + return $testConfig; + } +} diff --git a/src/ConfigurationTrait.php b/src/ConfigurationTrait.php index 935238e..bc7f22b 100644 --- a/src/ConfigurationTrait.php +++ b/src/ConfigurationTrait.php @@ -73,17 +73,7 @@ public function options($config) } // check for mandatory options if ($this instanceof HasMandatoryOptions) { - foreach ($this->mandatoryOptions() as $option) { - if (!isset($options[$option])) { - throw new Exception\MandatoryOptionNotFoundException(sprintf( - 'Mandatory option "%s" was not set for configuration "' . "['%s']['%s']%s", - $option, - $vendorName, - $packageName, - $id ? '[' . $id . ']' : '' - )); - } - } + $this->checkMandatoryOptions($this->mandatoryOptions(), $options); } // check for default options if ($this instanceof HasDefaultOptions) { @@ -92,6 +82,40 @@ public function options($config) return $options; } + /** + * Checks if a mandatory param is missing, supports recursion + * + * @param array|ArrayAccess $mandatoryOptions + * @param array|ArrayAccess $options + * @throws Exception\MandatoryOptionNotFoundException + */ + private function checkMandatoryOptions($mandatoryOptions, $options) + { + foreach ($mandatoryOptions as $key => $mandatoryOption) { + # if a string key exists it indicates a recursive check + if (isset($options[$key])) { + $this->checkMandatoryOptions($mandatoryOption, $options[$key]); + return; + } + if (isset($options[$mandatoryOption])) { + continue; + } + $id = null; + + if ($this instanceof HasContainerId) { + $id = $this->containerId(); + } + + throw new Exception\MandatoryOptionNotFoundException(sprintf( + 'Mandatory option "%s" was not set for configuration "' . "['%s']['%s']%s", + $mandatoryOption, + $this->vendorName(), + $this->packageName(), + $id ? '[' . $id . ']' : '' + )); + } + } + /** * @see \Interop\Config\HasConfig::vendorName */ diff --git a/test/ConfigurationTraitTest.php b/test/ConfigurationTraitTest.php index 53bbe69..d6ba659 100644 --- a/test/ConfigurationTraitTest.php +++ b/test/ConfigurationTraitTest.php @@ -14,6 +14,7 @@ use InteropTest\Config\TestAsset\ConnectionDefaultOptionsConfiguration; use InteropTest\Config\TestAsset\ConnectionMandatoryConfiguration; use InteropTest\Config\TestAsset\ConnectionMandatoryContainerIdConfiguration; +use InteropTest\Config\TestAsset\ConnectionMandatoryRecursiveContainerIdConfiguration; use PHPUnit_Framework_TestCase as TestCase; /** @@ -230,6 +231,27 @@ public function testOptionsThrowsRuntimeExceptionIfMandatoryOptionIsMissing() $stub->options($config); } + /** + * Tests if options() throws a runtime exception if a recursive mandatory option is missing + * + * @covers \Interop\Config\ConfigurationTrait::options + */ + public function testOptionsThrowsRuntimeExceptionIfMandatoryOptionRecursiveIsMissing() + { + $stub = new ConnectionMandatoryRecursiveContainerIdConfiguration(); + + $this->setExpectedException( + 'Interop\Config\Exception\MandatoryOptionNotFoundException', + 'Mandatory option "dbname"' + ); + + $config = $this->getTestConfig(); + + unset($config['doctrine']['connection']['orm_default']['params']['dbname']); + + $stub->options($config); + } + /** * Returns test config * diff --git a/test/TestAsset/ConnectionMandatoryRecursiveContainerIdConfiguration.php b/test/TestAsset/ConnectionMandatoryRecursiveContainerIdConfiguration.php new file mode 100644 index 0000000..b87230d --- /dev/null +++ b/test/TestAsset/ConnectionMandatoryRecursiveContainerIdConfiguration.php @@ -0,0 +1,43 @@ + ['user', 'dbname']]; + } +}