From 282df533deeaeccbe4162aefc2ecc82427da5c90 Mon Sep 17 00:00:00 2001 From: SpacePossum Date: Thu, 8 Dec 2016 11:42:53 +0100 Subject: [PATCH] Better type description on PHPDoc, better testing of returned value. --- doc/advanced.rst | 2 +- doc/advanced_legacy.rst | 2 +- lib/Twig/Environment.php | 9 ++- lib/Twig/ExtensionInterface.php | 2 +- test/Twig/Tests/CustomExtensionTest.php | 86 +++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 test/Twig/Tests/CustomExtensionTest.php diff --git a/doc/advanced.rst b/doc/advanced.rst index 313981f3e..8ba3e0104 100644 --- a/doc/advanced.rst +++ b/doc/advanced.rst @@ -596,7 +596,7 @@ An extension is a class that implements the following interface:: /** * Returns a list of operators to add to the existing list. * - * @return array An array of operators + * @return array First array of unary operators, second array of binary operators */ function getOperators(); diff --git a/doc/advanced_legacy.rst b/doc/advanced_legacy.rst index e2be5f564..33e9f45a4 100644 --- a/doc/advanced_legacy.rst +++ b/doc/advanced_legacy.rst @@ -580,7 +580,7 @@ An extension is a class that implements the following interface:: /** * Returns a list of operators to add to the existing list. * - * @return array An array of operators + * @return array First array of unary operators, second array of binary operators */ function getOperators(); diff --git a/lib/Twig/Environment.php b/lib/Twig/Environment.php index 461ba050c..5cb33dd92 100644 --- a/lib/Twig/Environment.php +++ b/lib/Twig/Environment.php @@ -1512,8 +1512,15 @@ class Twig_Environment // operators if ($operators = $extension->getOperators()) { + if (!is_array($operators)) { + throw new InvalidArgumentException(sprintf( + '"%s::getOperators()" must return an array with operators, got "%s".', + get_class($extension), is_object($operators) ? get_class($operators) : gettype($operators).(is_resource($operators) ? '' : '#'.$operators) + )); + } + if (2 !== count($operators)) { - throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); + throw new InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', get_class($extension), count($operators))); } $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); diff --git a/lib/Twig/ExtensionInterface.php b/lib/Twig/ExtensionInterface.php index 980eade06..ebc68061a 100644 --- a/lib/Twig/ExtensionInterface.php +++ b/lib/Twig/ExtensionInterface.php @@ -63,7 +63,7 @@ interface Twig_ExtensionInterface /** * Returns a list of operators to add to the existing list. * - * @return array An array of operators + * @return array First array of unary operators, second array of binary operators */ public function getOperators(); diff --git a/test/Twig/Tests/CustomExtensionTest.php b/test/Twig/Tests/CustomExtensionTest.php new file mode 100644 index 000000000..56d3b2139 --- /dev/null +++ b/test/Twig/Tests/CustomExtensionTest.php @@ -0,0 +1,86 @@ +setExpectedException('InvalidArgumentException', $expectedExceptionMessage); + + $loader = new \Twig_Loader_Array(array('foo' => '{{ foo }}')); + $env = new \Twig_Environment($loader); + $env->addExtension($extension); + + $method = new \ReflectionMethod($env, 'initExtensions'); + $method->setAccessible(true); + $method->invoke($env); + } + + public function provideInvalidExtensions() + { + return array( + array(new InvalidOperatorExtension(new \stdClass()), '"InvalidOperatorExtension::getOperators()" must return an array with operators, got "stdClass".'), + array(new InvalidOperatorExtension(array(1, 2, 3)), '"InvalidOperatorExtension::getOperators()" must return an array of 2 elements, got 3.'), + ); + } +} + +final class InvalidOperatorExtension implements \Twig_ExtensionInterface +{ + private $operators; + + public function __construct($operators) + { + $this->operators = $operators; + } + + public function initRuntime(Twig_Environment $environment) + { + } + + public function getTokenParsers() + { + return array(); + } + + public function getNodeVisitors() + { + return array(); + } + + public function getFilters() + { + return array(); + } + + public function getTests() + { + return array(); + } + + public function getFunctions() + { + return array(); + } + + public function getGlobals() + { + return array(); + } + + public function getOperators() + { + return $this->operators; + } + + public function getName() + { + return __CLASS__; + } +}