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

Commit

Permalink
Merge pull request #106 from jmalloc/feature/php7-scalar-hints
Browse files Browse the repository at this point in the history
Add support for PHP 7 scalar type hints. Relates to #94.
  • Loading branch information
ezzatron committed Dec 14, 2015
2 parents d38d371 + 8762dea commit 8f2d97e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 11 deletions.
30 changes: 19 additions & 11 deletions src/Reflection/FunctionSignatureInspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public function __construct(
->isSupported('reflection.function.export.reference');
$this->isVariadicParameterSupported = $featureDetector
->isSupported('parameter.variadic');
$this->isScalarTypeHintSupported = $featureDetector
->isSupported('parameter.hint.scalar');
$this->isHhvm = $featureDetector->isSupported('runtime.hhvm');
}

Expand Down Expand Up @@ -123,18 +125,23 @@ public function signature(ReflectionFunctionAbstract $function)
}
} // @codeCoverageIgnoreEnd

switch ($typehint) {
case '':
case 'array ':
case 'callable ':
break;

case 'self ':
$typehint = $parameter->getDeclaringClass()->getName() .
' ';

default:
if ('self ' === $typehint) {
$typehint = '\\' . $parameter->getDeclaringClass()->getName()
. ' ';
} elseif (
'' !== $typehint &&
'array ' !== $typehint &&
'callable ' !== $typehint
) {
if (!$this->isScalarTypeHintSupported) {
$typehint = '\\' . $typehint;
} elseif ('integer ' === $typehint && $parameter->getType()->isBuiltin()) {
$typehint = 'int ';
} elseif ('boolean ' === $typehint && $parameter->getType()->isBuiltin()) {
$typehint = 'bool ';
} elseif ('float ' !== $typehint && 'string ' !== $typehint) {
$typehint = '\\' . $typehint;
}
}

if ($this->isExportReferenceSupported) {
Expand Down Expand Up @@ -204,5 +211,6 @@ public function callbackSignature($callback)
private $featureDetector;
private $isExportDefaultArraySupported;
private $isExportReferenceSupported;
private $isScalarTypeHintSupported;
private $isHhvm;
}
7 changes: 7 additions & 0 deletions test/fixture/mock-generator/scalar-type-hint/builder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

return new Eloquent\Phony\Mock\Builder\MockBuilder(
'Eloquent\Phony\Test\TestInterfaceWithScalarTypeHint',
array('customMethod' => function (int $int) {}),
'MockGeneratorScalarTypeHint'
);
64 changes: 64 additions & 0 deletions test/fixture/mock-generator/scalar-type-hint/expected.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

class MockGeneratorScalarTypeHint
implements \Eloquent\Phony\Mock\MockInterface,
\Eloquent\Phony\Test\TestInterfaceWithScalarTypeHint
{
public function method(
int $a0,
float $a1,
string $a2,
bool $a3
) {
$argumentCount = \func_num_args();
$arguments = array();

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

for ($i = 4; $i < $argumentCount; ++$i) {
$arguments[] = \func_get_arg($i);
}

return $this->_proxy->spy(__FUNCTION__)->invokeWith(
new \Eloquent\Phony\Call\Argument\Arguments($arguments)
);
}

public function customMethod(
int $a0
) {
$argumentCount = \func_num_args();
$arguments = array();

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

for ($i = 1; $i < $argumentCount; ++$i) {
$arguments[] = \func_get_arg($i);
}

return $this->_proxy->spy(__FUNCTION__)->invokeWith(
new \Eloquent\Phony\Call\Argument\Arguments($arguments)
);
}

private static $_uncallableMethods = array(
'method' => true,
);
private static $_traitMethods = array();
private static $_customMethods = array();
private static $_staticProxy;
private $_proxy;
}
5 changes: 5 additions & 0 deletions test/fixture/mock-generator/scalar-type-hint/supported.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

$message = 'Requires scalar type hints.';

return $detector->isSupported('parameter.hint.scalar');
22 changes: 22 additions & 0 deletions test/src/Test/TestInterfaceWithScalarTypeHint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Phony package.
*
* Copyright © 2015 Erin Millard
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Eloquent\Phony\Test;

interface TestInterfaceWithScalarTypeHint
{
public function method(
int $a,
float $b,
string $c,
bool $d
);
}
12 changes: 12 additions & 0 deletions test/suite/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,18 @@ public function testVariadicParameterMockingByReference()
$this->assertSame('b', $b);
}

public function testScalarTypeHintMocking()
{
if (!$this->featureDetector->isSupported('parameter.hint.scalar')) {
$this->markTestSkipped('Requires scalar type hints.');
}

$proxy = x\mock('Eloquent\Phony\Test\TestInterfaceWithScalarTypeHint');

$proxy->mock()->method(123, 1.23, '<string>', true);
$proxy->method->calledWith(123, 1.23, '<string>', true);
}

public function testClassReturnTypeMocking()
{
if (!$this->featureDetector->isSupported('return.type')) {
Expand Down

0 comments on commit 8f2d97e

Please sign in to comment.