mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Fix serializing collection with intersection types
This commit is contained in:
parent
711cdc3481
commit
bad3cdca09
@ -96,7 +96,10 @@ class DocGenObjectNormalizer implements NormalizerAwareInterface, NormalizerInte
|
||||
return 'docgen' === $format && (is_object($data) || null === $data);
|
||||
}
|
||||
|
||||
private function getExpectedType(AttributeMetadata $attribute, ReflectionClass $reflection): string
|
||||
/**
|
||||
* @return string|array<string>
|
||||
*/
|
||||
private function getExpectedType(AttributeMetadata $attribute, ReflectionClass $reflection): string|array
|
||||
{
|
||||
$type = null;
|
||||
|
||||
@ -147,14 +150,31 @@ class DocGenObjectNormalizer implements NormalizerAwareInterface, NormalizerInte
|
||||
}
|
||||
} while (null === $type && $reflection instanceof ReflectionClass);
|
||||
|
||||
if (null === $type ?? null) {
|
||||
if ($type instanceof \ReflectionNamedType) {
|
||||
return $type->getName();
|
||||
}
|
||||
if ($type instanceof \ReflectionIntersectionType) {
|
||||
foreach (array_map(fn (\ReflectionNamedType $t) => $t->getName(), $type->getTypes()) as $classString) {
|
||||
if (ReadableCollection::class === $classString) {
|
||||
return ReadableCollection::class;
|
||||
}
|
||||
|
||||
$class = new ReflectionClass($classString);
|
||||
|
||||
if ($class->implementsInterface(ReadableCollection::class)) {
|
||||
return ReadableCollection::class;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \LogicException(sprintf("The automatic normalization of intersection types is not supported, unless a %s is contained in the intersected types", ReadableCollection::class));
|
||||
} elseif (null === $type ?? null) {
|
||||
throw new \LogicException(sprintf(
|
||||
'Could not determine the type for this attribute: %s. Add a return type to the method or property declaration',
|
||||
$attribute->getName()
|
||||
));
|
||||
}
|
||||
|
||||
return $type->getName();
|
||||
throw new \LogicException(sprintf("The automatic normalization of %s is not supported", $type::class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,10 @@ namespace Chill\DocGeneratorBundle\tests\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\ReadableCollection;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
|
||||
@ -28,7 +32,6 @@ final class DocGenObjectNormalizerTest extends KernelTestCase
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
self::bootKernel();
|
||||
|
||||
$this->normalizer = self::$container->get(NormalizerInterface::class);
|
||||
@ -171,6 +174,64 @@ final class DocGenObjectNormalizerTest extends KernelTestCase
|
||||
|
||||
$this->assertEquals($expected, $normalized, 'test normalization fo an user with null center');
|
||||
}
|
||||
|
||||
public function testIntersectionTypeForReadableCollection(): void
|
||||
{
|
||||
$value = new TestableWithIntersectionReadableCollection();
|
||||
|
||||
$normalized = $this->normalizer->normalize($value, 'docgen', [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => TestableWithIntersectionReadableCollection::class]);
|
||||
|
||||
self::assertIsArray($normalized);
|
||||
self::assertIsArray($normalized['collection']);
|
||||
self::assertCount(2, $normalized['collection']);
|
||||
|
||||
self::assertEquals(
|
||||
['baz' => 'bloup', 'isNull' => false],
|
||||
$normalized['collection'][0]
|
||||
);
|
||||
self::assertEquals(
|
||||
['baz' => 'bloup', 'isNull' => false],
|
||||
$normalized['collection'][1]
|
||||
);
|
||||
}
|
||||
|
||||
public function testIntersectionTypeForReadableCollectionWithNullValue(): void
|
||||
{
|
||||
$normalized = $this->normalizer->normalize(null, 'docgen', [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => TestableWithIntersectionReadableCollection::class]);
|
||||
|
||||
self::assertIsArray($normalized);
|
||||
self::assertIsArray($normalized['collection']);
|
||||
self::assertCount(0, $normalized['collection']);
|
||||
}
|
||||
|
||||
public function testIntersectionTypeForCollection(): void
|
||||
{
|
||||
$value = new TestableWithCollection();
|
||||
|
||||
$normalized = $this->normalizer->normalize($value, 'docgen', [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => TestableWithCollection::class]);
|
||||
|
||||
self::assertIsArray($normalized);
|
||||
self::assertIsArray($normalized['collection']);
|
||||
self::assertCount(2, $normalized['collection']);
|
||||
|
||||
self::assertEquals(
|
||||
['baz' => 'bloup', 'isNull' => false],
|
||||
$normalized['collection'][0]
|
||||
);
|
||||
self::assertEquals(
|
||||
['baz' => 'bloup', 'isNull' => false],
|
||||
$normalized['collection'][1]
|
||||
);
|
||||
}
|
||||
|
||||
public function testIntersectionTypeForCollectionWithNullValue(): void
|
||||
{
|
||||
$normalized = $this->normalizer->normalize(null, 'docgen', [AbstractNormalizer::GROUPS => ['docgen:read'], 'docgen:expects' => TestableWithCollection::class]);
|
||||
|
||||
self::assertIsArray($normalized);
|
||||
self::assertIsArray($normalized['collection']);
|
||||
self::assertCount(0, $normalized['collection']);
|
||||
}
|
||||
}
|
||||
|
||||
class TestableParentClass
|
||||
@ -215,3 +276,29 @@ class TestableClassWithBool
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TestableWithIntersectionReadableCollection
|
||||
{
|
||||
/**
|
||||
* @Serializer\Groups("docgen:read")
|
||||
*/
|
||||
public ReadableCollection&Selectable $collection;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->collection = new ArrayCollection([new TestableChildClass(), new TestableChildClass()]);
|
||||
}
|
||||
}
|
||||
|
||||
class TestableWithCollection
|
||||
{
|
||||
/**
|
||||
* @Serializer\Groups("docgen:read")
|
||||
*/
|
||||
public Collection&Selectable $collection;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->collection = new ArrayCollection([new TestableChildClass(), new TestableChildClass()]);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user