X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fsymfony%2Fserializer%2FTests%2FNormalizer%2FObjectNormalizerTest.php;h=005dfe92f90b4004a438038df667eef14860b3da;hp=1f735cc243b94f6e82799018544c601b2ba86892;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php b/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php index 1f735cc24..005dfe92f 100644 --- a/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/vendor/symfony/serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -13,12 +13,18 @@ namespace Symfony\Component\Serializer\Tests\Normalizer; use Doctrine\Common\Annotations\AnnotationReader; use PHPUnit\Framework\TestCase; +use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; +use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; +use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; +use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy; +use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy; use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder; use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; @@ -98,29 +104,6 @@ class ObjectNormalizerTest extends TestCase $this->assertEquals('bar', $obj->bar); } - /** - * @group legacy - */ - public function testLegacyDenormalizeOnCamelCaseFormat() - { - $this->normalizer->setCamelizedAttributes(array('camel_case')); - $obj = $this->normalizer->denormalize( - array('camel_case' => 'camelCase'), - __NAMESPACE__.'\ObjectDummy' - ); - $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')); @@ -156,11 +139,6 @@ class ObjectNormalizerTest extends TestCase $this->assertEquals(array(1, 2, 3), $obj->getBaz()); } - /** - * @see https://bugs.php.net/62715 - * - * @requires PHP 5.3.17 - */ public function testConstructorDenormalizeWithOptionalDefaultArgument() { $obj = $this->normalizer->denormalize( @@ -182,6 +160,49 @@ class ObjectNormalizerTest extends TestCase $this->assertEquals('bar', $obj->bar); } + public function testConstructorWithObjectTypeHintDenormalize() + { + $data = array( + 'id' => 10, + 'inner' => array( + 'foo' => 'oof', + 'bar' => 'rab', + ), + ); + + $normalizer = new ObjectNormalizer(); + $serializer = new Serializer(array($normalizer)); + $normalizer->setSerializer($serializer); + + $obj = $normalizer->denormalize($data, DummyWithConstructorObject::class); + $this->assertInstanceOf(DummyWithConstructorObject::class, $obj); + $this->assertEquals(10, $obj->getId()); + $this->assertInstanceOf(ObjectInner::class, $obj->getInner()); + $this->assertEquals('oof', $obj->getInner()->foo); + $this->assertEquals('rab', $obj->getInner()->bar); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\RuntimeException + * @expectedExceptionMessage Could not determine the class of the parameter "unknown". + */ + public function testConstructorWithUnknownObjectTypeHintDenormalize() + { + $data = array( + 'id' => 10, + 'unknown' => array( + 'foo' => 'oof', + 'bar' => 'rab', + ), + ); + + $normalizer = new ObjectNormalizer(); + $serializer = new Serializer(array($normalizer)); + $normalizer->setSerializer($serializer); + + $normalizer->denormalize($data, DummyWithConstructorInexistingObject::class); + } + public function testGroupsNormalize() { $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); @@ -413,7 +434,7 @@ class ObjectNormalizerTest extends TestCase /** * @expectedException \Symfony\Component\Serializer\Exception\LogicException - * @expectedExceptionMessage Cannot normalize attribute "object" because injected serializer is not a normalizer + * @expectedExceptionMessage Cannot normalize attribute "object" because the injected serializer is not a normalizer */ public function testUnableToNormalizeObjectAttribute() { @@ -505,7 +526,128 @@ class ObjectNormalizerTest extends TestCase 'bar' => null, ); - $this->assertEquals($expected, $this->normalizer->normalize($objectDummy, null, array('not_serializable' => function () {}))); + $this->assertEquals($expected, $this->normalizer->normalize($objectDummy, null, array('not_serializable' => function () { + }))); + } + + public function testMaxDepth() + { + $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); + $this->normalizer = new ObjectNormalizer($classMetadataFactory); + $serializer = new Serializer(array($this->normalizer)); + $this->normalizer->setSerializer($serializer); + + $level1 = new MaxDepthDummy(); + $level1->foo = 'level1'; + + $level2 = new MaxDepthDummy(); + $level2->foo = 'level2'; + $level1->child = $level2; + + $level3 = new MaxDepthDummy(); + $level3->foo = 'level3'; + $level2->child = $level3; + + $result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true)); + + $expected = array( + 'bar' => null, + 'foo' => 'level1', + 'child' => array( + 'bar' => null, + 'foo' => 'level2', + 'child' => array( + 'bar' => null, + 'child' => null, + ), + ), + ); + + $this->assertEquals($expected, $result); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + */ + public function testThrowUnexpectedValueException() + { + $this->normalizer->denormalize(array('foo' => 'bar'), ObjectTypeHinted::class); + } + + public function testDenomalizeRecursive() + { + $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor())); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer)); + + $obj = $serializer->denormalize(array( + 'inner' => array('foo' => 'foo', 'bar' => 'bar'), + 'date' => '1988/01/21', + 'inners' => array(array('foo' => 1), array('foo' => 2)), + ), ObjectOuter::class); + + $this->assertSame('foo', $obj->getInner()->foo); + $this->assertSame('bar', $obj->getInner()->bar); + $this->assertSame('1988-01-21', $obj->getDate()->format('Y-m-d')); + $this->assertSame(1, $obj->getInners()[0]->foo); + $this->assertSame(2, $obj->getInners()[1]->foo); + } + + public function testAcceptJsonNumber() + { + $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor())); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer)); + + $this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'json')->number); + $this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'jsonld')->number); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + * @expectedExceptionMessage The type of the "date" attribute for class "Symfony\Component\Serializer\Tests\Normalizer\ObjectOuter" must be one of "DateTimeInterface" ("string" given). + */ + public function testRejectInvalidType() + { + $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor()); + $serializer = new Serializer(array($normalizer)); + + $serializer->denormalize(array('date' => 'foo'), ObjectOuter::class); + } + + /** + * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException + * @expectedExceptionMessage The type of the key "a" must be "int" ("string" given). + */ + public function testRejectInvalidKey() + { + $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor())); + $normalizer = new ObjectNormalizer(null, null, null, $extractor); + $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer)); + + $serializer->denormalize(array('inners' => array('a' => array('foo' => 1))), ObjectOuter::class); + } + + public function testExtractAttributesRespectsFormat() + { + $normalizer = new FormatAndContextAwareNormalizer(); + + $data = new ObjectDummy(); + $data->setFoo('bar'); + $data->bar = 'foo'; + + $this->assertSame(array('foo' => 'bar', 'bar' => 'foo'), $normalizer->normalize($data, 'foo_and_bar_included')); + } + + public function testExtractAttributesRespectsContext() + { + $normalizer = new FormatAndContextAwareNormalizer(); + + $data = new ObjectDummy(); + $data->setFoo('bar'); + $data->bar = 'foo'; + + $this->assertSame(array('foo' => 'bar', 'bar' => 'foo'), $normalizer->normalize($data, null, array('include_foo_and_bar' => true))); } } @@ -668,6 +810,113 @@ class ObjectWithStaticPropertiesAndMethods } } +class ObjectTypeHinted +{ + public function setFoo(array $f) + { + } +} + +class ObjectOuter +{ + private $inner; + private $date; + + /** + * @var ObjectInner[] + */ + private $inners; + + public function getInner() + { + return $this->inner; + } + + public function setInner(ObjectInner $inner) + { + $this->inner = $inner; + } + + public function setDate(\DateTimeInterface $date) + { + $this->date = $date; + } + + public function getDate() + { + return $this->date; + } + + public function setInners(array $inners) + { + $this->inners = $inners; + } + + public function getInners() + { + return $this->inners; + } +} + +class ObjectInner +{ + public $foo; + public $bar; +} + +class FormatAndContextAwareNormalizer extends ObjectNormalizer +{ + protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array()) + { + if (in_array($attribute, array('foo', 'bar')) && 'foo_and_bar_included' === $format) { + return true; + } + + if (in_array($attribute, array('foo', 'bar')) && isset($context['include_foo_and_bar']) && true === $context['include_foo_and_bar']) { + return true; + } + + return false; + } +} + +class DummyWithConstructorObject +{ + private $id; + private $inner; + + public function __construct($id, ObjectInner $inner) + { + $this->id = $id; + $this->inner = $inner; + } + + public function getId() + { + return $this->id; + } + + public function getInner() + { + return $this->inner; + } +} + +class DummyWithConstructorInexistingObject +{ + public function __construct($id, Unknown $unknown) + { + } +} + +class JsonNumber +{ + /** + * @var float + */ + public $number; +} + class ObjectWithUpperCaseAttributeNames { private $Foo = 'Foo';