Skip to content

Commit

Permalink
Presenter: added support for typehint 'iterable' [Closes #203]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Nov 5, 2018
1 parent 9992c9e commit 0583553
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/Application/UI/ComponentReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, array $a
$res[$i] = $param->getDefaultValue();
} elseif ($type === 'NULL' || $param->allowsNull()) {
$res[$i] = null;
} elseif ($type === 'array') {
} elseif ($type === 'array' || $type === 'iterable') {
$res[$i] = [];
} else {
throw new Nette\InvalidArgumentException(sprintf(
Expand Down Expand Up @@ -198,7 +198,7 @@ public static function convertType(&$val, string $type, bool $isClass = false):
} elseif ($type === 'NULL') { // means 'not array'
return !is_array($val);

} elseif ($type === 'array') {
} elseif ($type === 'array' || $type === 'iterable') {
return is_array($val);

} elseif (!is_scalar($val)) { // array, resource, null, etc.
Expand Down
2 changes: 1 addition & 1 deletion src/Application/UI/Presenter.php
Original file line number Diff line number Diff line change
Expand Up @@ -959,7 +959,7 @@ public static function argsToParams(string $class, string $method, array &$args,
}

if (!isset($args[$name])) {
if (!$param->isDefaultValueAvailable() && !$param->allowsNull() && $type !== 'NULL' && $type !== 'array') {
if (!$param->isDefaultValueAvailable() && !$param->allowsNull() && $type !== 'NULL' && $type !== 'array' && $type !== 'iterable') {
$missing[] = $param;
unset($args[$name]);
}
Expand Down
36 changes: 18 additions & 18 deletions tests/UI/ComponentReflection.combineArgs.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ class MyPresenter
}


public function hints(int $int, bool $bool, string $str, array $arr)
public function hints(int $int, bool $bool, string $str, array $arr, iterable $iter)
{
}


public function hintsNulls(int $int = null, bool $bool = null, string $str = null, array $arr = null)
public function hintsNulls(int $int = null, bool $bool = null, string $str = null, array $arr = null, iterable $iter = null)
{
}


public function hintsNullable(?int $int, ?bool $bool, ?string $str, ?array $arr)
public function hintsNullable(?int $int, ?bool $bool, ?string $str, ?array $arr, ?iterable $iter)
{
}


public function hintsDefaults(int $int = 0, bool $bool = false, string $str = '', array $arr = [])
public function hintsDefaults(int $int = 0, bool $bool = false, string $str = '', array $arr = [], iterable $iter = [])
{
}

Expand Down Expand Up @@ -68,8 +68,8 @@ test(function () {
test(function () {
$method = new ReflectionMethod('MyPresenter', 'hints');

Assert::same([1, true, 'abc', [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1]]));
Assert::same([0, false, '', []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => ''])); // missing 'arr'
Assert::same([1, true, 'abc', [1], [2]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1], 'iter' => [2]]));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => ''])); // missing 'arr', 'iter'

Assert::exception(function () use ($method) {
Reflection::combineArgs($method, []);
Expand Down Expand Up @@ -104,10 +104,10 @@ test(function () {
test(function () {
$method = new ReflectionMethod('MyPresenter', 'hintsNulls');

Assert::same([null, null, null, null], Reflection::combineArgs($method, []));
Assert::same([null, null, null, null], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null]));
Assert::same([1, true, 'abc', [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1]]));
Assert::same([0, false, '', []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => []]));
Assert::same([null, null, null, null, null], Reflection::combineArgs($method, []));
Assert::same([null, null, null, null, null], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null, 'iter' => null]));
Assert::same([1, true, 'abc', [1], [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1], 'iter' => [1]]));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => [], 'iter' => []]));

Assert::exception(function () use ($method) {
Reflection::combineArgs($method, ['int' => '']);
Expand All @@ -134,10 +134,10 @@ test(function () {
test(function () {
$method = new ReflectionMethod('MyPresenter', 'hintsNullable');

Assert::same([null, null, null, null], Reflection::combineArgs($method, []));
Assert::same([null, null, null, null], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null]));
Assert::same([1, true, 'abc', [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1]]));
Assert::same([0, false, '', []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => []]));
Assert::same([null, null, null, null, null], Reflection::combineArgs($method, []));
Assert::same([null, null, null, null, null], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null, 'iter' => null]));
Assert::same([1, true, 'abc', [1], [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1], 'iter' => [1]]));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => [], 'iter' => []]));

Assert::exception(function () use ($method) {
Reflection::combineArgs($method, ['int' => '']);
Expand All @@ -164,10 +164,10 @@ test(function () {
test(function () {
$method = new ReflectionMethod('MyPresenter', 'hintsDefaults');

Assert::same([0, false, '', []], Reflection::combineArgs($method, []));
Assert::same([0, false, '', []], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null]));
Assert::same([1, true, 'abc', [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1]]));
Assert::same([0, false, '', []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => []]));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, []));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, ['int' => null, 'bool' => null, 'str' => null, 'arr' => null, 'iter' => null]));
Assert::same([1, true, 'abc', [1], [1]], Reflection::combineArgs($method, ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1], 'iter' => [1]]));
Assert::same([0, false, '', [], []], Reflection::combineArgs($method, ['int' => 0, 'bool' => false, 'str' => '', 'arr' => [], 'iter' => []]));

Assert::exception(function () use ($method) {
Reflection::combineArgs($method, ['int' => '']);
Expand Down
16 changes: 16 additions & 0 deletions tests/UI/ComponentReflection.convertType.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ testIt('array', 1);
testIt('array', 1.0);
testIt('array', 1.2);

testIt('iterable', null);
testIt('iterable', [], []);
testIt('iterable', $obj);
testIt('iterable', '');
testIt('iterable', 'a');
testIt('iterable', '1');
testIt('iterable', '1.0');
testIt('iterable', '1.1');
testIt('iterable', '1a');
testIt('iterable', true);
testIt('iterable', false);
testIt('iterable', 0);
testIt('iterable', 1);
testIt('iterable', 1.0);
testIt('iterable', 1.2);

testIt('callable', null);
testIt('callable', []);
testIt('callable', $obj);
Expand Down

0 comments on commit 0583553

Please sign in to comment.