Skip to content

Commit

Permalink
bug #37845 [Serializer] Fix variadic support when using type hints (f…
Browse files Browse the repository at this point in the history
…abpot)

This PR was merged into the 3.4 branch.

Discussion
----------

[Serializer] Fix variadic support when using type hints

| Q             | A
| ------------- | ---
| Branch?       | 3.4 <!-- see below -->
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | n/a <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead -->
| License       | MIT
| Doc PR        | n/a

Commits
-------

3fffa96928 [Serializer] Fix variadic support when using type hints
  • Loading branch information
fabpot committed Aug 16, 2020
2 parents fff4cb2 + 95a84bb commit e3e34e8
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Normalizer/AbstractObjectNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ private function validateAndDenormalize($currentClass, $attribute, $data, $forma
*/
protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, $parameterName, $parameterData, array $context, $format = null)
{
if (null === $this->propertyTypeExtractor || null === $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) {
if ((method_exists($parameter, 'isVariadic') && $parameter->isVariadic()) || null === $this->propertyTypeExtractor || null === $this->propertyTypeExtractor->getTypes($class->getName(), $parameterName)) {
return parent::denormalizeParameter($class, $parameter, $parameterName, $parameterData, $context, $format);
}

Expand Down
1 change: 1 addition & 0 deletions Tests/Fixtures/VariadicConstructorTypedArgsDummy.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public function __construct(Dummy ...$foo)
$this->foo = $foo;
}

/** @return Dummy[] */
public function getFoo()
{
return $this->foo;
Expand Down
42 changes: 37 additions & 5 deletions Tests/Normalizer/AbstractNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Mapping\AttributeMetadata;
use Symfony\Component\Serializer\Mapping\ClassMetadata;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
Expand Down Expand Up @@ -135,19 +137,49 @@ public function testObjectWithNullableConstructorArgument()
}

/**
* @dataProvider getNormalizer
*
* @requires PHP 5.6
*/
public function testObjectWithVariadicConstructorTypedArguments()
public function testObjectWithVariadicConstructorTypedArguments(AbstractNormalizer $normalizer)
{
$normalizer = new PropertyNormalizer();
$normalizer->setSerializer(new Serializer([$normalizer]));
$data = ['foo' => [['foo' => 'Foo', 'bar' => 'Bar', 'baz' => 'Baz', 'qux' => 'Qux'], ['foo' => 'FOO', 'bar' => 'BAR', 'baz' => 'BAZ', 'qux' => 'QUX']]];
$dummy = $normalizer->denormalize($data, VariadicConstructorTypedArgsDummy::class);
$d1 = new Dummy();
$d1->foo = 'Foo';
$d1->bar = 'Bar';
$d1->baz = 'Baz';
$d1->qux = 'Quz';
$d2 = new Dummy();
$d2->foo = 'FOO';
$d2->bar = 'BAR';
$d2->baz = 'BAZ';
$d2->qux = 'QUZ';
$obj = new VariadicConstructorTypedArgsDummy($d1, $d2);

$serializer = new Serializer([$normalizer], [new JsonEncoder()]);
$normalizer->setSerializer($serializer);
$data = $serializer->serialize($obj, 'json');
$dummy = $normalizer->denormalize(json_decode($data, true), VariadicConstructorTypedArgsDummy::class);
$this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy);
$this->assertCount(2, $dummy->getFoo());
foreach ($dummy->getFoo() as $foo) {
$this->assertInstanceOf(Dummy::class, $foo);
}

$dummy = $serializer->deserialize($data, VariadicConstructorTypedArgsDummy::class, 'json');
$this->assertInstanceOf(VariadicConstructorTypedArgsDummy::class, $dummy);
$this->assertCount(2, $dummy->getFoo());
foreach ($dummy->getFoo() as $foo) {
$this->assertInstanceOf(Dummy::class, $foo);
}
}

public function getNormalizer()
{
$extractor = new PhpDocExtractor();

yield [new PropertyNormalizer()];
yield [new PropertyNormalizer(null, null, $extractor)];
yield [new ObjectNormalizer()];
yield [new ObjectNormalizer(null, null, null, $extractor)];
}
}

0 comments on commit e3e34e8

Please sign in to comment.