Repository: Roave/BetterReflection (php)

Issue:
Reflection Adapter vs. non-empty-string
This PR https://github.com/Roave/BetterReflection/pull/1234 made Adapter reflection incompatible with the native PHP reflection. The native reflection returns `false` in `has*` methods if it's asked about nonexistent elements, and throws ReflectionException in `get*` methods: https://3v4l.org/YebV9

But the `assert($name !== '');` calls are unforgiving even for `has*` methods. The current situation isn't great, because these methods have `string` in parameter types but reject `''` at runtime. So currently these problems cannot be detected and avoided with static analysis.

I'd prefer if the Adapter namespace matched the behaviour of native reflection:

For `has*` methods, instead of the assert, do this:

```php
if ($s === '') {
    return false;
}
```

For `get*` methods, throw ReflectionException for empty strings.

Thank you.

Pull request description:
Fixed reflection compatibility when method/property/constant/case name is empty
Fixes #1278

Patch:
diff --git a/src/Reflection/Adapter/ReflectionClass.php b/src/Reflection/Adapter/ReflectionClass.php
index 49a8822b..db668af0 100644
--- a/src/Reflection/Adapter/ReflectionClass.php
+++ b/src/Reflection/Adapter/ReflectionClass.php
@@ -22,7 +22,6 @@ use ValueError;
 use function array_combine;
 use function array_map;
 use function array_values;
-use function assert;
 use function constant;
 use function func_num_args;
 use function sprintf;
@@ -117,16 +116,16 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function hasMethod(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionClass->hasMethod($name);
     }
 
     public function getMethod(string $name): ReflectionMethod
     {
-        assert($name !== '');
-
-        $method = $this->betterReflectionClass->getMethod($name);
+        $method = $name !== '' ? $this->betterReflectionClass->getMethod($name) : null;
 
         if ($method === null) {
             throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionClass->getName(), $name));
