From 9b0f8150f823ca22813ba9871156dabb20a911fa Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 13 Nov 2015 13:11:13 +0100 Subject: [PATCH] Compiler, CompilerExtension: shows suggestions for unexpected config items and extensions --- composer.json | 2 +- src/DI/Compiler.php | 9 ++++++--- src/DI/CompilerExtension.php | 5 +++-- tests/DI/CompilerExtension.validateConfig.phpt | 6 +++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index b0a54527a..91404951d 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "php": ">=5.6.0", "nette/neon": "^2.3.3", "nette/php-generator": "^2.4", - "nette/utils": "^2.3" + "nette/utils": "^2.4" }, "require-dev": { "nette/tester": "^1.6" diff --git a/src/DI/Compiler.php b/src/DI/Compiler.php index 44f294928..dfe360540 100644 --- a/src/DI/Compiler.php +++ b/src/DI/Compiler.php @@ -179,9 +179,12 @@ public function processExtensions() $extra = implode("', '", array_keys($extra)); throw new Nette\DeprecatedException("Extensions '$extra' were added while container was being compiled."); - } elseif ($extra = array_diff_key($this->config, self::$reserved, $this->extensions)) { - $extra = implode("', '", array_keys($extra)); - throw new Nette\InvalidStateException("Found sections '$extra' in configuration, but corresponding extensions are missing."); + } elseif ($extra = key(array_diff_key($this->config, self::$reserved, $this->extensions))) { + $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys(self::$reserved + $this->extensions), $extra); + throw new Nette\InvalidStateException( + "Found section '$extra' in configuration, but corresponding extension is missing" + . ($hint ? ", did you mean '$hint'?" : '.') + ); } } diff --git a/src/DI/CompilerExtension.php b/src/DI/CompilerExtension.php index f2ad3481f..8f50457e4 100644 --- a/src/DI/CompilerExtension.php +++ b/src/DI/CompilerExtension.php @@ -65,8 +65,9 @@ public function validateConfig(array $expected, array $config = NULL, $name = NU } if ($extra = array_diff_key((array) $config, $expected)) { $name = $name ?: $this->name; - $extra = implode(", $name.", array_keys($extra)); - throw new Nette\InvalidStateException("Unknown configuration option $name.$extra."); + $hint = Nette\Utils\ObjectMixin::getSuggestion(array_keys($expected), key($extra)); + $extra = $hint ? key($extra) : implode(", $name.", array_keys($extra)); + throw new Nette\InvalidStateException("Unknown configuration option $name.$extra" . ($hint ? ", did you mean $name.$hint?" : '.')); } return Config\Helpers::merge($config, $expected); } diff --git a/tests/DI/CompilerExtension.validateConfig.phpt b/tests/DI/CompilerExtension.validateConfig.phpt index 7d1779140..3f57dd6ee 100644 --- a/tests/DI/CompilerExtension.validateConfig.phpt +++ b/tests/DI/CompilerExtension.validateConfig.phpt @@ -47,15 +47,15 @@ test(function () { Assert::exception(function () { $ext = new MyExtension; $ext->validateConfig(['a' => 1, 'b' => 1], ['c' => 1]); -}, Nette\InvalidStateException::class, 'Unknown configuration option my.c.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, did you mean my.a?'); Assert::exception(function () { $ext = new MyExtension; $ext->validateConfig(['a' => 1, 'b' => 1], ['c' => 1, 'd' => 1], 'name'); -}, Nette\InvalidStateException::class, 'Unknown configuration option name.c, name.d.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option name.c, did you mean name.a?'); Assert::exception(function () { $ext = new MyExtension; $ext->setConfig(['c' => 1, 'd' => 1]); $ext->validateConfig(['a' => 1, 'b' => 1]); -}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, my.d.'); +}, Nette\InvalidStateException::class, 'Unknown configuration option my.c, did you mean my.a?');