diff --git a/src/Mapping/Factory/MetadataFactory.php b/src/Mapping/Factory/MetadataFactory.php index f6c8b64..56e12de 100644 --- a/src/Mapping/Factory/MetadataFactory.php +++ b/src/Mapping/Factory/MetadataFactory.php @@ -60,7 +60,7 @@ public function getMetadataFor($value): ClassMetadata } if (!class_exists($className)) { - throw new NoSuchMetadataException(sprintf('The class or interface "%s" does not exist.', $className)); + throw new NoSuchMetadataException(sprintf('The class "%s" does not exist.', $className)); } $metadata = new ClassMetadata($className); @@ -77,10 +77,6 @@ public function getMetadataFor($value): ClassMetadata private function mergeLoaders(ClassMetadata $metadata): void { - if ($metadata->getReflectionClass()->isInterface()) { - return; - } - // Include loaders from the parent class if ($parent = $metadata->getReflectionClass()->getParentClass()) { $metadata->mergePropertyLoaders($this->getMetadataFor($parent->name)); diff --git a/tests/Mapping/Factory/MetadataFactoryTest.php b/tests/Mapping/Factory/MetadataFactoryTest.php index a9c94da..4327748 100644 --- a/tests/Mapping/Factory/MetadataFactoryTest.php +++ b/tests/Mapping/Factory/MetadataFactoryTest.php @@ -5,8 +5,10 @@ use Doctrine\Common\Annotations\AnnotationReader; +use Guennichi\PropertyLoader\Exception\NoSuchMetadataException; use Guennichi\PropertyLoader\Mapping\Factory\MetadataFactory; use Guennichi\PropertyLoader\Mapping\Loader\AnnotationLoader; +use Guennichi\PropertyLoader\Mapping\Loader\LoaderInterface; use Guennichi\PropertyLoader\Tests\Fixtures\Child; use PHPUnit\Framework\TestCase; @@ -20,4 +22,50 @@ public function testCreateMetadataWithParentClasses(): void $this->assertCount(2, $metadata->getTargetProperties()); } + + public function testGetSameMetadataObjectIfCalledMoreThanOne(): void + { + $loader = new AnnotationLoader(new AnnotationReader()); + $factory = new MetadataFactory($loader); + + $meta1 = $factory->getMetadataFor(Foo::class); + $meta2 = $factory->getMetadataFor(Foo::class); + + $this->assertTrue($meta1 === $meta2); + } + + public function testThrowExceptionIfNotValidClassnameOrObject(): void + { + $loader = new AnnotationLoader(new AnnotationReader()); + $factory = new MetadataFactory($loader); + + $exceptions = []; + + try { + $factory->getMetadataFor(15); + } catch (NoSuchMetadataException $e) { + $exceptions[] = $e; + } + + try { + $factory->getMetadataFor('foo'); + } catch (NoSuchMetadataException $e) { + $exceptions[] = $e; + } + + $this->assertCount(2, $exceptions); + + $this->assertSame('Cannot create metadata for non-objects. Got: "int"', $exceptions[0]->getMessage()); + $this->assertSame('The class "foo" does not exist.', $exceptions[1]->getMessage()); + } +} + +class Foo +{ + +} + +interface FooInterface +{ + } diff --git a/tests/Mapping/Loader/StaticMethodLoaderTest.php b/tests/Mapping/Loader/StaticMethodLoaderTest.php index 54731f3..9008ac9 100644 --- a/tests/Mapping/Loader/StaticMethodLoaderTest.php +++ b/tests/Mapping/Loader/StaticMethodLoaderTest.php @@ -4,6 +4,7 @@ namespace Guennichi\PropertyLoader\Tests\Mapping\Loader; +use Guennichi\PropertyLoader\Exception\MappingException; use Guennichi\PropertyLoader\Mapping\ClassMetadata; use Guennichi\PropertyLoader\Mapping\Loader\StaticMethodLoader; use Guennichi\PropertyLoader\Tests\Fixtures\Loaders\Gmail; @@ -19,7 +20,7 @@ public function testLoadClassMetadataReturnsTrueIfSuccessful(): void $this->assertTrue($loader->loadClassMetadata($metadata)); } - public function testLoadClassMetadataReturnsFalseIfNotSuccessful() + public function testLoadClassMetadataReturnsFalseIfNotSuccessful(): void { $loader = new StaticMethodLoader('loadMetadata'); $metadata = new ClassMetadata('\stdClass'); @@ -27,7 +28,7 @@ public function testLoadClassMetadataReturnsFalseIfNotSuccessful() $this->assertFalse($loader->loadClassMetadata($metadata)); } - public function testLoadClassMetadata() + public function testLoadClassMetadata(): void { $loader = new StaticMethodLoader('loadMetadata'); $metadata = new ClassMetadata(StaticLoaderEntity::class); @@ -38,7 +39,7 @@ public function testLoadClassMetadata() } - public function testLoadClassMetadataDoesNotRepeatLoadWithParentClasses() + public function testLoadClassMetadataDoesNotRepeatLoadWithParentClasses(): void { $loader = new StaticMethodLoader('loadMetadata'); $metadata = new ClassMetadata(StaticLoaderDocument::class); @@ -51,7 +52,7 @@ public function testLoadClassMetadataDoesNotRepeatLoadWithParentClasses() $this->assertCount(1, $metadata->getTargetProperties()); } - public function testLoadClassMetadataIgnoresInterfaces() + public function testLoadClassMetadataIgnoresInterfaces(): void { $loader = new StaticMethodLoader('loadMetadata'); $metadata = new ClassMetadata(StaticLoaderInterface::class); @@ -61,7 +62,7 @@ public function testLoadClassMetadataIgnoresInterfaces() $this->assertCount(0, $metadata->getTargetProperties()); } - public function testLoadClassMetadataInAbstractClasses() + public function testLoadClassMetadataInAbstractClasses(): void { $loader = new StaticMethodLoader('loadMetadata'); $metadata = new ClassMetadata(AbstractStaticLoader::class); @@ -70,6 +71,25 @@ public function testLoadClassMetadataInAbstractClasses() $this->assertCount(1, $metadata->getTargetProperties()); } + + public function testLoadClassMetadataInNonStaticMethods(): void + { + $loader = new StaticMethodLoader('loadMetadata'); + $metadata = new ClassMetadata(NonStaticLoaderEntity::class); + + $this->expectException(MappingException::class); + $this->expectExceptionMessage('The method "Guennichi\PropertyLoader\Tests\Mapping\Loader\NonStaticLoaderEntity::loadMetadata()" should be static.'); + + $loader->loadClassMetadata($metadata); + } + + public function testLoadClassMetadataInAbstractStaticMethods(): void + { + $loader = new StaticMethodLoader('loadMetadata'); + $metadata = new ClassMetadata(AbstractMethodStaticLoader::class); + + $this->assertFalse($loader->loadClassMetadata($metadata)); + } } interface StaticLoaderInterface @@ -79,17 +99,32 @@ public static function loadMetadata(ClassMetadata $metadata); abstract class AbstractStaticLoader { - public static function loadMetadata(ClassMetadata $metadata) + public static function loadMetadata(ClassMetadata $metadata): void { $metadata->addPropertyLoader('foo', new Gmail()); } } +class NonStaticLoaderEntity +{ + public static ?ClassMetadata $invokedWith = null; + + public function loadMetadata(ClassMetadata $metadata): void + { + self::$invokedWith = $metadata; + } +} + +abstract class AbstractMethodStaticLoader +{ + public abstract static function loadMetadata(ClassMetadata $metadata): void; +} + class StaticLoaderEntity { public static ?ClassMetadata $invokedWith = null; - public static function loadMetadata(ClassMetadata $metadata) + public static function loadMetadata(ClassMetadata $metadata): void { self::$invokedWith = $metadata; }