diff -up ./src/Framework/MockObject/Builder/Match.php.php8 ./src/Framework/MockObject/Builder/Match.php --- ./src/Framework/MockObject/Builder/Match.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./src/Framework/MockObject/Builder/Match.php 2021-03-26 14:22:46.505856216 +0100 @@ -12,7 +12,7 @@ namespace PHPUnit\Framework\MockObject\B /** * Builder interface for invocation order matches. */ -interface Match extends Stub +interface Match_ extends Stub { /** * Defines the expectation which must occur before the current is valid. diff -up ./src/Framework/MockObject/Builder/NamespaceMatch.php.php8 ./src/Framework/MockObject/Builder/NamespaceMatch.php --- ./src/Framework/MockObject/Builder/NamespaceMatch.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./src/Framework/MockObject/Builder/NamespaceMatch.php 2021-03-26 14:22:46.505856216 +0100 @@ -33,5 +33,5 @@ interface NamespaceMatch * @param string $id The identification of the match builder * @param Match $builder The builder which is being registered */ - public function registerId($id, Match $builder); + public function registerId($id, Match_ $builder); } diff -up ./src/Framework/MockObject/Builder/ParametersMatch.php.php8 ./src/Framework/MockObject/Builder/ParametersMatch.php --- ./src/Framework/MockObject/Builder/ParametersMatch.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./src/Framework/MockObject/Builder/ParametersMatch.php 2021-03-26 14:22:46.505856216 +0100 @@ -14,7 +14,7 @@ use PHPUnit\Framework\MockObject\Matcher /** * Builder interface for parameter matchers. */ -interface ParametersMatch extends Match +interface ParametersMatch extends Match_ { /** * Sets the parameters to match for, each parameter to this function will diff -up ./src/Framework/MockObject/InvocationMocker.php.php8 ./src/Framework/MockObject/InvocationMocker.php --- ./src/Framework/MockObject/InvocationMocker.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./src/Framework/MockObject/InvocationMocker.php 2021-03-26 14:22:46.505856216 +0100 @@ -12,7 +12,7 @@ namespace PHPUnit\Framework\MockObject; use Exception; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker; -use PHPUnit\Framework\MockObject\Builder\Match; +use PHPUnit\Framework\MockObject\Builder\Match_; use PHPUnit\Framework\MockObject\Builder\NamespaceMatch; use PHPUnit\Framework\MockObject\Matcher\DeferredError; use PHPUnit\Framework\MockObject\Matcher\Invocation as MatcherInvocation; @@ -82,7 +82,7 @@ class InvocationMocker implements Invoka /** * @throws RuntimeException */ - public function registerId($id, Match $builder): void + public function registerId($id, Match_ $builder): void { if (isset($this->builderMap[$id])) { throw new RuntimeException( diff -up ./src/Framework/MockObject/MockMethod.php.php8 ./src/Framework/MockObject/MockMethod.php --- ./src/Framework/MockObject/MockMethod.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./src/Framework/MockObject/MockMethod.php 2021-03-26 14:23:49.737575694 +0100 @@ -12,6 +12,7 @@ namespace PHPUnit\Framework\MockObject; use ReflectionClass; use ReflectionException; use ReflectionMethod; +use ReflectionNamedType; use Text_Template; final class MockMethod @@ -269,7 +270,7 @@ final class MockMethod * * @throws RuntimeException */ - private static function getMethodParameters(ReflectionMethod $method, bool $forCall = false): string + private static function getMethodParametersForDeclaration(ReflectionMethod $method): string { $parameters = []; @@ -283,63 +284,38 @@ final class MockMethod $name = '$arg' . $i; } - if ($parameter->isVariadic()) { - if ($forCall) { - continue; - } - - $name = '...' . $name; - } - $nullable = ''; $default = ''; $reference = ''; $typeDeclaration = ''; + $type = null; + $typeName = null; - if (!$forCall) { - if ($parameter->hasType() && $parameter->allowsNull()) { - $nullable = '?'; + if ($parameter->hasType()) { + $type = $parameter->getType(); + + if ($type instanceof ReflectionNamedType) { + $typeName = $type->getName(); } + } + + if ($parameter->isVariadic()) { + $name = '...' . $name; + } elseif ($parameter->isDefaultValueAvailable()) { + $default = ' = ' . var_export($parameter->getDefaultValue(), true); + } elseif ($parameter->isOptional()) { + $default = ' = null'; + } - if ($parameter->hasType() && $parameter->getType()->getName() !== 'self') { - $typeDeclaration = $parameter->getType()->getName() . ' '; - } else { - try { - $class = $parameter->getClass(); - } catch (ReflectionException $e) { - throw new RuntimeException( - \sprintf( - 'Cannot mock %s::%s() because a class or ' . - 'interface used in the signature is not loaded', - $method->getDeclaringClass()->getName(), - $method->getName() - ), - 0, - $e - ); - } - - if ($class !== null) { - $typeDeclaration = $class->getName() . ' '; - } + if ($type !== null) { + if ($typeName !== 'mixed' && $parameter->allowsNull()) { + $nullable = '?'; } - if (!$parameter->isVariadic()) { - if ($parameter->isDefaultValueAvailable()) { - try { - $value = \var_export($parameter->getDefaultValue(), true); - } catch (\ReflectionException $e) { - throw new RuntimeException( - $e->getMessage(), - (int) $e->getCode(), - $e - ); - } - - $default = ' = ' . $value; - } elseif ($parameter->isOptional()) { - $default = ' = null'; - } + if ($typeName === 'self') { + $typeDeclaration = $method->getDeclaringClass()->getName() . ' '; + } elseif ($typeName !== null) { + $typeDeclaration = $typeName . ' '; } } @@ -350,6 +326,53 @@ final class MockMethod $parameters[] = $nullable . $typeDeclaration . $reference . $name . $default; } - return \implode(', ', $parameters); + return implode(', ', $parameters); + } + + /** + * Returns the parameters of a function or method. + * + * @throws ReflectionException + */ + private static function getMethodParametersForCall(ReflectionMethod $method): string + { + $parameters = []; + + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + + /* Note: PHP extensions may use empty names for reference arguments + * or "..." for methods taking a variable number of arguments. + */ + if ($name === '$' || $name === '$...') { + $name = '$arg' . $i; + } + + if ($parameter->isVariadic()) { + continue; + } + + if ($parameter->isPassedByReference()) { + $parameters[] = '&' . $name; + } else { + $parameters[] = $name; + } + } + + return implode(', ', $parameters); + } + + + /** + * Returns the parameters of a function or method. + * + * @throws RuntimeException + */ + private static function getMethodParameters(ReflectionMethod $method, bool $forCall = false): string + { + if ($forCall) { + return self::getMethodParametersForCall($method); + } + return self::getMethodParametersForDeclaration($method); } } diff -up ./tests/_files/SingletonClass.php.php8 ./tests/_files/SingletonClass.php --- ./tests/_files/SingletonClass.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./tests/_files/SingletonClass.php 2021-03-26 14:22:46.505856216 +0100 @@ -17,11 +17,11 @@ class SingletonClass { } - private function __sleep() + function __sleep() { } - private function __wakeup() + function __wakeup() { } diff -up ./tests/unit/Framework/Constraint/IsTypeTest.php.php8 ./tests/unit/Framework/Constraint/IsTypeTest.php --- ./tests/unit/Framework/Constraint/IsTypeTest.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./tests/unit/Framework/Constraint/IsTypeTest.php 2021-03-26 14:22:46.505856216 +0100 @@ -74,7 +74,7 @@ EOF $this->assertTrue($constraint->evaluate($resource, '', true)); - @\fclose($resource); + if (is_resource($resource)) @\fclose($resource); } public function resources() diff -up ./tests/unit/Framework/Constraint/JsonMatchesErrorMessageProviderTest.php.php8 ./tests/unit/Framework/Constraint/JsonMatchesErrorMessageProviderTest.php --- ./tests/unit/Framework/Constraint/JsonMatchesErrorMessageProviderTest.php.php8 2020-01-08 09:45:45.000000000 +0100 +++ ./tests/unit/Framework/Constraint/JsonMatchesErrorMessageProviderTest.php 2021-03-26 14:22:46.505856216 +0100 @@ -17,7 +17,7 @@ class JsonMatchesErrorMessageProviderTes { return [ 'JSON_ERROR_NONE' => [ - null, 'json_error_none', '', + null, \JSON_ERROR_NONE, '', ], 'JSON_ERROR_DEPTH' => [ 'Maximum stack depth exceeded', \JSON_ERROR_DEPTH, '',