From f8129a654ca22e935b475fa46857cc42c5666b41 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 31 Jul 2024 07:59:50 +0200 Subject: [PATCH 1/3] Ignore code from code coverage for handling of errors for edge cases that I do not know how to test --- src/Framework/MockObject/Runtime/ReturnValueGenerator.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Framework/MockObject/Runtime/ReturnValueGenerator.php b/src/Framework/MockObject/Runtime/ReturnValueGenerator.php index 38541908799..7cf1cd6a00a 100644 --- a/src/Framework/MockObject/Runtime/ReturnValueGenerator.php +++ b/src/Framework/MockObject/Runtime/ReturnValueGenerator.php @@ -184,6 +184,7 @@ private function newInstanceOf(string $stubClassName, string $className, string { try { return (new ReflectionClass($stubClassName))->newInstanceWithoutConstructor(); + // @codeCoverageIgnoreStart } catch (Throwable $t) { throw new RuntimeException( sprintf( @@ -193,6 +194,7 @@ private function newInstanceOf(string $stubClassName, string $className, string $t->getMessage(), ), ); + // @codeCoverageIgnoreEnd } } @@ -207,6 +209,7 @@ private function testDoubleFor(string $type, string $className, string $methodNa { try { return (new Generator)->testDouble($type, false, [], [], '', false); + // @codeCoverageIgnoreStart } catch (Throwable $t) { throw new RuntimeException( sprintf( @@ -216,6 +219,7 @@ private function testDoubleFor(string $type, string $className, string $methodNa $t->getMessage(), ), ); + // @codeCoverageIgnoreEnd } } @@ -230,6 +234,7 @@ private function testDoubleForIntersectionOfInterfaces(array $types, string $cla { try { return (new Generator)->testDoubleForInterfaceIntersection($types, false); + // @codeCoverageIgnoreStart } catch (Throwable $t) { throw new RuntimeException( sprintf( @@ -239,6 +244,7 @@ private function testDoubleForIntersectionOfInterfaces(array $types, string $cla $t->getMessage(), ), ); + // @codeCoverageIgnoreEnd } } } From fa0e4f6bac968b7c95593e166e1f2bb68f6797c7 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 31 Jul 2024 07:59:56 +0200 Subject: [PATCH 2/3] Add tests --- .../MockObject/ReturnValueGeneratorTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php b/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php index 2545affceb5..6529d5854a0 100644 --- a/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php +++ b/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php @@ -22,6 +22,7 @@ use PHPUnit\TestFixture\MockObject\AnInterfaceForIssue5593; use PHPUnit\TestFixture\MockObject\AnotherInterface; use PHPUnit\TestFixture\MockObject\AnotherInterfaceForIssue5593; +use PHPUnit\TestFixture\MockObject\ExtendableClass; use PHPUnit\TestFixture\MockObject\YetAnotherInterface; use stdClass; @@ -201,6 +202,22 @@ public function test_Generates_test_stub_for_first_intersection_of_interfaces_fo $this->assertInstanceOf(AnotherInterface::class, $value); } + public function test_Does_not_handle_union_of_extendable_class_and_interface(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Return value for OriginalClassName::methodName() cannot be generated because the declared return type is a union, please configure a return value for this method'); + + $this->generate(ExtendableClass::class . '|' . AnInterface::class); + } + + public function test_Does_not_handle_intersection_of_extendable_class_and_interface(): void + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Return value for OriginalClassName::methodName() cannot be generated because the declared return type is an intersection, please configure a return value for this method'); + + $this->generate(ExtendableClass::class . '&' . AnInterface::class); + } + public function test_Generates_test_stub_for_unknown_type(): void { $this->assertInstanceOf(Stub::class, $this->generate('ThisDoesNotExist')); From c23fadf309e736fcb1dd46ca63830205f8a6e0f2 Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Wed, 31 Jul 2024 08:05:08 +0200 Subject: [PATCH 3/3] Also cover the 'yield from [];' statement --- .../MockObject/ReturnValueGeneratorTest.php | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php b/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php index 6529d5854a0..c65c1a0af53 100644 --- a/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php +++ b/tests/unit/Framework/MockObject/ReturnValueGeneratorTest.php @@ -120,17 +120,35 @@ public function test_Generates_callable_for_Closure(): void public function test_Generates_Generator_for_Generator(): void { - $this->assertInstanceOf(Generator::class, $this->generate('Generator')); + $value = $this->generate('Generator'); + + $this->assertInstanceOf(Generator::class, $value); + + foreach ($value as $element) { + $this->assertSame([], $element); + } } public function test_Generates_Generator_for_Traversable(): void { - $this->assertInstanceOf(Generator::class, $this->generate('Traversable')); + $value = $this->generate('Traversable'); + + $this->assertInstanceOf(Generator::class, $value); + + foreach ($value as $element) { + $this->assertSame([], $element); + } } public function test_Generates_Generator_for_iterable(): void { - $this->assertInstanceOf(Generator::class, $this->generate('iterable')); + $value = $this->generate('iterable'); + + $this->assertInstanceOf(Generator::class, $value); + + foreach ($value as $element) { + $this->assertSame([], $element); + } } public function test_Generates_test_stub_for_class_or_interface_name(): void