diff --git a/src/Reflection/FunctionSignatureInspector.php b/src/Reflection/FunctionSignatureInspector.php index eb9ddea06..fdbe7b8d6 100644 --- a/src/Reflection/FunctionSignatureInspector.php +++ b/src/Reflection/FunctionSignatureInspector.php @@ -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'); } @@ -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) { @@ -204,5 +211,6 @@ public function callbackSignature($callback) private $featureDetector; private $isExportDefaultArraySupported; private $isExportReferenceSupported; + private $isScalarTypeHintSupported; private $isHhvm; } diff --git a/test/fixture/mock-generator/scalar-type-hint/builder.php b/test/fixture/mock-generator/scalar-type-hint/builder.php new file mode 100644 index 000000000..a1a22b4f4 --- /dev/null +++ b/test/fixture/mock-generator/scalar-type-hint/builder.php @@ -0,0 +1,7 @@ + function (int $int) {}), + 'MockGeneratorScalarTypeHint' +); diff --git a/test/fixture/mock-generator/scalar-type-hint/expected.php b/test/fixture/mock-generator/scalar-type-hint/expected.php new file mode 100644 index 000000000..aa9151dd9 --- /dev/null +++ b/test/fixture/mock-generator/scalar-type-hint/expected.php @@ -0,0 +1,64 @@ + 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; +} diff --git a/test/fixture/mock-generator/scalar-type-hint/supported.php b/test/fixture/mock-generator/scalar-type-hint/supported.php new file mode 100644 index 000000000..b9cd358d0 --- /dev/null +++ b/test/fixture/mock-generator/scalar-type-hint/supported.php @@ -0,0 +1,5 @@ +isSupported('parameter.hint.scalar'); diff --git a/test/src/Test/TestInterfaceWithScalarTypeHint.php b/test/src/Test/TestInterfaceWithScalarTypeHint.php new file mode 100644 index 000000000..172f8bf4e --- /dev/null +++ b/test/src/Test/TestInterfaceWithScalarTypeHint.php @@ -0,0 +1,22 @@ +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, '', true); + $proxy->method->calledWith(123, 1.23, '', true); + } + public function testClassReturnTypeMocking() { if (!$this->featureDetector->isSupported('return.type')) {