Skip to content

Commit

Permalink
bug #14415 [Serializer] Fix a bug when using groups together with a n…
Browse files Browse the repository at this point in the history
…ame converter (dunglas)

This PR was squashed before being merged into the 2.7 branch (closes #14415).

Discussion
----------

[Serializer] Fix a bug when using groups together with a name converter

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

* Fix the bug
* Increase test coverage

Commits
-------

454ef8c [Serializer] Fix a bug when using groups together with a name converter
  • Loading branch information
fabpot committed Apr 27, 2015
2 parents f85ba5d + 454ef8c commit 09cde7c
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 14 deletions.
Expand Up @@ -58,7 +58,6 @@ public function normalize($object, $format = null, array $context = array())
foreach ($reflectionMethods as $method) {
if ($this->isGetMethod($method)) {
$attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3));

if (in_array($attributeName, $this->ignoredAttributes)) {
continue;
}
Expand Down Expand Up @@ -104,14 +103,14 @@ public function denormalize($data, $class, $format = null, array $context = arra
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);

foreach ($normalizedData as $attribute => $value) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->denormalize($attribute);
}

$allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes);
$ignored = in_array($attribute, $this->ignoredAttributes);

if ($allowed && !$ignored) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->denormalize($attribute);
}

$setter = 'set'.ucfirst($attribute);

if (method_exists($object, $setter)) {
Expand Down
Expand Up @@ -141,14 +141,14 @@ public function denormalize($data, $class, $format = null, array $context = arra
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);

foreach ($normalizedData as $attribute => $value) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->denormalize($attribute);
}

$allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes);
$ignored = in_array($attribute, $this->ignoredAttributes);

if ($allowed && !$ignored) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->normalize($attribute);
}

try {
$this->propertyAccessor->setValue($object, $attribute, $value);
} catch (NoSuchPropertyException $exception) {
Expand Down
Expand Up @@ -22,6 +22,9 @@ class GroupDummy extends GroupDummyParent implements GroupDummyInterface
* @Groups({"a"})
*/
private $foo;
/**
* @Groups({"b", "c", "name_converter"})
*/
protected $bar;
private $fooBar;
private $symfony;
Expand Down Expand Up @@ -58,7 +61,7 @@ public function setFooBar($fooBar)
}

/**
* @Groups({"a", "b"})
* @Groups({"a", "b", "name_converter"})
*/
public function isFooBar()
{
Expand Down
Expand Up @@ -19,7 +19,7 @@
interface GroupDummyInterface
{
/**
* @Groups({"a"})
* @Groups({"a", "name_converter"})
*/
public function getSymfony();
}
Expand Up @@ -30,11 +30,13 @@ public static function createClassMetadata($withParent = false, $withInterface =
$bar = new AttributeMetadata('bar');
$bar->addGroup('b');
$bar->addGroup('c');
$bar->addGroup('name_converter');
$expected->addAttributeMetadata($bar);

$fooBar = new AttributeMetadata('fooBar');
$fooBar->addGroup('a');
$fooBar->addGroup('b');
$fooBar->addGroup('name_converter');
$expected->addAttributeMetadata($fooBar);

$symfony = new AttributeMetadata('symfony');
Expand All @@ -53,6 +55,7 @@ public static function createClassMetadata($withParent = false, $withInterface =

if ($withInterface) {
$symfony->addGroup('a');
$symfony->addGroup('name_converter');
}

// load reflection class so that the comparison passes
Expand Down
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Serializer\Tests\Normalizer;

use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
Expand Down Expand Up @@ -115,6 +116,16 @@ public function testLegacyDenormalizeOnCamelCaseFormat()
$this->assertEquals('camelCase', $obj->getCamelCase());
}

public function testNameConverterSupport()
{
$this->normalizer = new GetSetMethodNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
$obj = $this->normalizer->denormalize(
array('camel_case' => 'camelCase'),
__NAMESPACE__.'\GetSetDummy'
);
$this->assertEquals('camelCase', $obj->getCamelCase());
}

public function testDenormalizeNull()
{
$this->assertEquals(new GetSetDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\GetSetDummy'));
Expand Down Expand Up @@ -262,6 +273,48 @@ public function testGroupsDenormalize()
$this->assertEquals($obj, $normalized);
}

public function testGroupsNormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');
$obj->setCoopTilleuls('les-tilleuls.coop');

$this->assertEquals(
array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
),
$this->normalizer->normalize($obj, null, array('groups' => array('name_converter')))
);
}

public function testGroupsDenormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new GetSetMethodNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');

$this->assertEquals(
$obj,
$this->normalizer->denormalize(array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
'coop_tilleuls' => 'les-tilleuls.coop',
), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter')))
);
}

