diff --git a/test/unit/Fixture/Php71NullableReturnTypeDeclarations.php b/test/unit/Fixture/Php71NullableReturnTypeDeclarations.php deleted file mode 100644 index 2bdb80ca5..000000000 --- a/test/unit/Fixture/Php71NullableReturnTypeDeclarations.php +++ /dev/null @@ -1,13 +0,0 @@ -reflectClass('Bat'); + $this->expectException(UnableToCompileNode::class); $this->expectExceptionMessage('An enum expression Foo::ONE is not supported in class Bat in file '); $classInfo->getConstant('ONE_VALUE')->getValue(); } diff --git a/test/unit/Reflection/Adapter/Exception/NotImplementedBecauseItTriggersAutoloadingTest.php b/test/unit/Reflection/Adapter/Exception/NotImplementedBecauseItTriggersAutoloadingTest.php new file mode 100644 index 000000000..86cc229a0 --- /dev/null +++ b/test/unit/Reflection/Adapter/Exception/NotImplementedBecauseItTriggersAutoloadingTest.php @@ -0,0 +1,21 @@ +getMessage()); + } +} diff --git a/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php b/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php index f779d2633..8a714d0ec 100644 --- a/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php +++ b/test/unit/Reflection/Adapter/ReflectionNamedTypeTest.php @@ -111,20 +111,22 @@ public function testAdapterMethods(string $methodName, string|null $expectedExce } /** @return list */ - public static function dataNotBuildin(): array + public static function dataIsBuildin(): array { return [ - ['self'], - ['sElF'], - ['static'], - ['sTaTiC'], - ['parent'], - ['PaReNt'], + ['string', true], + ['int', true], + ['self', false], + ['sElF', false], + ['static', false], + ['sTaTiC', false], + ['parent', false], + ['PaReNt', false], ]; } - #[DataProvider('dataNotBuildin')] - public function testIsNotBuiltin(string $type): void + #[DataProvider('dataIsBuildin')] + public function testIsBuiltin(string $type, bool $isBuiltin): void { $reflector = $this->createMock(Reflector::class); $owner = $this->createMock(BetterReflectionMethod::class); @@ -132,6 +134,23 @@ public function testIsNotBuiltin(string $type): void $betterReflectionNamedType = new BetterReflectionNamedType($reflector, $owner, new Node\Name($type)); $reflectionTypeAdapter = new ReflectionNamedTypeAdapter($betterReflectionNamedType, false); - self::assertFalse($reflectionTypeAdapter->isBuiltin()); + self::assertSame($isBuiltin, $reflectionTypeAdapter->isBuiltin()); + } + + public function testTypeWithoutBetterReflection(): void + { + $reflectionTypeAdapter = new ReflectionNamedTypeAdapter('never'); + + self::assertSame('never', $reflectionTypeAdapter->getName()); + self::assertSame('never', $reflectionTypeAdapter->__toString()); + self::assertTrue($reflectionTypeAdapter->isBuiltin()); + self::assertFalse($reflectionTypeAdapter->allowsNull()); + } + + public function testDefaultAllowsNull(): void + { + $reflectionTypeAdapter = new ReflectionNamedTypeAdapter('never'); + + self::assertFalse($reflectionTypeAdapter->allowsNull()); } } diff --git a/test/unit/Reflection/ReflectionFunctionAbstractTest.php b/test/unit/Reflection/ReflectionFunctionAbstractTest.php index ca50541d7..d4ac4eb9f 100644 --- a/test/unit/Reflection/ReflectionFunctionAbstractTest.php +++ b/test/unit/Reflection/ReflectionFunctionAbstractTest.php @@ -471,7 +471,7 @@ public function testGetLocatedSource(): void self::assertSame($locatedSource, $functionInfo->getLocatedSource()); } - /** @return list */ + /** @return list */ public static function returnTypeFunctionProvider(): array { return [ @@ -480,46 +480,30 @@ public static function returnTypeFunctionProvider(): array ['returnsNull', 'null'], ['returnsObject', stdClass::class], ['returnsVoid', 'void'], + ['returnsVoid', 'void'], + ['returnsNothing', null], + ['returnsUnion', 'int|string'], + ['returnsIntersection', 'DateTime&DateTimeImmutable'], ]; } #[DataProvider('returnTypeFunctionProvider')] - public function testGetReturnTypeWithDeclaredType(string $functionToReflect, string $expectedType): void + public function testGetReturnTypeWithDeclaredType(string $functionToReflect, string|null $expectedType): void { $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), + new SingleFileSourceLocator(__DIR__ . '/../Fixture/ReturnTypeDeclarations.php', $this->astLocator), ))->reflectFunction($functionToReflect); - $reflectionType = $functionInfo->getReturnType(); - self::assertInstanceOf(ReflectionType::class, $reflectionType); - self::assertSame($expectedType, (string) $reflectionType); - } - - public function testGetReturnTypeReturnsNullWhenTypeIsNotDeclared(): void - { - $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), - ))->reflectFunction('returnsNothing'); - - self::assertNull($functionInfo->getReturnType()); - } - - public function testHasReturnTypeWhenTypeDeclared(): void - { - $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), - ))->reflectFunction('returnsString'); + if ($expectedType === null) { + self::assertFalse($functionInfo->hasReturnType()); + self::assertNull($functionInfo->getReturnType()); + } else { + self::assertTrue($functionInfo->hasReturnType()); - self::assertTrue($functionInfo->hasReturnType()); - } - - public function testHasReturnTypeWhenTypeIsNotDeclared(): void - { - $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), - ))->reflectFunction('returnsNothing'); - - self::assertFalse($functionInfo->hasReturnType()); + $reflectionType = $functionInfo->getReturnType(); + self::assertInstanceOf(ReflectionType::class, $reflectionType); + self::assertSame($expectedType, (string) $reflectionType); + } } /** @return list */ @@ -536,7 +520,7 @@ public static function nullableReturnTypeFunctionProvider(): array public function testGetNullableReturnTypeWithDeclaredType(string $functionToReflect, string $expectedType): void { $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php71NullableReturnTypeDeclarations.php', $this->astLocator), + new SingleFileSourceLocator(__DIR__ . '/../Fixture/ReturnTypeDeclarations.php', $this->astLocator), ))->reflectFunction($functionToReflect); $reflectionType = $functionInfo->getReturnType(); @@ -557,11 +541,13 @@ public function testHasTentativeReturnType(): void public function testHasNotTentativeReturnType(): void { $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), + new SingleFileSourceLocator(__DIR__ . '/../Fixture/ReturnTypeDeclarations.php', $this->astLocator), ))->reflectFunction('returnsString'); self::assertFalse($functionInfo->hasTentativeReturnType()); + self::assertNull($functionInfo->getTentativeReturnType()); self::assertTrue($functionInfo->hasReturnType()); + self::assertNotNull($functionInfo->getReturnType()); } public function testGetTentativeReturnType(): void @@ -576,16 +562,6 @@ public function testGetTentativeReturnType(): void self::assertNull($methodInfo->getReturnType()); } - public function testNoTentativeReturnType(): void - { - $functionInfo = (new DefaultReflector( - new SingleFileSourceLocator(__DIR__ . '/../Fixture/Php7ReturnTypeDeclarations.php', $this->astLocator), - ))->reflectFunction('returnsString'); - - self::assertNull($functionInfo->getTentativeReturnType()); - self::assertNotNull($functionInfo->getReturnType()); - } - #[DataProvider('deprecatedDocCommentsProvider')] public function testFunctionsCanBeDeprecated(string $comment): void { diff --git a/test/unit/Reflection/ReflectionPropertyTest.php b/test/unit/Reflection/ReflectionPropertyTest.php index ed8cb3e34..6d678e24a 100644 --- a/test/unit/Reflection/ReflectionPropertyTest.php +++ b/test/unit/Reflection/ReflectionPropertyTest.php @@ -915,7 +915,7 @@ public static function asymetricVisibilityModifierProvider(): array /** @param non-empty-string $propertyName */ #[DataProvider('asymetricVisibilityModifierProvider')] - public function testGetAsymetricVisibilityModifiers(string $propertyName, int $expectedModifier): void + public function testGetAsymetricVisibilityMethods(string $propertyName, int $expectedModifier): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/AsymetricVisibilityClass.php', $this->astLocator)); $classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\AsymetricVisibilityClass'); @@ -924,6 +924,30 @@ public function testGetAsymetricVisibilityModifiers(string $propertyName, int $e self::assertSame($expectedModifier, $property->getModifiers()); } + public function testIsProtectedSet(): void + { + $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/AsymetricVisibilityClass.php', $this->astLocator)); + $classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\AsymetricVisibilityClass'); + + $publicPublicSetProperty = $classInfo->getProperty('publicPublicSet'); + $publicProtectedSetProperty = $classInfo->getProperty('publicProtectedSet'); + + self::assertFalse($publicPublicSetProperty->isProtectedSet()); + self::assertTrue($publicProtectedSetProperty->isProtectedSet()); + } + + public function testIsPrivateSet(): void + { + $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/AsymetricVisibilityClass.php', $this->astLocator)); + $classInfo = $reflector->reflectClass('Roave\BetterReflectionTest\Fixture\AsymetricVisibilityClass'); + + $protectedProtectedSet = $classInfo->getProperty('protectedProtectedSet'); + $protectedPrivateSet = $classInfo->getProperty('protectedPrivateSet'); + + self::assertFalse($protectedProtectedSet->isPrivateSet()); + self::assertTrue($protectedPrivateSet->isPrivateSet()); + } + public function testIsAbstract(): void { $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/PropertyHooks.php', $this->astLocator)); diff --git a/test/unit/SourceLocator/Ast/FindReflectionsInTreeTest.php b/test/unit/SourceLocator/Ast/FindReflectionsInTreeTest.php index e938694c9..a657dcbef 100644 --- a/test/unit/SourceLocator/Ast/FindReflectionsInTreeTest.php +++ b/test/unit/SourceLocator/Ast/FindReflectionsInTreeTest.php @@ -7,6 +7,7 @@ use PhpParser\Node; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Constraint\Callback; use PHPUnit\Framework\TestCase; use Roave\BetterReflection\Identifier\Identifier; use Roave\BetterReflection\Identifier\IdentifierType; @@ -215,6 +216,12 @@ public function testInvokeCallsReflectNodesForConstantByDefine(): void $strategy->expects($this->once()) ->method('__invoke') + ->with( + $this->isInstanceOf(Reflector::class), + new Callback( + static fn (Node $node): bool => $node instanceof Node\Expr\FuncCall && $node->getDocComment() !== null, + ), + ) ->willReturn($mockReflection); $reflector = $this->createMock(Reflector::class); @@ -224,6 +231,7 @@ public function testInvokeCallsReflectNodesForConstantByDefine(): void $source = <<<'PHP'