Fix bug in style changes for the Use cases on the live site.
[yaffs-website] / vendor / symfony / serializer / Tests / Normalizer / PropertyNormalizerTest.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\Serializer\Tests\Normalizer;
13
14 use Doctrine\Common\Annotations\AnnotationReader;
15 use PHPUnit\Framework\TestCase;
16 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
17 use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
18 use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
19 use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
20 use Symfony\Component\Serializer\Serializer;
21 use Symfony\Component\Serializer\SerializerInterface;
22 use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
23 use Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy;
24 use Symfony\Component\Serializer\Tests\Fixtures\PropertySiblingHolder;
25
26 class PropertyNormalizerTest extends TestCase
27 {
28     /**
29      * @var PropertyNormalizer
30      */
31     private $normalizer;
32     /**
33      * @var SerializerInterface
34      */
35     private $serializer;
36
37     protected function setUp()
38     {
39         $this->serializer = $this->getMockBuilder('Symfony\Component\Serializer\SerializerInterface')->getMock();
40         $this->normalizer = new PropertyNormalizer();
41         $this->normalizer->setSerializer($this->serializer);
42     }
43
44     public function testNormalize()
45     {
46         $obj = new PropertyDummy();
47         $obj->foo = 'foo';
48         $obj->setBar('bar');
49         $obj->setCamelCase('camelcase');
50         $this->assertEquals(
51             array('foo' => 'foo', 'bar' => 'bar', 'camelCase' => 'camelcase'),
52             $this->normalizer->normalize($obj, 'any')
53         );
54     }
55
56     public function testDenormalize()
57     {
58         $obj = $this->normalizer->denormalize(
59             array('foo' => 'foo', 'bar' => 'bar'),
60             __NAMESPACE__.'\PropertyDummy',
61             'any'
62         );
63         $this->assertEquals('foo', $obj->foo);
64         $this->assertEquals('bar', $obj->getBar());
65     }
66
67     /**
68      * @group legacy
69      */
70     public function testLegacyDenormalizeOnCamelCaseFormat()
71     {
72         $this->normalizer->setCamelizedAttributes(array('camel_case'));
73         $obj = $this->normalizer->denormalize(
74             array('camel_case' => 'value'),
75             __NAMESPACE__.'\PropertyDummy'
76         );
77         $this->assertEquals('value', $obj->getCamelCase());
78     }
79
80     /**
81      * @group legacy
82      */
83     public function testLegacyCamelizedAttributesNormalize()
84     {
85         $obj = new PropertyCamelizedDummy('dunglas.fr');
86         $obj->fooBar = 'les-tilleuls.coop';
87         $obj->bar_foo = 'lostinthesupermarket.fr';
88
89         $this->normalizer->setCamelizedAttributes(array('kevin_dunglas'));
90         $this->assertEquals($this->normalizer->normalize($obj), array(
91             'kevin_dunglas' => 'dunglas.fr',
92             'fooBar' => 'les-tilleuls.coop',
93             'bar_foo' => 'lostinthesupermarket.fr',
94         ));
95
96         $this->normalizer->setCamelizedAttributes(array('foo_bar'));
97         $this->assertEquals($this->normalizer->normalize($obj), array(
98             'kevinDunglas' => 'dunglas.fr',
99             'foo_bar' => 'les-tilleuls.coop',
100             'bar_foo' => 'lostinthesupermarket.fr',
101         ));
102     }
103
104     /**
105      * @group legacy
106      */
107     public function testLegacyCamelizedAttributesDenormalize()
108     {
109         $obj = new PropertyCamelizedDummy('dunglas.fr');
110         $obj->fooBar = 'les-tilleuls.coop';
111         $obj->bar_foo = 'lostinthesupermarket.fr';
112
113         $this->normalizer->setCamelizedAttributes(array('kevin_dunglas'));
114         $this->assertEquals($this->normalizer->denormalize(array(
115             'kevin_dunglas' => 'dunglas.fr',
116             'fooBar' => 'les-tilleuls.coop',
117             'bar_foo' => 'lostinthesupermarket.fr',
118         ), __NAMESPACE__.'\PropertyCamelizedDummy'), $obj);
119
120         $this->normalizer->setCamelizedAttributes(array('foo_bar'));
121         $this->assertEquals($this->normalizer->denormalize(array(
122             'kevinDunglas' => 'dunglas.fr',
123             'foo_bar' => 'les-tilleuls.coop',
124             'bar_foo' => 'lostinthesupermarket.fr',
125         ), __NAMESPACE__.'\PropertyCamelizedDummy'), $obj);
126     }
127
128     public function testNameConverterSupport()
129     {
130         $this->normalizer = new PropertyNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
131         $obj = $this->normalizer->denormalize(
132             array('camel_case' => 'camelCase'),
133             __NAMESPACE__.'\PropertyDummy'
134         );
135         $this->assertEquals('camelCase', $obj->getCamelCase());
136     }
137
138     public function testConstructorDenormalize()
139     {
140         $obj = $this->normalizer->denormalize(
141             array('foo' => 'foo', 'bar' => 'bar'),
142             __NAMESPACE__.'\PropertyConstructorDummy',
143             'any'
144         );
145         $this->assertEquals('foo', $obj->getFoo());
146         $this->assertEquals('bar', $obj->getBar());
147     }
148
149     public function testConstructorDenormalizeWithNullArgument()
150     {
151         $obj = $this->normalizer->denormalize(
152             array('foo' => null, 'bar' => 'bar'),
153             __NAMESPACE__.'\PropertyConstructorDummy', '
154             any'
155         );
156         $this->assertNull($obj->getFoo());
157         $this->assertEquals('bar', $obj->getBar());
158     }
159
160     /**
161      * @dataProvider provideCallbacks
162      */
163     public function testCallbacks($callbacks, $value, $result, $message)
164     {
165         $this->normalizer->setCallbacks($callbacks);
166
167         $obj = new PropertyConstructorDummy('', $value);
168
169         $this->assertEquals(
170             $result,
171             $this->normalizer->normalize($obj, 'any'),
172             $message
173         );
174     }
175
176     /**
177      * @expectedException \InvalidArgumentException
178      */
179     public function testUncallableCallbacks()
180     {
181         $this->normalizer->setCallbacks(array('bar' => null));
182
183         $obj = new PropertyConstructorDummy('baz', 'quux');
184
185         $this->normalizer->normalize($obj, 'any');
186     }
187
188     public function testIgnoredAttributes()
189     {
190         $this->normalizer->setIgnoredAttributes(array('foo', 'bar', 'camelCase'));
191
192         $obj = new PropertyDummy();
193         $obj->foo = 'foo';
194         $obj->setBar('bar');
195
196         $this->assertEquals(
197             array(),
198             $this->normalizer->normalize($obj, 'any')
199         );
200     }
201
202     public function testGroupsNormalize()
203     {
204         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
205         $this->normalizer = new PropertyNormalizer($classMetadataFactory);
206         $this->normalizer->setSerializer($this->serializer);
207
208         $obj = new GroupDummy();
209         $obj->setFoo('foo');
210         $obj->setBar('bar');
211         $obj->setFooBar('fooBar');
212         $obj->setSymfony('symfony');
213         $obj->setKevin('kevin');
214         $obj->setCoopTilleuls('coopTilleuls');
215
216         $this->assertEquals(array(
217             'bar' => 'bar',
218         ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('c'))));
219
220         // The PropertyNormalizer is not able to hydrate properties from parent classes
221         $this->assertEquals(array(
222             'symfony' => 'symfony',
223             'foo' => 'foo',
224             'fooBar' => 'fooBar',
225             'bar' => 'bar',
226         ), $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('a', 'c'))));
227     }
228
229     public function testGroupsDenormalize()
230     {
231         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
232         $this->normalizer = new PropertyNormalizer($classMetadataFactory);
233         $this->normalizer->setSerializer($this->serializer);
234
235         $obj = new GroupDummy();
236         $obj->setFoo('foo');
237
238         $toNormalize = array('foo' => 'foo', 'bar' => 'bar');
239
240         $normalized = $this->normalizer->denormalize(
241             $toNormalize,
242             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
243             null,
244             array(PropertyNormalizer::GROUPS => array('a'))
245         );
246         $this->assertEquals($obj, $normalized);
247
248         $obj->setBar('bar');
249
250         $normalized = $this->normalizer->denormalize(
251             $toNormalize,
252             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
253             null,
254             array(PropertyNormalizer::GROUPS => array('a', 'b'))
255         );
256         $this->assertEquals($obj, $normalized);
257     }
258
259     public function testGroupsNormalizeWithNameConverter()
260     {
261         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
262         $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
263         $this->normalizer->setSerializer($this->serializer);
264
265         $obj = new GroupDummy();
266         $obj->setFooBar('@dunglas');
267         $obj->setSymfony('@coopTilleuls');
268         $obj->setCoopTilleuls('les-tilleuls.coop');
269
270         $this->assertEquals(
271             array(
272                 'bar' => null,
273                 'foo_bar' => '@dunglas',
274                 'symfony' => '@coopTilleuls',
275             ),
276             $this->normalizer->normalize($obj, null, array(PropertyNormalizer::GROUPS => array('name_converter')))
277         );
278     }
279
280     public function testGroupsDenormalizeWithNameConverter()
281     {
282         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
283         $this->normalizer = new PropertyNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
284         $this->normalizer->setSerializer($this->serializer);
285
286         $obj = new GroupDummy();
287         $obj->setFooBar('@dunglas');
288         $obj->setSymfony('@coopTilleuls');
289
290         $this->assertEquals(
291             $obj,
292             $this->normalizer->denormalize(array(
293                 'bar' => null,
294                 'foo_bar' => '@dunglas',
295                 'symfony' => '@coopTilleuls',
296                 'coop_tilleuls' => 'les-tilleuls.coop',
297             ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(PropertyNormalizer::GROUPS => array('name_converter')))
298         );
299     }
300
301     public function provideCallbacks()
302     {
303         return array(
304             array(
305                 array(
306                     'bar' => function ($bar) {
307                         return 'baz';
308                     },
309                 ),
310                 'baz',
311                 array('foo' => '', 'bar' => 'baz'),
312                 'Change a string',
313             ),
314             array(
315                 array(
316                     'bar' => function ($bar) {
317                         return;
318                     },
319                 ),
320                 'baz',
321                 array('foo' => '', 'bar' => null),
322                 'Null an item',
323             ),
324             array(
325                 array(
326                     'bar' => function ($bar) {
327                         return $bar->format('d-m-Y H:i:s');
328                     },
329                 ),
330                 new \DateTime('2011-09-10 06:30:00'),
331                 array('foo' => '', 'bar' => '10-09-2011 06:30:00'),
332                 'Format a date',
333             ),
334             array(
335                 array(
336                     'bar' => function ($bars) {
337                         $foos = '';
338                         foreach ($bars as $bar) {
339                             $foos .= $bar->getFoo();
340                         }
341
342                         return $foos;
343                     },
344                 ),
345                 array(new PropertyConstructorDummy('baz', ''), new PropertyConstructorDummy('quux', '')),
346                 array('foo' => '', 'bar' => 'bazquux'),
347                 'Collect a property',
348             ),
349             array(
350                 array(
351                     'bar' => function ($bars) {
352                         return count($bars);
353                     },
354                 ),
355                 array(new PropertyConstructorDummy('baz', ''), new PropertyConstructorDummy('quux', '')),
356                 array('foo' => '', 'bar' => 2),
357                 'Count a property',
358             ),
359         );
360     }
361
362     /**
363      * @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
364      */
365     public function testUnableToNormalizeCircularReference()
366     {
367         $serializer = new Serializer(array($this->normalizer));
368         $this->normalizer->setSerializer($serializer);
369         $this->normalizer->setCircularReferenceLimit(2);
370
371         $obj = new PropertyCircularReferenceDummy();
372
373         $this->normalizer->normalize($obj);
374     }
375
376     public function testSiblingReference()
377     {
378         $serializer = new Serializer(array($this->normalizer));
379         $this->normalizer->setSerializer($serializer);
380
381         $siblingHolder = new PropertySiblingHolder();
382
383         $expected = array(
384             'sibling0' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
385             'sibling1' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
386             'sibling2' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
387         );
388         $this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
389     }
390
391     public function testCircularReferenceHandler()
392     {
393         $serializer = new Serializer(array($this->normalizer));
394         $this->normalizer->setSerializer($serializer);
395         $this->normalizer->setCircularReferenceHandler(function ($obj) {
396             return get_class($obj);
397         });
398
399         $obj = new PropertyCircularReferenceDummy();
400
401         $expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\PropertyCircularReferenceDummy');
402         $this->assertEquals($expected, $this->normalizer->normalize($obj));
403     }
404
405     public function testDenormalizeNonExistingAttribute()
406     {
407         $this->assertEquals(
408             new PropertyDummy(),
409             $this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\PropertyDummy')
410         );
411     }
412
413     public function testDenormalizeShouldIgnoreStaticProperty()
414     {
415         $obj = $this->normalizer->denormalize(array('outOfScope' => true), __NAMESPACE__.'\PropertyDummy');
416
417         $this->assertEquals(new PropertyDummy(), $obj);
418         $this->assertEquals('out_of_scope', PropertyDummy::$outOfScope);
419     }
420
421     /**
422      * @expectedException \Symfony\Component\Serializer\Exception\LogicException
423      * @expectedExceptionMessage Cannot normalize attribute "bar" because injected serializer is not a normalizer
424      */
425     public function testUnableToNormalizeObjectAttribute()
426     {
427         $serializer = $this->getMockBuilder('Symfony\Component\Serializer\SerializerInterface')->getMock();
428         $this->normalizer->setSerializer($serializer);
429
430         $obj = new PropertyDummy();
431         $object = new \stdClass();
432         $obj->setBar($object);
433
434         $this->normalizer->normalize($obj, 'any');
435     }
436
437     public function testNoTraversableSupport()
438     {
439         $this->assertFalse($this->normalizer->supportsNormalization(new \ArrayObject()));
440     }
441
442     public function testNoStaticPropertySupport()
443     {
444         $this->assertFalse($this->normalizer->supportsNormalization(new StaticPropertyDummy()));
445     }
446 }
447
448 class PropertyDummy
449 {
450     public static $outOfScope = 'out_of_scope';
451     public $foo;
452     private $bar;
453     protected $camelCase;
454
455     public function getBar()
456     {
457         return $this->bar;
458     }
459
460     public function setBar($bar)
461     {
462         $this->bar = $bar;
463     }
464
465     public function getCamelCase()
466     {
467         return $this->camelCase;
468     }
469
470     public function setCamelCase($camelCase)
471     {
472         $this->camelCase = $camelCase;
473     }
474 }
475
476 class PropertyConstructorDummy
477 {
478     protected $foo;
479     private $bar;
480
481     public function __construct($foo, $bar)
482     {
483         $this->foo = $foo;
484         $this->bar = $bar;
485     }
486
487     public function getFoo()
488     {
489         return $this->foo;
490     }
491
492     public function getBar()
493     {
494         return $this->bar;
495     }
496 }
497
498 class PropertyCamelizedDummy
499 {
500     private $kevinDunglas;
501     public $fooBar;
502     public $bar_foo;
503
504     public function __construct($kevinDunglas = null)
505     {
506         $this->kevinDunglas = $kevinDunglas;
507     }
508 }
509
510 class StaticPropertyDummy
511 {
512     private static $property = 'value';
513 }