From f89f251697762c00d0e496570f85022880d8b377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 10:00:15 +0100 Subject: [PATCH 1/8] Killed some mutants --- .../SourceStubber/PhpStormStubsSourceStubber.php | 10 ++++++++-- src/SourceLocator/Type/MemoizingSourceLocator.php | 2 +- test/unit/Util/CalculateReflectionColumnTest.php | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index 249b73bb2..b555c95a1 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -376,13 +376,19 @@ private function createStub(Node $node, string $extension): string $node = $namespaceBuilder->getNode(); } - return "prettyPrinter->prettyPrint([$node]) . ($node instanceof Node\Expr\FuncCall ? ';' : '') . "\n"; + return sprintf( + "prettyPrinter->prettyPrint([$node]), + $node instanceof Node\Expr\FuncCall ? ';' : '', + ); } private function createCachingVisitor(): NodeVisitorAbstract { return new class () extends NodeVisitorAbstract { + private const TRUE_FALSE_NULL = ['true', 'false', 'null']; + /** @var array */ private array $classNodes = []; @@ -450,7 +456,7 @@ public function enterNode(Node $node): ?int assert($nameNode instanceof Node\Scalar\String_); $constantName = $nameNode->value; - if (in_array($constantName, ['true', 'false', 'null'], true)) { + if (in_array($constantName, self::TRUE_FALSE_NULL, true)) { $constantName = strtoupper($constantName); $nameNode->value = $constantName; } diff --git a/src/SourceLocator/Type/MemoizingSourceLocator.php b/src/SourceLocator/Type/MemoizingSourceLocator.php index d8553586a..22b79d844 100644 --- a/src/SourceLocator/Type/MemoizingSourceLocator.php +++ b/src/SourceLocator/Type/MemoizingSourceLocator.php @@ -42,7 +42,7 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier): */ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array { - $cacheKey = $this->reflectorCacheKey($reflector) . '_' . $this->identifierTypeToCacheKey($identifierType); + $cacheKey = sprintf('%s_%s', $this->reflectorCacheKey($reflector), $this->identifierTypeToCacheKey($identifierType)); if (array_key_exists($cacheKey, $this->cacheByIdentifierTypeKeyAndOid)) { return $this->cacheByIdentifierTypeKeyAndOid[$cacheKey]; diff --git a/test/unit/Util/CalculateReflectionColumnTest.php b/test/unit/Util/CalculateReflectionColumnTest.php index e19a3e5e7..9afd6cc8c 100644 --- a/test/unit/Util/CalculateReflectionColumnTest.php +++ b/test/unit/Util/CalculateReflectionColumnTest.php @@ -72,11 +72,11 @@ public function testGetStartColumnThrowsExceptionIfInvalidPosition(): void ->willReturn(true); $node ->method('getStartFilePos') - ->willReturn(10000); + ->willReturn(5); $this->expectException(InvalidNodePosition::class); - CalculateReflectionColumn::getStartColumn('', $node); + CalculateReflectionColumn::getStartColumn('test', $node); } public function testGetStartColumnThrowsExceptionIfNoPosition(): void From 2bdc9a6ae452174e94fef1a619602ca098af4db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 10:31:53 +0100 Subject: [PATCH 2/8] Improved parsing of supported PHP versions in PhpStormStubsSourceStubber --- .../PhpStormStubsSourceStubber.php | 39 +++++++++++-------- .../PhpStormStubsSourceStubberTest.php | 9 +++++ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index b555c95a1..6ef936c77 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -637,22 +637,31 @@ private function isSupportedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\Function_ return true; } + [$fromVersion, $toVersion] = $this->getSupportedPhpVersions($node); + + if ($fromVersion !== null && $fromVersion > $this->phpVersion) { + return false; + } + + return $toVersion === null || $toVersion >= $this->phpVersion; + } + + /** + * @return array{0: int|null, 1: int|null} + */ + private function getSupportedPhpVersions(Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt $node): array + { + $fromVersion = null; + $toVersion = null; + $docComment = $node->getDocComment(); if ($docComment !== null) { if (preg_match('~@since\s+(?P\d+\.\d+(?:\.\d+)?)\s+~', $docComment->getText(), $sinceMatches) === 1) { - $sincePhpVersion = $this->parsePhpVersion($sinceMatches['version']); - - if ($sincePhpVersion > $this->phpVersion) { - return false; - } + $fromVersion = $this->parsePhpVersion($sinceMatches['version']); } if (preg_match('~@removed\s+(?P\d+\.\d+(?:\.\d+)?)\s+~', $docComment->getText(), $removedMatches) === 1) { - $removedPhpVersion = $this->parsePhpVersion($removedMatches['version']); - - if ($removedPhpVersion <= $this->phpVersion) { - return false; - } + $toVersion = $this->parsePhpVersion($removedMatches['version']) - 1; } } @@ -668,9 +677,7 @@ private function isSupportedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\Function_ if ($attributeArg->name === null || $attributeArg->name->toString() === 'from') { assert($attributeArg->value instanceof Node\Scalar\String_); - if ($this->parsePhpVersion($attributeArg->value->value) > $this->phpVersion) { - return false; - } + $fromVersion = $this->parsePhpVersion($attributeArg->value->value); } if ($attributeArg->name?->toString() !== 'to') { @@ -679,15 +686,13 @@ private function isSupportedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\Function_ assert($attributeArg->value instanceof Node\Scalar\String_); - if ($this->parsePhpVersion($attributeArg->value->value) < $this->phpVersion) { - return false; - } + $toVersion = $this->parsePhpVersion($attributeArg->value->value); } } } } - return true; + return [$fromVersion, $toVersion]; } private function parsePhpVersion(string $version): int diff --git a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php index df33169f0..874fd2893 100644 --- a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php @@ -32,6 +32,7 @@ use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator; use Roave\BetterReflection\Util\FileHelper; use Roave\BetterReflectionTest\BetterReflectionSingleton; +use SplFileObject; use Stringable; use ZipArchive; @@ -693,6 +694,8 @@ public function dataClassInPhpVersion(): array [Stringable::class, 80000, true], [Stringable::class, 70400, false], [Stringable::class, 70399, false], + ['DOMNameList', 79999, true], + ['DOMNameList', 80000, false], ]; } @@ -719,6 +722,7 @@ public function dataClassConstantInPhpVersion(): array [DateTimeInterface::class, 'ATOM', 70200, true], [DateTimeInterface::class, 'ATOM', 70100, false], [DateTime::class, 'ATOM', 70100, true], + [DateTime::class, 'ATOM', 70199, true], [DateTime::class, 'ATOM', 70200, false], [PDO::class, 'FETCH_DEFAULT', 80007, true], [PDO::class, 'FETCH_DEFAULT', 80006, false], @@ -753,6 +757,8 @@ public function dataMethodInPhpVersion(): array [CoreReflectionClass::class, 'export', 80000, false], [DatePeriod::class, 'getRecurrences', 70217, true], [DatePeriod::class, 'getRecurrences', 70216, false], + [SplFileObject::class, 'fgetss', 79999, true], + [SplFileObject::class, 'fgetss', 80000, false], ]; } @@ -808,6 +814,8 @@ public function dataFunctionInPhpVersion(): array ['mysql_query', 70000, false], ['hash_hkdf', 70102, true], ['hash_hkdf', 70101, false], + ['read_exif_data', 79999, true], + ['read_exif_data', 80000, false], // Not core functions ['newrelic_add_custom_parameter', 40000, true], ]; @@ -860,6 +868,7 @@ public function dataConstantInPhpVersion(): array ['PHP_OS_FAMILY', 70200, true], ['PHP_OS_FAMILY', 70100, false], ['INPUT_SESSION', 70400, true], + ['INPUT_SESSION', 79999, true], ['INPUT_SESSION', 80000, false], ['CURL_VERSION_ALTSVC', 70306, true], ['CURL_VERSION_ALTSVC', 70305, false], From 933dcb9c61745c29702199f0a1260d36c083cda0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 10:58:48 +0100 Subject: [PATCH 3/8] Killed some mutants --- .../PhpStormStubsSourceStubber.php | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index 6ef936c77..dd358982b 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -555,17 +555,13 @@ private function modifyStmtsByPhpVersion(array $stmts, bool $isCoreExtension): a { $newStmts = []; foreach ($stmts as $stmt) { + assert($stmt instanceof Node\Stmt\ClassConst || $stmt instanceof Node\Stmt\Property || $stmt instanceof Node\Stmt\ClassMethod); + if (! $this->isSupportedInPhpVersion($stmt, $isCoreExtension)) { continue; } - if ( - $stmt instanceof Node\Stmt\ClassConst - || $stmt instanceof Node\Stmt\Property - || $stmt instanceof Node\Stmt\ClassMethod - ) { - $this->addDeprecatedDocComment($stmt); - } + $this->addDeprecatedDocComment($stmt); $newStmts[] = $stmt; } @@ -626,8 +622,10 @@ private function isDeprecatedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\ClassCon return false; } - private function isSupportedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt $node, bool $isCoreExtension): bool - { + private function isSupportedInPhpVersion( + Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod $node, + bool $isCoreExtension, + ): bool { if ($this->phpVersion === null) { return true; } @@ -649,8 +647,9 @@ private function isSupportedInPhpVersion(Node\Stmt\ClassLike|Node\Stmt\Function_ /** * @return array{0: int|null, 1: int|null} */ - private function getSupportedPhpVersions(Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt $node): array - { + private function getSupportedPhpVersions( + Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall|Node\Stmt\ClassConst|Node\Stmt\Property|Node\Stmt\ClassMethod $node, + ): array { $fromVersion = null; $toVersion = null; From 3e4cb999a861bebca9868ec959e4f20db398fc54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 11:04:26 +0100 Subject: [PATCH 4/8] Improved tests of detection deprecated in PhpStormStubsSourceStubber --- .../SourceStubber/PhpStormStubsSourceStubberTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php index 874fd2893..5658b8eff 100644 --- a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php @@ -949,6 +949,7 @@ public function dataMethodIsDeprecatedInPhpVersion(): array [CoreReflectionClass::class, 'export', null, true], [CoreReflectionClass::class, 'export', 70400, true], [CoreReflectionClass::class, 'export', 70300, false], + [CoreReflectionClass::class, 'export', 70399, false], ]; } @@ -1003,6 +1004,7 @@ public function dataFunctionIsDeprecatedInPhpVersion(): array ['create_function', null, true], ['create_function', 70200, true], ['create_function', 70100, false], + ['create_function', 70199, false], ]; } From 4e71bf45f8ab57d5c7c98990575e36ffe36df69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 14:23:48 +0100 Subject: [PATCH 5/8] Improved tests for PhpStormStubsSourceStubber --- .../PhpStormStubsSourceStubberTest.php | 86 +++++++++++++++++-- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php index 5658b8eff..76e5b5311 100644 --- a/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php +++ b/test/unit/SourceLocator/SourceStubber/PhpStormStubsSourceStubberTest.php @@ -9,6 +9,7 @@ use DatePeriod; use DateTime; use DateTimeInterface; +use Generator; use PDO; use PhpParser\Parser; use PHPUnit\Framework\TestCase; @@ -27,6 +28,7 @@ use Roave\BetterReflection\Reflector\Reflector; use Roave\BetterReflection\SourceLocator\Ast\Locator; use Roave\BetterReflection\SourceLocator\SourceStubber\PhpStormStubsSourceStubber; +use Roave\BetterReflection\SourceLocator\SourceStubber\StubData; use Roave\BetterReflection\SourceLocator\Type\AggregateSourceLocator; use Roave\BetterReflection\SourceLocator\Type\PhpInternalSourceLocator; use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator; @@ -34,6 +36,7 @@ use Roave\BetterReflectionTest\BetterReflectionSingleton; use SplFileObject; use Stringable; +use Traversable; use ZipArchive; use function array_filter; @@ -522,21 +525,60 @@ public function testConstantInNamespace(string $constantName): void $this->assertSame($constantName, $constantReflection->getName()); } - public function testNoStubForUnknownClass(): void + public function testNameResolverForClassInNamespace(): void + { + $classReflection = $this->reflector->reflectClass('http\Client'); + $methodReflection = $classReflection->getMethod('enqueue'); + $parameterReflection = $methodReflection->getParameter('request'); + + self::assertSame('http\Client\Request', $parameterReflection->getType()->getName()); + } + + public function testStubForClassThatExists(): void + { + self::assertInstanceOf(StubData::class, $this->sourceStubber->generateClassStub('ReflectionClass')); + } + + public function testNoStubForClassThatDoesNotExist(): void { self::assertNull($this->sourceStubber->generateClassStub('SomeClass')); } - public function testNoStubForUnknownFunction(): void + public function testStubForFunctionThatExists(): void + { + self::assertInstanceOf(StubData::class, $this->sourceStubber->generateFunctionStub('phpversion')); + } + + public function testNoStubForFunctionThatDoesNotExist(): void { self::assertNull($this->sourceStubber->generateFunctionStub('someFunction')); } - public function testNoStubForUnknownConstant(): void + public function testStubForConstantThatExists(): void + { + self::assertInstanceOf(StubData::class, $this->sourceStubber->generateConstantStub('PHP_VERSION_ID')); + } + + public function testNoStubForConstantThatDoesNotExist(): void { self::assertNull($this->sourceStubber->generateConstantStub('SOME_CONSTANT')); } + public function testStubForConstantDeclaredByDefine(): void + { + $stub = $this->sourceStubber->generateConstantStub('PHP_VERSION_ID'); + + self::assertInstanceOf(StubData::class, $stub); + self::assertStringEndsWith(";\n", $stub->getStub()); + } + + public function testStubForConstantDeclaredByConst(): void + { + $stub = $this->sourceStubber->generateConstantStub('ast\AST_ARG_LIST'); + + self::assertInstanceOf(StubData::class, $stub); + } + public function dataCaseInsensitiveClass(): array { return [ @@ -613,7 +655,7 @@ public function testCaseInsensitiveConstant(string $constantName, string $expect $this->assertSame($expectedConstantName, $reflector->getName()); } - public function dataCaseSensitiveConstant(): array + public function dataCaseSensitiveConstantSearchedByWrongCase(): array { return [ ['date_atom'], @@ -623,15 +665,32 @@ public function dataCaseSensitiveConstant(): array } /** - * @dataProvider dataCaseSensitiveConstant + * @dataProvider dataCaseSensitiveConstantSearchedByWrongCase */ - public function testCaseSensitiveConstant(string $constantName): void + public function testCaseSensitiveConstantSearchedByWrongCase(string $constantName): void { self::expectException(IdentifierNotFound::class); $this->reflector->reflectConstant($constantName); } + public function dataCaseSensitiveConstantSearchedByRightCase(): array + { + return [ + ['DATE_ATOM'], + ['PHP_VERSION_ID'], + ['FILEINFO_NONE'], + ]; + } + + /** + * @dataProvider dataCaseSensitiveConstantSearchedByRightCase + */ + public function testCaseSensitiveConstantSearchedByRightCase(string $constantName): void + { + self::assertInstanceOf(ReflectionConstant::class, $this->reflector->reflectConstant($constantName)); + } + /** * The second search should use optimization, see code coverage. */ @@ -1020,4 +1079,19 @@ public function testFunctionIsDeprecatedInPhpVersion(string $functionName, ?int self::assertSame($isDeprecated, $functionReflection->isDeprecated()); } + + public function testModifiedStubForTraversableClass(): void + { + $classReflection = $this->reflector->reflectClass(Traversable::class); + + self::assertInstanceOf(ReflectionClass::class, $classReflection); + } + + public function testModifiedStubForGeneratorClass(): void + { + $classReflection = $this->reflector->reflectClass(Generator::class); + + self::assertInstanceOf(ReflectionClass::class, $classReflection); + self::assertTrue($classReflection->hasMethod('throw')); + } } From 27aaa0b88b70e2aa8a5b982d89bd1daa81f481ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 14:54:10 +0100 Subject: [PATCH 6/8] Removed dead code --- .../SourceStubber/PhpStormStubsSourceStubber.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php index dd358982b..5e4c39600 100644 --- a/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php +++ b/src/SourceLocator/SourceStubber/PhpStormStubsSourceStubber.php @@ -221,7 +221,7 @@ public function generateClassStub(string $className): ?StubData } $extension = $this->getExtensionFromFilePath($filePath); - $stub = $this->createStub($this->classNodes[$lowercaseClassName], $extension); + $stub = $this->createStub($this->classNodes[$lowercaseClassName]); if ($className === Traversable::class) { // See https://github.com/JetBrains/phpstorm-stubs/commit/0778a26992c47d7dbee4d0b0bfb7fad4344371b1#diff-575bacb45377d474336c71cbf53c1729 @@ -259,7 +259,7 @@ public function generateFunctionStub(string $functionName): ?StubData $extension = $this->getExtensionFromFilePath($filePath); - return new StubData($this->createStub($this->functionNodes[$lowercaseFunctionName], $extension), $extension); + return new StubData($this->createStub($this->functionNodes[$lowercaseFunctionName]), $extension); } public function generateConstantStub(string $constantName): ?StubData @@ -295,7 +295,7 @@ public function generateConstantStub(string $constantName): ?StubData $extension = $this->getExtensionFromFilePath($filePath); - return new StubData($this->createStub($constantNode, $extension), $extension); + return new StubData($this->createStub($constantNode), $extension); } private function parseFile(string $filePath): void @@ -363,7 +363,7 @@ private function parseFile(string $filePath): void /** * @param Node\Stmt\ClassLike|Node\Stmt\Function_|Node\Stmt\Const_|Node\Expr\FuncCall $node */ - private function createStub(Node $node, string $extension): string + private function createStub(Node $node): string { if (! ($node instanceof Node\Expr\FuncCall)) { $this->addDeprecatedDocComment($node); From 3a052f55564c09c0eb322b73f43631698b6e0437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 16:22:13 +0100 Subject: [PATCH 7/8] Improved tests for default enum properties --- test/unit/Reflection/ReflectionClassTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/unit/Reflection/ReflectionClassTest.php b/test/unit/Reflection/ReflectionClassTest.php index c0a86815a..0f4b77ce5 100644 --- a/test/unit/Reflection/ReflectionClassTest.php +++ b/test/unit/Reflection/ReflectionClassTest.php @@ -459,6 +459,8 @@ public function testGetPropertiesForPureEnum(): void self::assertTrue($property->isPublic()); self::assertTrue($property->isReadOnly()); + self::assertFalse($property->isPromoted()); + self::assertTrue($property->isDefault()); self::assertSame(0, $property->getPositionInAst()); } @@ -479,6 +481,8 @@ public function testGetPropertiesForBackedEnum(): void self::assertTrue($property->isPublic(), $propertyName); self::assertTrue($property->isReadOnly(), $propertyName); + self::assertFalse($property->isPromoted()); + self::assertTrue($property->isDefault()); self::assertSame(0, $property->getPositionInAst(), $propertyName); } } From 2696b2677e6da15611abe6ce36ff476b82c31699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Hansl=C3=ADk?= Date: Sun, 14 Nov 2021 16:26:06 +0100 Subject: [PATCH 8/8] Improved tests for ReflectionClass::getDefaultProperties() --- test/unit/Reflection/ReflectionClassTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/unit/Reflection/ReflectionClassTest.php b/test/unit/Reflection/ReflectionClassTest.php index 0f4b77ce5..49b194b5b 100644 --- a/test/unit/Reflection/ReflectionClassTest.php +++ b/test/unit/Reflection/ReflectionClassTest.php @@ -786,6 +786,22 @@ public function testGetMethodIsCaseInsensitive(): void } public function testGetDefaultProperties(): void + { + $reflector = new DefaultReflector(new SingleFileSourceLocator(__DIR__ . '/../Fixture/DefaultProperties.php', $this->astLocator)); + $classInfo = $reflector->reflectClass(DefaultProperties::class); + + self::assertSame([ + 'fromTrait' => 'anything', + 'hasDefault' => 'const', + 'hasNullAsDefault' => null, + 'noDefault' => null, + 'hasDefaultWithType' => 123, + 'hasNullAsDefaultWithType' => null, + 'noDefaultWithType' => null, + ], $classInfo->getDefaultProperties()); + } + + public function testGetDefaultPropertiesShouldIgnoreRuntimeProperty(): void { $object = new DefaultProperties(); $object->notDefaultProperty = null;