Skip to content
This repository has been archived by the owner on Jul 8, 2023. It is now read-only.

Commit

Permalink
Merge branch 'nullable-variadics' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Aug 29, 2020
2 parents 5fd6b64 + c9101a3 commit 2df7604
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 2 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Phony changelog

## 4.0.1 (2020-08-29)

- **[FIXED]** Nullable variadics can now be mocked ([#248] - thanks [@keksa]).

[#248]: https://github.com/eloquent/phony/issues/248

## 4.0.0 (2019-12-31)

- **[BC BREAK]** PHP 7.1 is no longer supported.
Expand Down Expand Up @@ -592,6 +598,8 @@ and version constraint will need to be updated:

- **[NEW]** Initial implementation.

<!-- Contributors -->

[@jmalloc]: https://github.com/jmalloc
[@keksa]: https://github.com/keksa
[@pmall]: https://github.com/pmall
Expand Down
9 changes: 7 additions & 2 deletions src/Reflection/FunctionSignatureInspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,15 @@ public function signature(ReflectionFunctionAbstract $function): array
}

$byReference = $match[4];
$isVariadic = $parameter->isVariadic();

if ($parameter->isVariadic()) {
if ($isVariadic) {
$variadic = '...';
$optional = false;

if ($match[3]) {
$typehint = '?' . $typehint;
}
} else {
$variadic = '';
$optional = 'optional' === $match[1];
Expand All @@ -107,7 +112,7 @@ public function signature(ReflectionFunctionAbstract $function): array
$defaultValue = ' = ' .
var_export($parameter->getDefaultValue(), true);
}
} elseif ($optional || $match[3]) {
} elseif (!$isVariadic && ($optional || $match[3])) {
$defaultValue = ' = null';
} else {
$defaultValue = '';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

$functionName = 'functionName';
$namespace = 'Foo\Bar';
$callback = function ($a, $b, ?stdClass ...$c) {};
42 changes: 42 additions & 0 deletions test/fixture/hook-generator/variadics-nullable-type/expected.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Foo\Bar;

function functionName(
$a0,
$a1,
?\stdClass ...$a2
) {
$argumentCount = \func_num_args();
$arguments = [];

if ($argumentCount > 0) {
$arguments[] = $a0;
}
if ($argumentCount > 1) {
$arguments[] = $a1;
}

for ($i = 2; $i < $argumentCount; ++$i) {
$arguments[] = $a2[$i - 2];
}

$name = 'foo\\bar\\functionname';

if (
!isset(
\Eloquent\Phony\Hook\FunctionHookManager::$hooks[$name]['callback']
)
) {
return \functionName(...$arguments);
}

$callback =
\Eloquent\Phony\Hook\FunctionHookManager::$hooks[$name]['callback'];

if ($callback instanceof \Eloquent\Phony\Invocation\Invocable) {
return $callback->invokeWith($arguments);
}

return $callback(...$arguments);
}
1 change: 1 addition & 0 deletions test/fixture/mock-generator/variadics/builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'methodA' => function ($a, $b, ...$c) {},
'methodB' => function ($a, $b, stdClass ...$c) {},
'methodC' => function ($a, $b, &...$c) {},
'methodD' => function ($a, $b, ?stdClass...$c) {},
]
);

Expand Down
32 changes: 32 additions & 0 deletions test/fixture/mock-generator/variadics/expected.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,38 @@ public function methodC(
return $result;
}

public function methodD(
$a0,
$a1,
?\stdClass ...$a2
) {
$argumentCount = \func_num_args();
$arguments = [];

if ($argumentCount > 0) {
$arguments[] = $a0;
}
if ($argumentCount > 1) {
$arguments[] = $a1;
}

for ($i = 2; $i < $argumentCount; ++$i) {
$arguments[] = $a2[$i - 2];
}

if (!$this->_handle) {
$result = null;

return $result;
}

$result = $this->_handle->spy(__FUNCTION__)->invokeWith(
new \Eloquent\Phony\Call\Arguments($arguments)
);

return $result;
}

private static $_uncallableMethods = [];
private static $_traitMethods = [];
private static $_customMethods = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Eloquent\Phony\Test;

use stdClass;

interface TestInterfaceWithVariadicParameterWithNullableType
{
public function method(?stdClass ...$arguments);
}
16 changes: 16 additions & 0 deletions test/suite/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use Eloquent\Phony\Test\TestInterfaceWithScalarTypeHint;
use Eloquent\Phony\Test\TestInterfaceWithVariadicParameter;
use Eloquent\Phony\Test\TestInterfaceWithVariadicParameterByReference;
use Eloquent\Phony\Test\TestInterfaceWithVariadicParameterWithNullableType;
use Eloquent\Phony\Test\TestInterfaceWithVariadicParameterWithType;
use Eloquent\Phony\Test\TestInvocable;
use Eloquent\Phony\Test\TestTraitA;
Expand Down Expand Up @@ -171,6 +172,21 @@ function () {
$this->assertSame([$a, $b], $handle->get()->method($a, $b));
}

public function testVariadicParameterMockingWithNullableType()
{
$handle = mock(TestInterfaceWithVariadicParameterWithNullableType::class);
$handle->method->does(
function () {
return func_get_args();
}
);
$a = (object) [];
$b = null;
$c = (object) [];

$this->assertSame([$a, $b, $c], $handle->get()->method($a, $b, $c));
}

public function testVariadicParameterMockingByReference()
{
$handle = mock(TestInterfaceWithVariadicParameterByReference::class);
Expand Down

0 comments on commit 2df7604

Please sign in to comment.