From e14ee99b2b55837a099700e710fd3c5da83bc5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Fri, 10 Nov 2023 21:20:44 +0100 Subject: [PATCH 1/2] ReflectionSourceStubber supports types class constants --- .../SourceStubber/ReflectionSourceStubber.php | 9 +++++ .../Fixture/PHP83ClassForSourceStubber.php | 10 ++++++ .../PHP83ClassForSourceStubberExpected.php | 9 +++++ .../ReflectionSourceStubberTest.php | 36 +++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 test/unit/Fixture/PHP83ClassForSourceStubber.php create mode 100644 test/unit/Fixture/PHP83ClassForSourceStubberExpected.php diff --git a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php index a6449a98c..72c114dbe 100644 --- a/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php +++ b/src/SourceLocator/SourceStubber/ReflectionSourceStubber.php @@ -412,6 +412,15 @@ private function addClassConstants(Class_|Interface_|Trait_|Enum_ $classNode, Co $classConstantNode = $this->builderFactory->classConst($constantReflection->getName(), $constantReflection->getValue()); + if (method_exists($constantReflection, 'getType')) { + $constantType = $constantReflection->getType(); + + if ($constantType !== null) { + assert($constantType instanceof CoreReflectionNamedType || $constantType instanceof CoreReflectionUnionType || $constantType instanceof CoreReflectionIntersectionType); + $classConstantNode->setType($this->formatType($constantType)); + } + } + if ($constantReflection->getDocComment() !== false) { $classConstantNode->setDocComment(new Doc($constantReflection->getDocComment())); } diff --git a/test/unit/Fixture/PHP83ClassForSourceStubber.php b/test/unit/Fixture/PHP83ClassForSourceStubber.php new file mode 100644 index 000000000..ed53dfbd0 --- /dev/null +++ b/test/unit/Fixture/PHP83ClassForSourceStubber.php @@ -0,0 +1,10 @@ +getExtensionName()); } + #[RequiresPhp('8.3')] + public function testClassStubWithTypedConstants(): void + { + require_once __DIR__ . '/../../Fixture/PHP83ClassForSourceStubber.php'; + + $stubData = $this->stubber->generateClassStub(PHP83ClassForSourceStubber::class); + + self::assertNotNull($stubData); + self::assertStringEqualsFile(__DIR__ . '/../../Fixture/PHP83ClassForSourceStubberExpected.php', $stubData->getStub()); + } + public function testClassWithoutNamespaceStub(): void { require_once __DIR__ . '/../../Fixture/ClassWithoutNamespaceForSourceStubber.php'; @@ -306,10 +319,33 @@ private function assertSameClassAttributes(CoreReflectionClass $original, Reflec $this->assertSameMethodAttributes($method, $stubbed->getMethod($method->getName())); } + $this->assertSameClassConstants($original, $stubbed); + } + + private function assertSameClassConstants(CoreReflectionClass $original, ReflectionClass $stubbed): void + { self::assertEquals( $original->getConstants(), array_map(static fn (ReflectionClassConstant $classConstant) => $classConstant->getValue(), $stubbed->getConstants()), ); + + foreach ($original->getReflectionConstants() as $originalConstant) { + if ( + ! method_exists($originalConstant, 'hasType') + || ! method_exists($originalConstant, 'getType') + ) { + continue; + } + + $stubbedConstant = $stubbed->getConstant($originalConstant->getName()); + + self::assertSame($originalConstant->hasType(), $stubbedConstant->hasType()); + self::assertSame( + (string) $originalConstant->getType(), + (string) ReflectionType::fromTypeOrNull($stubbedConstant->getType()), + $original->getName() . '::' . $originalConstant->getName(), + ); + } } private function assertSameMethodAttributes(CoreReflectionMethod $original, ReflectionMethod $stubbed): void From a8d91248118d0eb38bcd1223fce7f6f51932541d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sat, 11 Nov 2023 08:51:25 +0100 Subject: [PATCH 2/2] Run mutation tests on PHP 8.3 --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index cd4b98a47..26459ce2b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -126,7 +126,7 @@ jobs: dependencies: - "locked" php-version: - - "8.2" + - "8.3" operating-system: - "ubuntu-latest"