Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a2e5a85

Browse files
committed
Fix TemplateType handling in AbstractObjectNormalizer
1 parent 0158b0e commit a2e5a85

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

Tests/Normalizer/AbstractObjectNormalizerTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
16+
use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor;
1617
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
1718
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
1819
use Symfony\Component\PropertyInfo\Type as LegacyType;
@@ -37,6 +38,7 @@
3738
use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
3839
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
3940
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
41+
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
4042
use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer;
4143
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
4244
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
@@ -1247,6 +1249,52 @@ protected function isAllowedAttribute($classOrObject, string $attribute, ?string
12471249
$this->assertInstanceOf(\ArrayObject::class, $actual->foo);
12481250
$this->assertSame(1, $actual->foo->count());
12491251
}
1252+
1253+
public function testTemplateTypeWhenAnObjectIsPassedToDenormalize()
1254+
{
1255+
$normalizer = new class (
1256+
classMetadataFactory: new ClassMetadataFactory(new AttributeLoader()),
1257+
propertyTypeExtractor: new PropertyInfoExtractor(typeExtractors: [new PhpStanExtractor(), new ReflectionExtractor()])
1258+
) extends AbstractObjectNormalizerDummy {
1259+
protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []): bool
1260+
{
1261+
return true;
1262+
}
1263+
};
1264+
$serializer = new Serializer([$normalizer]);
1265+
$normalizer->setSerializer($serializer);
1266+
1267+
$denormalizedData = $normalizer->denormalize(['value' => new DummyGenericsValue()], DummyGenericsValueWrapper::class);
1268+
1269+
$this->assertInstanceOf(DummyGenericsValueWrapper::class, $denormalizedData);
1270+
$this->assertInstanceOf(DummyGenericsValue::class, $denormalizedData->value);
1271+
1272+
$this->assertSame('dummy', $denormalizedData->value->type);
1273+
}
1274+
1275+
public function testDenormalizeTemplateType()
1276+
{
1277+
$normalizer = new class (
1278+
classMetadataFactory: new ClassMetadataFactory(new AttributeLoader()),
1279+
propertyTypeExtractor: new PropertyInfoExtractor(typeExtractors: [new PhpStanExtractor(), new ReflectionExtractor()])
1280+
) extends AbstractObjectNormalizerDummy {
1281+
protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []): bool
1282+
{
1283+
return true;
1284+
}
1285+
};
1286+
$serializer = new Serializer([new ArrayDenormalizer(), $normalizer]);
1287+
$normalizer->setSerializer($serializer);
1288+
1289+
$denormalizedData = $normalizer->denormalize(['value' => ['type' => 'dummy'], 'values' => [['type' => 'dummy']]], DummyGenericsValueWrapper::class);
1290+
1291+
$this->assertInstanceOf(DummyGenericsValueWrapper::class, $denormalizedData);
1292+
$this->assertInstanceOf(DummyGenericsValue::class, $denormalizedData->value);
1293+
$this->assertContainsOnlyInstancesOf(DummyGenericsValue::class, $denormalizedData->values);
1294+
$this->assertCount(1, $denormalizedData->values);
1295+
$this->assertSame('dummy', $denormalizedData->value->type);
1296+
$this->assertSame('dummy', $denormalizedData->values[0]->type);
1297+
}
12501298
}
12511299

12521300
class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer
@@ -1753,3 +1801,31 @@ public function getSupportedTypes(?string $format): array
17531801
];
17541802
}
17551803
}
1804+
1805+
#[DiscriminatorMap('type', ['dummy' => DummyGenericsValue::class])]
1806+
abstract class AbstractDummyGenericsValue
1807+
{
1808+
public function __construct(
1809+
public string $type,
1810+
) {
1811+
}
1812+
}
1813+
1814+
class DummyGenericsValue extends AbstractDummyGenericsValue
1815+
{
1816+
public function __construct()
1817+
{
1818+
parent::__construct('dummy');
1819+
}
1820+
}
1821+
1822+
/**
1823+
* @template T of AbstractDummyGenericsValue
1824+
*/
1825+
class DummyGenericsValueWrapper
1826+
{
1827+
/** @var T */
1828+
public mixed $value;
1829+
/** @var T[] */
1830+
public array $values;
1831+
}

0 commit comments

Comments
 (0)