@@ -152,16 +151,16 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function hasProperty(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionClass->hasProperty($name);
     }
 
     public function getProperty(string $name): ReflectionProperty
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionClass->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionClass->getName(), $name));
@@ -187,7 +186,9 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function hasConstant(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         if ($this->betterReflectionClass instanceof BetterReflectionEnum && $this->betterReflectionClass->hasCase($name)) {
             return true;
@@ -211,7 +212,9 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function getConstant(string $name): mixed
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         if ($this->betterReflectionClass instanceof BetterReflectionEnum) {
             $enumCase = $this->betterReflectionClass->getCase($name);
@@ -239,7 +242,9 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function getReflectionConstant(string $name): ReflectionClassConstant|false
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         if ($this->betterReflectionClass instanceof BetterReflectionEnum) {
             $enumCase = $this->betterReflectionClass->getCase($name);
@@ -420,9 +425,7 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function getStaticPropertyValue(string $name, mixed $default = null): mixed
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionClass->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             if (func_num_args() === 2) {
@@ -443,9 +446,7 @@ final class ReflectionClass extends CoreReflectionClass
 
     public function setStaticPropertyValue(string $name, mixed $value): void
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionClass->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionClass->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionClass->getName(), $name));
diff --git a/src/Reflection/Adapter/ReflectionEnum.php b/src/Reflection/Adapter/ReflectionEnum.php
index eb880581..07d35d25 100644
--- a/src/Reflection/Adapter/ReflectionEnum.php
+++ b/src/Reflection/Adapter/ReflectionEnum.php
@@ -23,7 +23,6 @@ use ValueError;
 use function array_combine;
 use function array_map;
 use function array_values;
-use function assert;
 use function constant;
 use function sprintf;
 use function strtolower;
@@ -115,16 +114,16 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function hasMethod(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionEnum->hasMethod($name);
     }
 
     public function getMethod(string $name): ReflectionMethod
     {
-        assert($name !== '');
-
-        $method = $this->betterReflectionEnum->getMethod($name);
+        $method = $name !== '' ? $this->betterReflectionEnum->getMethod($name) : null;
 
         if ($method === null) {
             throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionEnum->getName(), $name));
@@ -150,16 +149,16 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function hasProperty(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionEnum->hasProperty($name);
     }
 
     public function getProperty(string $name): ReflectionProperty
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionEnum->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionEnum->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionEnum->getName(), $name));
@@ -185,7 +184,9 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function hasConstant(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionEnum->hasCase($name) || $this->betterReflectionEnum->hasConstant($name);
     }
@@ -205,7 +206,9 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function getConstant(string $name): mixed
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         $enumCase = $this->betterReflectionEnum->getCase($name);
         if ($enumCase !== null) {
@@ -231,7 +234,9 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function getReflectionConstant(string $name): ReflectionClassConstant|false
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         // @infection-ignore-all Coalesce: There's no difference
         $betterReflectionConstantOrEnumCase = $this->betterReflectionEnum->getCase($name) ?? $this->betterReflectionEnum->getConstant($name);
@@ -493,16 +498,16 @@ final class ReflectionEnum extends CoreReflectionEnum
 
     public function hasCase(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionEnum->hasCase($name);
     }
 
     public function getCase(string $name): ReflectionEnumUnitCase|ReflectionEnumBackedCase
     {
-        assert($name !== '');
-
-        $case = $this->betterReflectionEnum->getCase($name);
+        $case = $name !== '' ? $this->betterReflectionEnum->getCase($name) : null;
 
         if ($case === null) {
             throw new CoreReflectionException(sprintf('Case %s::%s does not exist', $this->betterReflectionEnum->getName(), $name));
diff --git a/src/Reflection/Adapter/ReflectionObject.php b/src/Reflection/Adapter/ReflectionObject.php
index a3d115d1..2eb8d74f 100644
--- a/src/Reflection/Adapter/ReflectionObject.php
+++ b/src/Reflection/Adapter/ReflectionObject.php
@@ -21,7 +21,6 @@ use ValueError;
 use function array_combine;
 use function array_map;
 use function array_values;
-use function assert;
 use function func_num_args;
 use function sprintf;
 use function strtolower;
@@ -99,16 +98,16 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function hasMethod(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionObject->hasMethod($this->getMethodRealName($name));
     }
 
     public function getMethod(string $name): ReflectionMethod
     {
-        assert($name !== '');
-
-        $method = $this->betterReflectionObject->getMethod($this->getMethodRealName($name));
+        $method = $name !== '' ? $this->betterReflectionObject->getMethod($this->getMethodRealName($name)) : null;
 
         if ($method === null) {
             throw new CoreReflectionException(sprintf('Method %s::%s() does not exist', $this->betterReflectionObject->getName(), $name));
@@ -150,16 +149,16 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function hasProperty(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionObject->hasProperty($name);
     }
 
     public function getProperty(string $name): ReflectionProperty
     {
-        assert($name !== '');
-
-        $property = $this->betterReflectionObject->getProperty($name);
+        $property = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null;
 
         if ($property === null) {
             throw new CoreReflectionException(sprintf('Property %s::$%s does not exist', $this->betterReflectionObject->getName(), $name));
@@ -185,7 +184,9 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function hasConstant(string $name): bool
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         return $this->betterReflectionObject->hasConstant($name);
     }
@@ -205,7 +206,9 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function getConstant(string $name): mixed
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         $betterReflectionConstant = $this->betterReflectionObject->getConstant($name);
         if ($betterReflectionConstant === null) {
@@ -217,7 +220,9 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function getReflectionConstant(string $name): ReflectionClassConstant|false
     {
-        assert($name !== '');
+        if ($name === '') {
+            return false;
+        }
 
         $betterReflectionConstant = $this->betterReflectionObject->getConstant($name);
 
@@ -370,9 +375,7 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function getStaticPropertyValue(string $name, mixed $default = null): mixed
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionObject->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             if (func_num_args() === 2) {
@@ -393,9 +396,7 @@ final class ReflectionObject extends CoreReflectionObject
 
     public function setStaticPropertyValue(string $name, mixed $value): void
     {
-        assert($name !== '');
-
-        $betterReflectionProperty = $this->betterReflectionObject->getProperty($name);
+        $betterReflectionProperty = $name !== '' ? $this->betterReflectionObject->getProperty($name) : null;
 
         if ($betterReflectionProperty === null) {
             throw new CoreReflectionException(sprintf('Class %s does not have a property named %s', $this->betterReflectionObject->getName(), $name));


Test patch:
diff --git a/test/unit/Reflection/Adapter/ReflectionClassTest.php b/test/unit/Reflection/Adapter/ReflectionClassTest.php
index 6170cbcb..cc78b662 100644
--- a/test/unit/Reflection/Adapter/ReflectionClassTest.php
+++ b/test/unit/Reflection/Adapter/ReflectionClassTest.php
@@ -212,6 +212,28 @@ class ReflectionClassTest extends TestCase
         self::assertFalse($reflectionClassAdapter->getParentClass());
     }
 
+    public function testHasMethodReturnsFalseWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionClass  = $this->createMock(BetterReflectionClass::class);
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::assertFalse($reflectionClassAdapter->hasMethod(''));
+    }
+
+    public function testGetMethodThrowsExceptionWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
+        $betterReflectionClass
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Method SomeClass::() does not exist');
+        $reflectionClassAdapter->getMethod('');
+    }
+
     public function testGetMethodThrowsExceptionWhenMethodDoesNotExist(): void
     {
         $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
@@ -496,6 +518,28 @@ class ReflectionClassTest extends TestCase
         self::assertTrue($reflectionClassAdapter->implementsInterface('FoO'));
     }
 
+    public function testHasPropertyReturnFalseWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionClass  = $this->createMock(BetterReflectionClass::class);
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::assertFalse($reflectionClassAdapter->hasProperty(''));
+    }
+
+    public function testGetPropertyThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
+        $betterReflectionClass
+            ->method('getName')
+            ->willReturn('Boo');
+
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Property Boo::$ does not exist');
+        $reflectionClassAdapter->getProperty('');
+    }
+
     public function testGetPropertyThrowsExceptionWhenPropertyDoesNotExist(): void
     {
         $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
@@ -574,6 +618,20 @@ class ReflectionClassTest extends TestCase
         self::assertSame(123, $reflectionClassAdapter->getStaticPropertyValue('foo'));
     }
 
+    public function testGetStaticPropertyValueThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
+        $betterReflectionClass
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::expectException(CoreReflectionException::class);
+        self::expectExceptionMessage('Property SomeClass::$ does not exist');
+        $reflectionClassAdapter->getStaticPropertyValue('');
+    }
+
     public function testSetStaticPropertyValue(): void
     {
         $betterReflectionProperty = $this->createMock(BetterReflectionProperty::class);
@@ -599,6 +657,20 @@ class ReflectionClassTest extends TestCase
         $reflectionClassAdapter->setStaticPropertyValue('foo', 123);
     }
 
+    public function testSetStaticPropertyValueThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
+        $betterReflectionClass
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::expectException(CoreReflectionException::class);
+        self::expectExceptionMessage('Class SomeClass does not have a property named ');
+        $reflectionClassAdapter->setStaticPropertyValue('', '');
+    }
+
     public function testGetStaticPropertyValueThrowsExceptionWhenPropertyDoesNotExist(): void
     {
         $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
@@ -736,6 +808,14 @@ class ReflectionClassTest extends TestCase
         self::assertNull($reflectionClassAdapter->getConstructor());
     }
 
+    public function testHasConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionClass  = $this->createMock(BetterReflectionClass::class);
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::assertFalse($reflectionClassAdapter->hasConstant(''));
+    }
+
     public function testGetConstant(): void
     {
         $betterReflectionClassConstant = $this->createMock(BetterReflectionClassConstant::class);
@@ -754,6 +834,14 @@ class ReflectionClassTest extends TestCase
         self::assertSame(123, $reflectionClassAdapter->getConstant('FOO'));
     }
 
+    public function testGetConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionClass  = $this->createMock(BetterReflectionClass::class);
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::assertFalse($reflectionClassAdapter->getConstant(''));
+    }
+
     public function testGetConstantReturnsFalseWhenConstantDoesNotExist(): void
     {
         $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
@@ -793,6 +881,14 @@ class ReflectionClassTest extends TestCase
         self::assertFalse($reflectionClassAdapter->getReflectionConstant('FOO'));
     }
 
+    public function testGetReflectionConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionClass  = $this->createMock(BetterReflectionClass::class);
+        $reflectionClassAdapter = new ReflectionClassAdapter($betterReflectionClass);
+
+        self::assertFalse($reflectionClassAdapter->getReflectionConstant(''));
+    }
+
     public function testPropertyName(): void
     {
         $betterReflectionClass = $this->createMock(BetterReflectionClass::class);
diff --git a/test/unit/Reflection/Adapter/ReflectionEnumTest.php b/test/unit/Reflection/Adapter/ReflectionEnumTest.php
index 3946aed2..78da3aee 100644
--- a/test/unit/Reflection/Adapter/ReflectionEnumTest.php
+++ b/test/unit/Reflection/Adapter/ReflectionEnumTest.php
@@ -246,6 +246,28 @@ class ReflectionEnumTest extends TestCase
         self::assertNull($reflectionEnumAdapter->getConstructor());
     }
 
+    public function testHasPropertyReturnFalseWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionEnum  = $this->createMock(BetterReflectionEnum::class);
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionEnumAdapter->hasProperty(''));
+    }
+
+    public function testGetPropertyThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
+        $betterReflectionEnum
+            ->method('getName')
+            ->willReturn('Boo');
+
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Property Boo::$ does not exist');
+        $reflectionEnumAdapter->getProperty('');
+    }
+
     public function testGetPropertyThrowsExceptionWhenPropertyDoesNotExist(): void
     {
         $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
@@ -572,6 +594,28 @@ class ReflectionEnumTest extends TestCase
         $reflectionEnumAdapter->getAttributes(null, 123);
     }
 
