From f3757c0d7d3609c07753275579b6a0b96244bc50 Mon Sep 17 00:00:00 2001 From: Thomas Gerbet Date: Tue, 1 Dec 2020 19:46:16 +0100 Subject: [PATCH] Fix crash on a union type including null This change prevents the generation of type hints with 2 "null". For example, "string|array|null" should generate the code "string|array|null" instead of "string|array|null|null" to avoid a PHP fatal error "Duplicate type null is redundant". Closes #1105. --- library/Mockery/Reflector.php | 8 +++++--- tests/PHP80/Php80LanguageFeaturesTest.php | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/library/Mockery/Reflector.php b/library/Mockery/Reflector.php index 524d20cd2..bb145de93 100644 --- a/library/Mockery/Reflector.php +++ b/library/Mockery/Reflector.php @@ -192,9 +192,11 @@ private static function typeToString(\ReflectionType $type, \ReflectionClass $de { // PHP 8 union types can be recursively processed if ($type instanceof \ReflectionUnionType) { - return \implode('|', \array_map(function (\ReflectionType $type) use ($declaringClass) { - return self::typeToString($type, $declaringClass); - }, $type->getTypes())); + return \implode('|', \array_filter(\array_map(function (\ReflectionType $type) use ($declaringClass) { + $typeHint = self::typeToString($type, $declaringClass); + + return $typeHint === 'null' ? null : $typeHint; + }, $type->getTypes()))); } // PHP 7.0 doesn't have named types, but 7.1+ does diff --git a/tests/PHP80/Php80LanguageFeaturesTest.php b/tests/PHP80/Php80LanguageFeaturesTest.php index fbecee555..11ffa232e 100644 --- a/tests/PHP80/Php80LanguageFeaturesTest.php +++ b/tests/PHP80/Php80LanguageFeaturesTest.php @@ -29,6 +29,15 @@ public function it_can_mock_a_class_with_a_union_argument_type_hint() $mock->foo($object); } + /** @test */ + public function it_can_mock_a_class_with_a_union_argument_type_hint_including_null() + { + $mock = mock(ArgumentUnionTypeHintWithNull::class); + $mock->allows()->foo(null); + + $mock->foo(null); + } + /** @test */ public function it_can_mock_a_class_with_a_parent_argument_type_hint() { @@ -78,6 +87,13 @@ public function foo(string|array|self $foo) } } +class ArgumentUnionTypeHintWithNull +{ + public function foo(string|array|null $foo) + { + } +} + class ArgumentParentTypeHint extends \stdClass { public function foo(parent $foo)