From 72ac7ef893a27d328af665a9d9547e2591612b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Birkl=C3=A9?= Date: Sat, 27 Jul 2024 22:34:32 +0200 Subject: [PATCH] Add test for CollectionAnnotationReader cache --- .../CollectionAnnotationReader.php | 52 ++++++++++++------- .../CollectionAnnotationReaderTest.php | 31 +++++++++++ 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/Support/Annotations/CollectionAnnotationReader.php b/src/Support/Annotations/CollectionAnnotationReader.php index 2c08e59a..b14a903f 100644 --- a/src/Support/Annotations/CollectionAnnotationReader.php +++ b/src/Support/Annotations/CollectionAnnotationReader.php @@ -25,6 +25,9 @@ public function __construct( protected Context $context; + /** + * @param class-string $className + */ public function getForClass(string $className): ?CollectionAnnotation { // Check the cache first @@ -33,7 +36,7 @@ public function getForClass(string $className): ?CollectionAnnotation } // Create ReflectionClass from class string - $class = new ReflectionClass($className); + $class = $this->getReflectionClass($className); // Determine if the class is a collection if (! $this->isCollection($class)) { @@ -61,6 +64,36 @@ public function getForClass(string $className): ?CollectionAnnotation return $annotation; } + public static function clearCache(): void + { + self::$cache = []; + } + + /** + * @param class-string $className + */ + protected function getReflectionClass(string $className): ReflectionClass + { + return new ReflectionClass($className); + } + + protected function isCollection(ReflectionClass $class): bool + { + // Check if the class implements common collection interfaces + $collectionInterfaces = [ + Iterator::class, + IteratorAggregate::class, + ]; + + foreach ($collectionInterfaces as $interface) { + if ($class->implementsInterface($interface)) { + return true; + } + } + + return false; + } + /** * @return array{keyType: string|null, valueType: string|null}|null */ @@ -128,23 +161,6 @@ protected function getCollectionReturnType(ReflectionClass $class): ?array return null; } - protected function isCollection(ReflectionClass $class): bool - { - // Check if the class implements common collection interfaces - $collectionInterfaces = [ - Iterator::class, - IteratorAggregate::class, - ]; - - foreach ($collectionInterfaces as $interface) { - if ($class->implementsInterface($interface)) { - return true; - } - } - - return false; - } - protected function resolve(string $type): ?string { $type = (string) $this->typeResolver->resolve($type, $this->context); diff --git a/tests/Support/Annotations/CollectionAnnotationReaderTest.php b/tests/Support/Annotations/CollectionAnnotationReaderTest.php index 09033822..18be76d9 100644 --- a/tests/Support/Annotations/CollectionAnnotationReaderTest.php +++ b/tests/Support/Annotations/CollectionAnnotationReaderTest.php @@ -1,11 +1,17 @@ makePartial(); + + // Call the getForClass method with a test class + $collectionAnnotation = $collectionAnnotationReader->getForClass($className); + + // Call the getForClass method again to test caching + $cachedCollectionAnnotation = $collectionAnnotationReader->getForClass($className); + + // Assert the cache is used and the same annotation is returned + expect($cachedCollectionAnnotation)->toBe($collectionAnnotation); + + // Check if getReflectionClass was called only once + $collectionAnnotationReader->shouldHaveReceived('getReflectionClass')->once(); + +})->with([ + [CollectionWhoImplementsNothing::class], // first return + [CollectionWithoutDocBlock::class], // second return + [DataCollectionWithTemplate::class], // third return +]); /** * @template TKey of array-key