+    public function testHasCaseReturnsFalseWhenCaseNameIsEmpty(): void
+    {
+        $betterReflectionEnum  = $this->createMock(BetterReflectionEnum::class);
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionEnumAdapter->hasCase(''));
+    }
+
+    public function testGetCaseThrowsExceptionWhenCaseNameIsEmpty(): void
+    {
+        $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
+        $betterReflectionEnum
+            ->method('getName')
+            ->willReturn('SomeEnum');
+
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::expectException(CoreReflectionException::class);
+        self::expectExceptionMessage('Case SomeEnum:: does not exist');
+        $reflectionEnumAdapter->getCase('');
+    }
+
     public function testGetCaseWhenCaseDoesNotExist(): void
     {
         $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
@@ -697,6 +741,14 @@ class ReflectionEnumTest extends TestCase
         self::assertTrue($reflectionClassAdapter->hasConstant('ENUM_CASE'));
     }
 
+    public function testHasConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionEnum  = $this->createMock(BetterReflectionEnum::class);
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionEnumAdapter->hasConstant(''));
+    }
+
     public function testGetConstant(): void
     {
         $betterReflectionClassConstant = $this->createMock(BetterReflectionClassConstant::class);
@@ -715,6 +767,14 @@ class ReflectionEnumTest extends TestCase
         self::assertSame(123, $reflectionClassAdapter->getConstant('FOO'));
     }
 