/**
* @dataProvider provideCallbacks
*/
Expand Down
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Serializer\Tests\Normalizer;

use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
Expand Down Expand Up @@ -111,6 +112,16 @@ public function testLegacyDenormalizeOnCamelCaseFormat()
$this->assertEquals('camelCase', $obj->getCamelCase());
}

public function testNameConverterSupport()
{
$this->normalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
$obj = $this->normalizer->denormalize(
array('camel_case' => 'camelCase'),
__NAMESPACE__.'\ObjectDummy'
);
$this->assertEquals('camelCase', $obj->getCamelCase());
}

public function testDenormalizeNull()
{
$this->assertEquals(new ObjectDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\ObjectDummy'));
Expand Down Expand Up @@ -206,6 +217,48 @@ public function testGroupsDenormalize()
$this->assertEquals($obj, $normalized);
}

public function testGroupsNormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');
$obj->setCoopTilleuls('les-tilleuls.coop');

$this->assertEquals(
array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
),
$this->normalizer->normalize($obj, null, array('groups' => array('name_converter')))
);
}

public function testGroupsDenormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');

$this->assertEquals(
$obj,
$this->normalizer->denormalize(array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
'coop_tilleuls' => 'les-tilleuls.coop',
), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter')))
);
}

/**
* @dataProvider provideCallbacks
*/
Expand Down Expand Up @@ -423,7 +476,7 @@ public function setCamelCase($camelCase)

public function otherMethod()
{
throw new \RuntimeException("Dummy::otherMethod() should not be called");
throw new \RuntimeException('Dummy::otherMethod() should not be called');
}

public function setObject($object)
Expand Down Expand Up @@ -462,7 +515,7 @@ public function isBaz()

public function otherMethod()
{
throw new \RuntimeException("Dummy::otherMethod() should not be called");
throw new \RuntimeException('Dummy::otherMethod() should not be called');
}
}

Expand Down Expand Up @@ -495,6 +548,6 @@ public function getBaz()

public function otherMethod()
{
throw new \RuntimeException("Dummy::otherMethod() should not be called");
throw new \RuntimeException('Dummy::otherMethod() should not be called');
}
}
Expand Up @@ -14,6 +14,7 @@
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
Expand Down Expand Up @@ -129,6 +130,16 @@ public function testLegacyCamelizedAttributesDenormalize()
), __NAMESPACE__.'\PropertyCamelizedDummy'), $obj);
}

public function testNameConverterSupport()
{
$this->normalizer = new PropertyNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
$obj = $this->normalizer->denormalize(
array('camel_case' => 'camelCase'),
__NAMESPACE__.'\PropertyDummy'
);
$this->assertEquals('camelCase', $obj->getCamelCase());
}

public function testConstructorDenormalize()
{
$obj = $this->normalizer->denormalize(
Expand Down Expand Up @@ -239,6 +250,48 @@ public function testGroupsDenormalize()
$this->assertEquals($obj, $normalized);
}

public function testGroupsNormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');
$obj->setCoopTilleuls('les-tilleuls.coop');

$this->assertEquals(
array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
),
$this->normalizer->normalize($obj, null, array('groups' => array('name_converter')))
);
}

public function testGroupsDenormalizeWithNameConverter()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
$this->normalizer->setSerializer($this->serializer);

$obj = new GroupDummy();
$obj->setFooBar('@dunglas');
$obj->setSymfony('@coopTilleuls');

$this->assertEquals(
$obj,
$this->normalizer->denormalize(array(
'bar' => null,
'foo_bar' => '@dunglas',
'symfony' => '@coopTilleuls',
'coop_tilleuls' => 'les-tilleuls.coop',
), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array('groups' => array('name_converter')))
);
}

public function provideCallbacks()
{
return array(
Expand Down

0 comments on commit 09cde7c

Please sign in to comment.