Skip to content

Commit

Permalink
Reflection::getParameterDefaultValue() fixed constants parsing in nam…
Browse files Browse the repository at this point in the history
…espaced scope (#129)
  • Loading branch information
xificurk authored and dg committed Jan 13, 2017
1 parent d552403 commit f2cc01d
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 45 deletions.
9 changes: 6 additions & 3 deletions src/Utils/Reflection.php
Expand Up @@ -75,14 +75,17 @@ public static function getParameterType(\ReflectionParameter $param)
public static function getParameterDefaultValue(\ReflectionParameter $param)
{
if ($param->isDefaultValueConstant()) {
$const = $param->getDefaultValueConstantName();
$const = $orig = $param->getDefaultValueConstantName();
$pair = explode('::', $const);
if (isset($pair[1]) && strtolower($pair[0]) === 'self') {
$const = $param->getDeclaringClass()->getName() . '::' . $pair[1];
}
if (!defined($const)) {
$name = self::toString($param);
throw new \ReflectionException("Unable to resolve constant $const used as default value of $name.");
$const = substr((string) strrchr($const, '\\'), 1);
if (isset($pair[1]) || !defined($const)) {
$name = self::toString($param);
throw new \ReflectionException("Unable to resolve constant $orig used as default value of $name.");
}
}
return constant($const);
}
Expand Down
93 changes: 51 additions & 42 deletions tests/Utils/Reflection.getParameterDefaultValue.phpt
Expand Up @@ -4,60 +4,69 @@
* Test: Nette\Utils\Reflection::getParameterDefaultValue()
*/

use Nette\Utils\Reflection;
use Tester\Assert;
namespace NS {
define('DEFINED', 123);
define('NS_DEFINED', 'xxx');
const NS_DEFINED = 456;

require __DIR__ . '/../bootstrap.php';


define('DEFINED', 123);

interface Bar
{
const DEFINED = 'xyz';
}
interface Bar
{
const DEFINED = 'xyz';
}

class Foo
{
const DEFINED = 'abc';

function method(
$a,
$b = self::DEFINED,
$c = Foo::DEFINED,
$d = SELF::DEFINED,
$e = bar::DEFINED,
$f = self::UNDEFINED,
$g = Undefined::ANY,
$h = DEFINED,
$i = UNDEFINED)
class Foo
{
const DEFINED = 'abc';

function method(
$a,
$b = self::DEFINED,
$c = Foo::DEFINED,
$d = SELF::DEFINED,
$e = bar::DEFINED,
$f = self::UNDEFINED,
$g = Undefined::ANY,
$h = DEFINED,
$i = UNDEFINED,
$j = NS_DEFINED
) {
}
}
}


Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'a'));
}, ReflectionException::class);
namespace {
use Nette\Utils\Reflection;
use Tester\Assert;

Assert::same(Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'b')));
require __DIR__ . '/../bootstrap.php';

Assert::same(Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'c')));

Assert::same(Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'd')));
Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'a'));
}, ReflectionException::class);

Assert::same(Bar::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'e')));
Assert::same(NS\Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'b')));

Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'f'));
}, ReflectionException::class, 'Unable to resolve constant Foo::UNDEFINED used as default value of $f in Foo::method().');
Assert::same(NS\Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'c')));

Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'g'));
}, ReflectionException::class, 'Unable to resolve constant Undefined::ANY used as default value of $g in Foo::method().');
Assert::same(NS\Foo::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'd')));

Assert::same(DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'h')));
Assert::same(NS\Bar::DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'e')));

Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['Foo', 'method'], 'i'));
}, ReflectionException::class, 'Unable to resolve constant UNDEFINED used as default value of $i in Foo::method().');
Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'f'));
}, ReflectionException::class, 'Unable to resolve constant self::UNDEFINED used as default value of $f in NS\Foo::method().');

Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'g'));
}, ReflectionException::class, 'Unable to resolve constant NS\Undefined::ANY used as default value of $g in NS\Foo::method().');

Assert::same(DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'h')));

Assert::exception(function () {
Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'i'));
}, ReflectionException::class, 'Unable to resolve constant NS\UNDEFINED used as default value of $i in NS\Foo::method().');

Assert::same(NS\NS_DEFINED, Reflection::getParameterDefaultValue(new ReflectionParameter(['NS\Foo', 'method'], 'j')));
}

0 comments on commit f2cc01d

Please sign in to comment.