+    public function testGetConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionEnum   = $this->createMock(BetterReflectionEnum::class);
+        $reflectionClassAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionClassAdapter->getConstant(''));
+    }
+
     public function testGetConstantReturnsFalseWhenConstantDoesNotExist(): void
     {
         $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
@@ -761,6 +821,14 @@ class ReflectionEnumTest extends TestCase
         self::assertInstanceOf(AutoloadableEnum::class, $reflectionClassAdapter->getConstant('ENUM_CASE'));
     }
 
+    public function testGetReflectionConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionEnum   = $this->createMock(BetterReflectionEnum::class);
+        $reflectionClassAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionClassAdapter->getReflectionConstant(''));
+    }
+
     public function testGetReflectionConstantWithEnumCase(): void
     {
         $betterReflectionEnumCase = $this->createMock(BetterReflectionEnumCase::class);
@@ -859,6 +927,28 @@ class ReflectionEnumTest extends TestCase
         self::assertArrayHasKey($traitTwoClassName, $traits);
     }
 
+    public function testHasMethodReturnsFalseWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionEnum  = $this->createMock(BetterReflectionEnum::class);
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        self::assertFalse($reflectionEnumAdapter->hasMethod(''));
+    }
+
+    public function testGetMethodThrowsExceptionWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
+        $betterReflectionEnum
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionEnumAdapter = new ReflectionEnumAdapter($betterReflectionEnum);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Method SomeClass::() does not exist');
+        $reflectionEnumAdapter->getMethod('');
+    }
+
     public function testGetMethodThrowsExceptionWhenMethodDoesNotExist(): void
     {
         $betterReflectionEnum = $this->createMock(BetterReflectionEnum::class);
diff --git a/test/unit/Reflection/Adapter/ReflectionObjectTest.php b/test/unit/Reflection/Adapter/ReflectionObjectTest.php
index 757f9af2..fd756328 100644
--- a/test/unit/Reflection/Adapter/ReflectionObjectTest.php
+++ b/test/unit/Reflection/Adapter/ReflectionObjectTest.php
@@ -336,6 +336,28 @@ class ReflectionObjectTest extends TestCase
         self::assertTrue($reflectionObjectAdapter->implementsInterface('FoO'));
     }
 
+    public function testHasPropertyReturnFalseWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionObject  = $this->createMock(BetterReflectionObject::class);
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::assertFalse($reflectionObjectAdapter->hasProperty(''));
+    }
+
+    public function testGetPropertyThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
+        $betterReflectionObject
+            ->method('getName')
+            ->willReturn('Boo');
+
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Property Boo::$ does not exist');
+        $reflectionObjectAdapter->getProperty('');
+    }
+
     public function testGetPropertyThrowsExceptionWhenPropertyDoesNotExist(): void
     {
         $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
@@ -378,6 +400,20 @@ class ReflectionObjectTest extends TestCase
         self::assertSame(123, $reflectionClassAdapter->getStaticPropertyValue('foo'));
     }
 
+    public function testGetStaticPropertyValueThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
+        $betterReflectionObject
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::expectException(CoreReflectionException::class);
+        self::expectExceptionMessage('Property SomeClass::$ does not exist');
+        $reflectionObjectAdapter->getStaticPropertyValue('');
+    }
+
     public function testSetStaticPropertyValue(): void
     {
         $betterReflectionProperty = $this->createMock(BetterReflectionProperty::class);
@@ -403,6 +439,20 @@ class ReflectionObjectTest extends TestCase
         $reflectionClassAdapter->setStaticPropertyValue('foo', 123);
     }
 
+    public function testSetStaticPropertyValueThrowsExceptionWhenPropertyNameIsEmpty(): void
+    {
+        $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
+        $betterReflectionObject
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::expectException(CoreReflectionException::class);
+        self::expectExceptionMessage('Class SomeClass does not have a property named ');
+        $reflectionObjectAdapter->setStaticPropertyValue('', '');
+    }
+
     public function testGetStaticPropertyValueThrowsExceptionWhenPropertyDoesNotExist(): void
     {
         $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
@@ -603,6 +653,14 @@ class ReflectionObjectTest extends TestCase
         self::assertEquals([$protectedBetterReflectionClassConstant->getName() => $protectedBetterReflectionClassConstant->getValue()], $protectedConstants);
     }
 
+    public function testHasConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionObject  = $this->createMock(BetterReflectionObject::class);
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::assertFalse($reflectionObjectAdapter->hasConstant(''));
+    }
+
     public function testGetConstant(): void
     {
         $betterReflectionClassConstant = $this->createMock(BetterReflectionClassConstant::class);
@@ -621,6 +679,14 @@ class ReflectionObjectTest extends TestCase
         self::assertSame(123, $reflectionObjectAdapter->getConstant('FOO'));
     }
 
+    public function testGetConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionObject  = $this->createMock(BetterReflectionObject::class);
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::assertFalse($reflectionObjectAdapter->getConstant(''));
+    }
+
     public function testGetConstantReturnsFalseWhenConstantDoesNotExist(): void
     {
         $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
@@ -649,6 +715,14 @@ class ReflectionObjectTest extends TestCase
         self::assertInstanceOf(ReflectionClassConstantAdapter::class, $reflectionObjectAdapter->getReflectionConstant('FOO'));
     }
 
+    public function testGetReflectionConstantReturnsFalseWhenConstantNameIsEmpty(): void
+    {
+        $betterReflectionObject  = $this->createMock(BetterReflectionObject::class);
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::assertFalse($reflectionObjectAdapter->getReflectionConstant(''));
+    }
+
     public function testGetReflectionConstantReturnsFalseWhenConstantDoesNotExist(): void
     {
         $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
@@ -975,6 +1049,28 @@ class ReflectionObjectTest extends TestCase
         $reflectionObjectAdapter->foo;
     }
 
+    public function testHasMethodReturnsFalseWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionObject  = $this->createMock(BetterReflectionObject::class);
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        self::assertFalse($reflectionObjectAdapter->hasMethod(''));
+    }
+
+    public function testGetMethodThrowsExceptionWhenMethodNameIsEmpty(): void
+    {
+        $betterReflectionObject = $this->createMock(BetterReflectionObject::class);
+        $betterReflectionObject
+            ->method('getName')
+            ->willReturn('SomeClass');
+
+        $reflectionObjectAdapter = new ReflectionObjectAdapter($betterReflectionObject);
+
+        $this->expectException(CoreReflectionException::class);
+        $this->expectExceptionMessage('Method SomeClass::() does not exist');
+        $reflectionObjectAdapter->getMethod('');
+    }
+
     public function testGetMethodThrowsExceptionWhenMethodDoesNotExist(): void
     {
         $betterReflectionObject = $this->createMock(BetterReflectionObject::class);