005dfe92f90b4004a438038df667eef14860b3da
[yaffs-website] / vendor / symfony / serializer / Tests / Normalizer / ObjectNormalizerTest.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\PropertyInfo\Extractor\PhpDocExtractor;
17 use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
18 use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
19 use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
20 use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
21 use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
22 use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
23 use Symfony\Component\Serializer\Serializer;
24 use Symfony\Component\Serializer\SerializerInterface;
25 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
26 use Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy;
27 use Symfony\Component\Serializer\Tests\Fixtures\MaxDepthDummy;
28 use Symfony\Component\Serializer\Tests\Fixtures\SiblingHolder;
29 use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
30 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
31 use Symfony\Component\Serializer\Tests\Fixtures\GroupDummy;
32
33 /**
34  * @author Kévin Dunglas <dunglas@gmail.com>
35  */
36 class ObjectNormalizerTest extends TestCase
37 {
38     /**
39      * @var ObjectNormalizer
40      */
41     private $normalizer;
42     /**
43      * @var SerializerInterface
44      */
45     private $serializer;
46
47     protected function setUp()
48     {
49         $this->serializer = $this->getMockBuilder(__NAMESPACE__.'\ObjectSerializerNormalizer')->getMock();
50         $this->normalizer = new ObjectNormalizer();
51         $this->normalizer->setSerializer($this->serializer);
52     }
53
54     public function testNormalize()
55     {
56         $obj = new ObjectDummy();
57         $object = new \stdClass();
58         $obj->setFoo('foo');
59         $obj->bar = 'bar';
60         $obj->setBaz(true);
61         $obj->setCamelCase('camelcase');
62         $obj->setObject($object);
63
64         $this->serializer
65             ->expects($this->once())
66             ->method('normalize')
67             ->with($object, 'any')
68             ->will($this->returnValue('string_object'))
69         ;
70
71         $this->assertEquals(
72             array(
73                 'foo' => 'foo',
74                 'bar' => 'bar',
75                 'baz' => true,
76                 'fooBar' => 'foobar',
77                 'camelCase' => 'camelcase',
78                 'object' => 'string_object',
79             ),
80             $this->normalizer->normalize($obj, 'any')
81         );
82     }
83
84     public function testDenormalize()
85     {
86         $obj = $this->normalizer->denormalize(
87             array('foo' => 'foo', 'bar' => 'bar', 'baz' => true, 'fooBar' => 'foobar'),
88             __NAMESPACE__.'\ObjectDummy',
89             'any'
90         );
91         $this->assertEquals('foo', $obj->getFoo());
92         $this->assertEquals('bar', $obj->bar);
93         $this->assertTrue($obj->isBaz());
94     }
95
96     public function testDenormalizeWithObject()
97     {
98         $data = new \stdClass();
99         $data->foo = 'foo';
100         $data->bar = 'bar';
101         $data->fooBar = 'foobar';
102         $obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\ObjectDummy', 'any');
103         $this->assertEquals('foo', $obj->getFoo());
104         $this->assertEquals('bar', $obj->bar);
105     }
106
107     public function testDenormalizeNull()
108     {
109         $this->assertEquals(new ObjectDummy(), $this->normalizer->denormalize(null, __NAMESPACE__.'\ObjectDummy'));
110     }
111
112     public function testConstructorDenormalize()
113     {
114         $obj = $this->normalizer->denormalize(
115             array('foo' => 'foo', 'bar' => 'bar', 'baz' => true, 'fooBar' => 'foobar'),
116             __NAMESPACE__.'\ObjectConstructorDummy', 'any');
117         $this->assertEquals('foo', $obj->getFoo());
118         $this->assertEquals('bar', $obj->bar);
119         $this->assertTrue($obj->isBaz());
120     }
121
122     public function testConstructorDenormalizeWithNullArgument()
123     {
124         $obj = $this->normalizer->denormalize(
125             array('foo' => 'foo', 'bar' => null, 'baz' => true),
126             __NAMESPACE__.'\ObjectConstructorDummy', 'any');
127         $this->assertEquals('foo', $obj->getFoo());
128         $this->assertNull($obj->bar);
129         $this->assertTrue($obj->isBaz());
130     }
131
132     public function testConstructorDenormalizeWithMissingOptionalArgument()
133     {
134         $obj = $this->normalizer->denormalize(
135             array('foo' => 'test', 'baz' => array(1, 2, 3)),
136             __NAMESPACE__.'\ObjectConstructorOptionalArgsDummy', 'any');
137         $this->assertEquals('test', $obj->getFoo());
138         $this->assertEquals(array(), $obj->bar);
139         $this->assertEquals(array(1, 2, 3), $obj->getBaz());
140     }
141
142     public function testConstructorDenormalizeWithOptionalDefaultArgument()
143     {
144         $obj = $this->normalizer->denormalize(
145             array('bar' => 'test'),
146             __NAMESPACE__.'\ObjectConstructorArgsWithDefaultValueDummy', 'any');
147         $this->assertEquals(array(), $obj->getFoo());
148         $this->assertEquals('test', $obj->getBar());
149     }
150
151     public function testConstructorWithObjectDenormalize()
152     {
153         $data = new \stdClass();
154         $data->foo = 'foo';
155         $data->bar = 'bar';
156         $data->baz = true;
157         $data->fooBar = 'foobar';
158         $obj = $this->normalizer->denormalize($data, __NAMESPACE__.'\ObjectConstructorDummy', 'any');
159         $this->assertEquals('foo', $obj->getFoo());
160         $this->assertEquals('bar', $obj->bar);
161     }
162
163     public function testConstructorWithObjectTypeHintDenormalize()
164     {
165         $data = array(
166             'id' => 10,
167             'inner' => array(
168                 'foo' => 'oof',
169                 'bar' => 'rab',
170             ),
171         );
172
173         $normalizer = new ObjectNormalizer();
174         $serializer = new Serializer(array($normalizer));
175         $normalizer->setSerializer($serializer);
176
177         $obj = $normalizer->denormalize($data, DummyWithConstructorObject::class);
178         $this->assertInstanceOf(DummyWithConstructorObject::class, $obj);
179         $this->assertEquals(10, $obj->getId());
180         $this->assertInstanceOf(ObjectInner::class, $obj->getInner());
181         $this->assertEquals('oof', $obj->getInner()->foo);
182         $this->assertEquals('rab', $obj->getInner()->bar);
183     }
184
185     /**
186      * @expectedException \Symfony\Component\Serializer\Exception\RuntimeException
187      * @expectedExceptionMessage Could not determine the class of the parameter "unknown".
188      */
189     public function testConstructorWithUnknownObjectTypeHintDenormalize()
190     {
191         $data = array(
192             'id' => 10,
193             'unknown' => array(
194                 'foo' => 'oof',
195                 'bar' => 'rab',
196             ),
197         );
198
199         $normalizer = new ObjectNormalizer();
200         $serializer = new Serializer(array($normalizer));
201         $normalizer->setSerializer($serializer);
202
203         $normalizer->denormalize($data, DummyWithConstructorInexistingObject::class);
204     }
205
206     public function testGroupsNormalize()
207     {
208         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
209         $this->normalizer = new ObjectNormalizer($classMetadataFactory);
210         $this->normalizer->setSerializer($this->serializer);
211
212         $obj = new GroupDummy();
213         $obj->setFoo('foo');
214         $obj->setBar('bar');
215         $obj->setFooBar('fooBar');
216         $obj->setSymfony('symfony');
217         $obj->setKevin('kevin');
218         $obj->setCoopTilleuls('coopTilleuls');
219
220         $this->assertEquals(array(
221             'bar' => 'bar',
222         ), $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('c'))));
223
224         $this->assertEquals(array(
225             'symfony' => 'symfony',
226             'foo' => 'foo',
227             'fooBar' => 'fooBar',
228             'bar' => 'bar',
229             'kevin' => 'kevin',
230             'coopTilleuls' => 'coopTilleuls',
231         ), $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('a', 'c'))));
232     }
233
234     public function testGroupsDenormalize()
235     {
236         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
237         $this->normalizer = new ObjectNormalizer($classMetadataFactory);
238         $this->normalizer->setSerializer($this->serializer);
239
240         $obj = new GroupDummy();
241         $obj->setFoo('foo');
242
243         $toNormalize = array('foo' => 'foo', 'bar' => 'bar');
244
245         $normalized = $this->normalizer->denormalize(
246             $toNormalize,
247             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
248             null,
249             array(ObjectNormalizer::GROUPS => array('a'))
250         );
251         $this->assertEquals($obj, $normalized);
252
253         $obj->setBar('bar');
254
255         $normalized = $this->normalizer->denormalize(
256             $toNormalize,
257             'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy',
258             null,
259             array(ObjectNormalizer::GROUPS => array('a', 'b'))
260         );
261         $this->assertEquals($obj, $normalized);
262     }
263
264     public function testNormalizeNoPropertyInGroup()
265     {
266         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
267         $this->normalizer = new ObjectNormalizer($classMetadataFactory);
268         $this->normalizer->setSerializer($this->serializer);
269
270         $obj = new GroupDummy();
271         $obj->setFoo('foo');
272
273         $this->assertEquals(array(), $this->normalizer->normalize($obj, null, array('groups' => array('notExist'))));
274     }
275
276     public function testGroupsNormalizeWithNameConverter()
277     {
278         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
279         $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
280         $this->normalizer->setSerializer($this->serializer);
281
282         $obj = new GroupDummy();
283         $obj->setFooBar('@dunglas');
284         $obj->setSymfony('@coopTilleuls');
285         $obj->setCoopTilleuls('les-tilleuls.coop');
286
287         $this->assertEquals(
288             array(
289                 'bar' => null,
290                 'foo_bar' => '@dunglas',
291                 'symfony' => '@coopTilleuls',
292             ),
293             $this->normalizer->normalize($obj, null, array(ObjectNormalizer::GROUPS => array('name_converter')))
294         );
295     }
296
297     public function testGroupsDenormalizeWithNameConverter()
298     {
299         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
300         $this->normalizer = new ObjectNormalizer($classMetadataFactory, new CamelCaseToSnakeCaseNameConverter());
301         $this->normalizer->setSerializer($this->serializer);
302
303         $obj = new GroupDummy();
304         $obj->setFooBar('@dunglas');
305         $obj->setSymfony('@coopTilleuls');
306
307         $this->assertEquals(
308             $obj,
309             $this->normalizer->denormalize(array(
310                 'bar' => null,
311                 'foo_bar' => '@dunglas',
312                 'symfony' => '@coopTilleuls',
313                 'coop_tilleuls' => 'les-tilleuls.coop',
314             ), 'Symfony\Component\Serializer\Tests\Fixtures\GroupDummy', null, array(ObjectNormalizer::GROUPS => array('name_converter')))
315         );
316     }
317
318     /**
319      * @dataProvider provideCallbacks
320      */
321     public function testCallbacks($callbacks, $value, $result, $message)
322     {
323         $this->normalizer->setCallbacks($callbacks);
324
325         $obj = new ObjectConstructorDummy('', $value, true);
326
327         $this->assertEquals(
328             $result,
329             $this->normalizer->normalize($obj, 'any'),
330             $message
331         );
332     }
333
334     /**
335      * @expectedException \InvalidArgumentException
336      */
337     public function testUncallableCallbacks()
338     {
339         $this->normalizer->setCallbacks(array('bar' => null));
340
341         $obj = new ObjectConstructorDummy('baz', 'quux', true);
342
343         $this->normalizer->normalize($obj, 'any');
344     }
345
346     public function testIgnoredAttributes()
347     {
348         $this->normalizer->setIgnoredAttributes(array('foo', 'bar', 'baz', 'camelCase', 'object'));
349
350         $obj = new ObjectDummy();
351         $obj->setFoo('foo');
352         $obj->bar = 'bar';
353         $obj->setBaz(true);
354
355         $this->assertEquals(
356             array('fooBar' => 'foobar'),
357             $this->normalizer->normalize($obj, 'any')
358         );
359     }
360
361     public function testIgnoredAttributesDenormalize()
362     {
363         $this->normalizer->setIgnoredAttributes(array('fooBar', 'bar', 'baz'));
364
365         $obj = new ObjectDummy();
366         $obj->setFoo('foo');
367
368         $this->assertEquals(
369             $obj,
370             $this->normalizer->denormalize(array('fooBar' => 'fooBar', 'foo' => 'foo', 'baz' => 'baz'), __NAMESPACE__.'\ObjectDummy')
371         );
372     }
373
374     public function provideCallbacks()
375     {
376         return array(
377             array(
378                 array(
379                     'bar' => function ($bar) {
380                         return 'baz';
381                     },
382                 ),
383                 'baz',
384                 array('foo' => '', 'bar' => 'baz', 'baz' => true),
385                 'Change a string',
386             ),
387             array(
388                 array(
389                     'bar' => function ($bar) {
390                         return;
391                     },
392                 ),
393                 'baz',
394                 array('foo' => '', 'bar' => null, 'baz' => true),
395                 'Null an item',
396             ),
397             array(
398                 array(
399                     'bar' => function ($bar) {
400                         return $bar->format('d-m-Y H:i:s');
401                     },
402                 ),
403                 new \DateTime('2011-09-10 06:30:00'),
404                 array('foo' => '', 'bar' => '10-09-2011 06:30:00', 'baz' => true),
405                 'Format a date',
406             ),
407             array(
408                 array(
409                     'bar' => function ($bars) {
410                         $foos = '';
411                         foreach ($bars as $bar) {
412                             $foos .= $bar->getFoo();
413                         }
414
415                         return $foos;
416                     },
417                 ),
418                 array(new ObjectConstructorDummy('baz', '', false), new ObjectConstructorDummy('quux', '', false)),
419                 array('foo' => '', 'bar' => 'bazquux', 'baz' => true),
420                 'Collect a property',
421             ),
422             array(
423                 array(
424                     'bar' => function ($bars) {
425                         return count($bars);
426                     },
427                 ),
428                 array(new ObjectConstructorDummy('baz', '', false), new ObjectConstructorDummy('quux', '', false)),
429                 array('foo' => '', 'bar' => 2, 'baz' => true),
430                 'Count a property',
431             ),
432         );
433     }
434
435     /**
436      * @expectedException \Symfony\Component\Serializer\Exception\LogicException
437      * @expectedExceptionMessage Cannot normalize attribute "object" because the injected serializer is not a normalizer
438      */
439     public function testUnableToNormalizeObjectAttribute()
440     {
441         $serializer = $this->getMockBuilder('Symfony\Component\Serializer\SerializerInterface')->getMock();
442         $this->normalizer->setSerializer($serializer);
443
444         $obj = new ObjectDummy();
445         $object = new \stdClass();
446         $obj->setObject($object);
447
448         $this->normalizer->normalize($obj, 'any');
449     }
450
451     /**
452      * @expectedException \Symfony\Component\Serializer\Exception\CircularReferenceException
453      */
454     public function testUnableToNormalizeCircularReference()
455     {
456         $serializer = new Serializer(array($this->normalizer));
457         $this->normalizer->setSerializer($serializer);
458         $this->normalizer->setCircularReferenceLimit(2);
459
460         $obj = new CircularReferenceDummy();
461
462         $this->normalizer->normalize($obj);
463     }
464
465     public function testSiblingReference()
466     {
467         $serializer = new Serializer(array($this->normalizer));
468         $this->normalizer->setSerializer($serializer);
469
470         $siblingHolder = new SiblingHolder();
471
472         $expected = array(
473             'sibling0' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
474             'sibling1' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
475             'sibling2' => array('coopTilleuls' => 'Les-Tilleuls.coop'),
476         );
477         $this->assertEquals($expected, $this->normalizer->normalize($siblingHolder));
478     }
479
480     public function testCircularReferenceHandler()
481     {
482         $serializer = new Serializer(array($this->normalizer));
483         $this->normalizer->setSerializer($serializer);
484         $this->normalizer->setCircularReferenceHandler(function ($obj) {
485             return get_class($obj);
486         });
487
488         $obj = new CircularReferenceDummy();
489
490         $expected = array('me' => 'Symfony\Component\Serializer\Tests\Fixtures\CircularReferenceDummy');
491         $this->assertEquals($expected, $this->normalizer->normalize($obj));
492     }
493
494     public function testDenormalizeNonExistingAttribute()
495     {
496         $this->assertEquals(
497             new ObjectDummy(),
498             $this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\ObjectDummy')
499         );
500     }
501
502     public function testNoTraversableSupport()
503     {
504         $this->assertFalse($this->normalizer->supportsNormalization(new \ArrayObject()));
505     }
506
507     public function testNormalizeStatic()
508     {
509         $this->assertEquals(array('foo' => 'K'), $this->normalizer->normalize(new ObjectWithStaticPropertiesAndMethods()));
510     }
511
512     public function testNormalizeUpperCaseAttributes()
513     {
514         $this->assertEquals(array('Foo' => 'Foo', 'Bar' => 'BarBar'), $this->normalizer->normalize(new ObjectWithUpperCaseAttributeNames()));
515     }
516
517     public function testNormalizeNotSerializableContext()
518     {
519         $objectDummy = new ObjectDummy();
520         $expected = array(
521             'foo' => null,
522             'baz' => null,
523             'fooBar' => '',
524             'camelCase' => null,
525             'object' => null,
526             'bar' => null,
527         );
528
529         $this->assertEquals($expected, $this->normalizer->normalize($objectDummy, null, array('not_serializable' => function () {
530         })));
531     }
532
533     public function testMaxDepth()
534     {
535         $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
536         $this->normalizer = new ObjectNormalizer($classMetadataFactory);
537         $serializer = new Serializer(array($this->normalizer));
538         $this->normalizer->setSerializer($serializer);
539
540         $level1 = new MaxDepthDummy();
541         $level1->foo = 'level1';
542
543         $level2 = new MaxDepthDummy();
544         $level2->foo = 'level2';
545         $level1->child = $level2;
546
547         $level3 = new MaxDepthDummy();
548         $level3->foo = 'level3';
549         $level2->child = $level3;
550
551         $result = $serializer->normalize($level1, null, array(ObjectNormalizer::ENABLE_MAX_DEPTH => true));
552
553         $expected = array(
554             'bar' => null,
555             'foo' => 'level1',
556             'child' => array(
557                     'bar' => null,
558                     'foo' => 'level2',
559                     'child' => array(
560                             'bar' => null,
561                             'child' => null,
562                         ),
563                 ),
564         );
565
566         $this->assertEquals($expected, $result);
567     }
568
569     /**
570      * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
571      */
572     public function testThrowUnexpectedValueException()
573     {
574         $this->normalizer->denormalize(array('foo' => 'bar'), ObjectTypeHinted::class);
575     }
576
577     public function testDenomalizeRecursive()
578     {
579         $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor()));
580         $normalizer = new ObjectNormalizer(null, null, null, $extractor);
581         $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer));
582
583         $obj = $serializer->denormalize(array(
584             'inner' => array('foo' => 'foo', 'bar' => 'bar'),
585             'date' => '1988/01/21',
586             'inners' => array(array('foo' => 1), array('foo' => 2)),
587         ), ObjectOuter::class);
588
589         $this->assertSame('foo', $obj->getInner()->foo);
590         $this->assertSame('bar', $obj->getInner()->bar);
591         $this->assertSame('1988-01-21', $obj->getDate()->format('Y-m-d'));
592         $this->assertSame(1, $obj->getInners()[0]->foo);
593         $this->assertSame(2, $obj->getInners()[1]->foo);
594     }
595
596     public function testAcceptJsonNumber()
597     {
598         $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor()));
599         $normalizer = new ObjectNormalizer(null, null, null, $extractor);
600         $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer));
601
602         $this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'json')->number);
603         $this->assertSame(10.0, $serializer->denormalize(array('number' => 10), JsonNumber::class, 'jsonld')->number);
604     }
605
606     /**
607      * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
608      * @expectedExceptionMessage The type of the "date" attribute for class "Symfony\Component\Serializer\Tests\Normalizer\ObjectOuter" must be one of "DateTimeInterface" ("string" given).
609      */
610     public function testRejectInvalidType()
611     {
612         $normalizer = new ObjectNormalizer(null, null, null, new ReflectionExtractor());
613         $serializer = new Serializer(array($normalizer));
614
615         $serializer->denormalize(array('date' => 'foo'), ObjectOuter::class);
616     }
617
618     /**
619      * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
620      * @expectedExceptionMessage The type of the key "a" must be "int" ("string" given).
621      */
622     public function testRejectInvalidKey()
623     {
624         $extractor = new PropertyInfoExtractor(array(), array(new PhpDocExtractor(), new ReflectionExtractor()));
625         $normalizer = new ObjectNormalizer(null, null, null, $extractor);
626         $serializer = new Serializer(array(new ArrayDenormalizer(), new DateTimeNormalizer(), $normalizer));
627
628         $serializer->denormalize(array('inners' => array('a' => array('foo' => 1))), ObjectOuter::class);
629     }
630
631     public function testExtractAttributesRespectsFormat()
632     {
633         $normalizer = new FormatAndContextAwareNormalizer();
634
635         $data = new ObjectDummy();
636         $data->setFoo('bar');
637         $data->bar = 'foo';
638
639         $this->assertSame(array('foo' => 'bar', 'bar' => 'foo'), $normalizer->normalize($data, 'foo_and_bar_included'));
640     }
641
642     public function testExtractAttributesRespectsContext()
643     {
644         $normalizer = new FormatAndContextAwareNormalizer();
645
646         $data = new ObjectDummy();
647         $data->setFoo('bar');
648         $data->bar = 'foo';
649
650         $this->assertSame(array('foo' => 'bar', 'bar' => 'foo'), $normalizer->normalize($data, null, array('include_foo_and_bar' => true)));
651     }
652 }
653
654 class ObjectDummy
655 {
656     protected $foo;
657     public $bar;
658     private $baz;
659     protected $camelCase;
660     protected $object;
661
662     public function getFoo()
663     {
664         return $this->foo;
665     }
666
667     public function setFoo($foo)
668     {
669         $this->foo = $foo;
670     }
671
672     public function isBaz()
673     {
674         return $this->baz;
675     }
676
677     public function setBaz($baz)
678     {
679         $this->baz = $baz;
680     }
681
682     public function getFooBar()
683     {
684         return $this->foo.$this->bar;
685     }
686
687     public function getCamelCase()
688     {
689         return $this->camelCase;
690     }
691
692     public function setCamelCase($camelCase)
693     {
694         $this->camelCase = $camelCase;
695     }
696
697     public function otherMethod()
698     {
699         throw new \RuntimeException('Dummy::otherMethod() should not be called');
700     }
701
702     public function setObject($object)
703     {
704         $this->object = $object;
705     }
706
707     public function getObject()
708     {
709         return $this->object;
710     }
711 }
712
713 class ObjectConstructorDummy
714 {
715     protected $foo;
716     public $bar;
717     private $baz;
718
719     public function __construct($foo, $bar, $baz)
720     {
721         $this->foo = $foo;
722         $this->bar = $bar;
723         $this->baz = $baz;
724     }
725
726     public function getFoo()
727     {
728         return $this->foo;
729     }
730
731     public function isBaz()
732     {
733         return $this->baz;
734     }
735
736     public function otherMethod()
737     {
738         throw new \RuntimeException('Dummy::otherMethod() should not be called');
739     }
740 }
741
742 abstract class ObjectSerializerNormalizer implements SerializerInterface, NormalizerInterface
743 {
744 }
745
746 class ObjectConstructorOptionalArgsDummy
747 {
748     protected $foo;
749     public $bar;
750     private $baz;
751
752     public function __construct($foo, $bar = array(), $baz = array())
753     {
754         $this->foo = $foo;
755         $this->bar = $bar;
756         $this->baz = $baz;
757     }
758
759     public function getFoo()
760     {
761         return $this->foo;
762     }
763
764     public function getBaz()
765     {
766         return $this->baz;
767     }
768
769     public function otherMethod()
770     {
771         throw new \RuntimeException('Dummy::otherMethod() should not be called');
772     }
773 }
774
775 class ObjectConstructorArgsWithDefaultValueDummy
776 {
777     protected $foo;
778     protected $bar;
779
780     public function __construct($foo = array(), $bar)
781     {
782         $this->foo = $foo;
783         $this->bar = $bar;
784     }
785
786     public function getFoo()
787     {
788         return $this->foo;
789     }
790
791     public function getBar()
792     {
793         return $this->bar;
794     }
795
796     public function otherMethod()
797     {
798         throw new \RuntimeException('Dummy::otherMethod() should not be called');
799     }
800 }
801
802 class ObjectWithStaticPropertiesAndMethods
803 {
804     public $foo = 'K';
805     public static $bar = 'A';
806
807     public static function getBaz()
808     {
809         return 'L';
810     }
811 }
812
813 class ObjectTypeHinted
814 {
815     public function setFoo(array $f)
816     {
817     }
818 }
819
820 class ObjectOuter
821 {
822     private $inner;
823     private $date;
824
825     /**
826      * @var ObjectInner[]
827      */
828     private $inners;
829
830     public function getInner()
831     {
832         return $this->inner;
833     }
834
835     public function setInner(ObjectInner $inner)
836     {
837         $this->inner = $inner;
838     }
839
840     public function setDate(\DateTimeInterface $date)
841     {
842         $this->date = $date;
843     }
844
845     public function getDate()
846     {
847         return $this->date;
848     }
849
850     public function setInners(array $inners)
851     {
852         $this->inners = $inners;
853     }
854
855     public function getInners()
856     {
857         return $this->inners;
858     }
859 }
860
861 class ObjectInner
862 {
863     public $foo;
864     public $bar;
865 }
866
867 class FormatAndContextAwareNormalizer extends ObjectNormalizer
868 {
869     protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
870     {
871         if (in_array($attribute, array('foo', 'bar')) && 'foo_and_bar_included' === $format) {
872             return true;
873         }
874
875         if (in_array($attribute, array('foo', 'bar')) && isset($context['include_foo_and_bar']) && true === $context['include_foo_and_bar']) {
876             return true;
877         }
878
879         return false;
880     }
881 }
882
883 class DummyWithConstructorObject
884 {
885     private $id;
886     private $inner;
887
888     public function __construct($id, ObjectInner $inner)
889     {
890         $this->id = $id;
891         $this->inner = $inner;
892     }
893
894     public function getId()
895     {
896         return $this->id;
897     }
898
899     public function getInner()
900     {
901         return $this->inner;
902     }
903 }
904
905 class DummyWithConstructorInexistingObject
906 {
907     public function __construct($id, Unknown $unknown)
908     {
909     }
910 }
911
912 class JsonNumber
913 {
914     /**
915      * @var float
916      */
917     public $number;
918 }
919
920 class ObjectWithUpperCaseAttributeNames
921 {
922     private $Foo = 'Foo';
923     public $Bar = 'BarBar';
924
925     public function getFoo()
926     {
927         return $this->Foo;
928     }
929 }