Skip to content

Commit

Permalink
Merge pull request #1374 from Roave/reflection-stubber
Browse files Browse the repository at this point in the history
ReflectionSourceStubber supports types class constants
  • Loading branch information
kukulich authored Nov 13, 2023
2 parents c694c10 + a8d9124 commit 919a204
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ jobs:
dependencies:
- "locked"
php-version:
- "8.2"
- "8.3"
operating-system:
- "ubuntu-latest"

Expand Down
9 changes: 9 additions & 0 deletions src/SourceLocator/SourceStubber/ReflectionSourceStubber.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down
10 changes: 10 additions & 0 deletions test/unit/Fixture/PHP83ClassForSourceStubber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Roave\BetterReflectionTest\Fixture;

class PHP83ClassForSourceStubber
{
public final const string STRING_CONST = 'string';

public final const int INTEGER_CONST = 0;
}
9 changes: 9 additions & 0 deletions test/unit/Fixture/PHP83ClassForSourceStubberExpected.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Roave\BetterReflectionTest\Fixture;

class PHP83ClassForSourceStubber
{
public final const string STRING_CONST = 'string';
public final const int INTEGER_CONST = 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use ClassWithoutNamespaceForSourceStubber;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\TestCase;
use ReflectionClass as CoreReflectionClass;
use ReflectionException;
Expand All @@ -31,6 +32,7 @@
use Roave\BetterReflectionTest\Fixture\EnumPureForSourceStubber;
use Roave\BetterReflectionTest\Fixture\InterfaceForSourceStubber;
use Roave\BetterReflectionTest\Fixture\PHP81ClassForSourceStubber;
use Roave\BetterReflectionTest\Fixture\PHP83ClassForSourceStubber;
use Roave\BetterReflectionTest\Fixture\PHP8ClassForSourceStubber;
use Roave\BetterReflectionTest\Fixture\TraitForSourceStubber;
use stdClass;
Expand Down Expand Up @@ -171,6 +173,17 @@ public function testClassStubWithPHP81Syntax(): void
self::assertNull($stubData->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';
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 919a204

Please sign in to comment.