1<?php
2
3declare(strict_types=1);
4
5namespace JMS\Serializer\Tests\Metadata;
6
7use JMS\Serializer\Metadata\ClassMetadata;
8use JMS\Serializer\Metadata\PropertyMetadata;
9use PHPUnit\Framework\TestCase;
10
11class ClassMetadataTest extends TestCase
12{
13    public function getAccessOrderCases()
14    {
15        return [
16            [['b', 'a'], ['b', 'a']],
17            [['a', 'b'], ['a', 'b']],
18            [['b'], ['b', 'a']],
19            [['a'], ['a', 'b']],
20            [['foo', 'bar'], ['b', 'a']],
21        ];
22    }
23
24    public function testSerialization()
25    {
26        $meta = new PropertyMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder', 'b');
27        $restoredMeta = unserialize(serialize($meta));
28        self::assertEquals($meta, $restoredMeta);
29    }
30
31    public function testSerializationClass()
32    {
33        $meta = new ClassMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder');
34        $meta->xmlRootPrefix = 'foo';
35        $meta->xmlDiscriminatorCData = 'foo';
36        $meta->xmlDiscriminatorAttribute = 'foo';
37        $meta->xmlRootName = 'foo';
38
39        $restoredMeta = unserialize(serialize($meta));
40        self::assertEquals($meta, $restoredMeta);
41    }
42
43    /**
44     * @dataProvider getAccessOrderCases
45     */
46    public function testSetAccessorOrderCustom(array $order, array $expected)
47    {
48        $metadata = new ClassMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder');
49        $metadata->addPropertyMetadata(new PropertyMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder', 'b'));
50        $metadata->addPropertyMetadata(new PropertyMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder', 'a'));
51        self::assertEquals(['b', 'a'], array_keys($metadata->propertyMetadata));
52
53        $metadata->setAccessorOrder(ClassMetadata::ACCESSOR_ORDER_CUSTOM, $order);
54        self::assertEquals($expected, array_keys($metadata->propertyMetadata));
55    }
56
57    public function testSetAccessorOrderAlphabetical()
58    {
59        $metadata = new ClassMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder');
60        $metadata->addPropertyMetadata(new PropertyMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder', 'b'));
61        $metadata->addPropertyMetadata(new PropertyMetadata('JMS\Serializer\Tests\Metadata\PropertyMetadataOrder', 'a'));
62        self::assertEquals(['b', 'a'], array_keys($metadata->propertyMetadata));
63
64        $metadata->setAccessorOrder(ClassMetadata::ACCESSOR_ORDER_ALPHABETICAL);
65        self::assertEquals(['a', 'b'], array_keys($metadata->propertyMetadata));
66    }
67
68    /**
69     * @dataProvider providerPublicMethodData
70     */
71    public function testAccessorTypePublicMethod($property, $getterInit, $setterInit, $getterName, $setterName)
72    {
73        $object = new PropertyMetadataPublicMethod();
74
75        $metadata = new PropertyMetadata(get_class($object), $property);
76        $metadata->setAccessor(PropertyMetadata::ACCESS_TYPE_PUBLIC_METHOD, $getterInit, $setterInit);
77
78        self::assertEquals($getterName, $metadata->getter);
79        self::assertEquals($setterName, $metadata->setter);
80    }
81
82    /**
83     * @dataProvider providerPublicMethodException
84     */
85    public function testAccessorTypePublicMethodException($getter, $setter, $message)
86    {
87        $this->expectException('\JMS\Serializer\Exception\InvalidMetadataException');
88        $this->expectExceptionMessage($message);
89
90        $object = new PropertyMetadataPublicMethod();
91
92        $metadata = new PropertyMetadata(get_class($object), 'e');
93        $metadata->setAccessor(PropertyMetadata::ACCESS_TYPE_PUBLIC_METHOD, $getter, $setter);
94    }
95
96    public function providerPublicMethodData()
97    {
98        return [
99            ['a', null, null, 'geta', 'seta'],
100            ['b', null, null, 'isb', 'setb'],
101            ['c', null, null, 'hasc', 'setc'],
102            ['d', 'fetchd', 'saved', 'fetchd', 'saved'],
103        ];
104    }
105
106    public function providerPublicMethodException()
107    {
108        return [
109            [null, null, 'a public getE method, nor a public isE method, nor a public hasE method in class'],
110            [null, 'setx', 'a public getE method, nor a public isE method, nor a public hasE method in class'],
111            ['getx', null, 'no public setE method in class'],
112        ];
113    }
114}
115
116class PropertyMetadataOrder
117{
118    private $b, $a;
119}
120
121class PropertyMetadataPublicMethod
122{
123    private $a, $b, $c, $d, $e;
124
125    public function getA()
126    {
127        return 'A:' . $this->a;
128    }
129
130    public function setA($a)
131    {
132        $this->a = 'A:' . $a;
133    }
134
135    public function isB()
136    {
137        return 'B:' . $this->b;
138    }
139
140    public function setB($b)
141    {
142        $this->b = 'B:' . $b;
143    }
144
145    public function hasC()
146    {
147        return 'C:' . $this->c;
148    }
149
150    public function setC($c)
151    {
152        $this->c = 'C:' . $c;
153    }
154
155    public function fetchD()
156    {
157        return 'D:' . $this->d;
158    }
159
160    public function saveD($d)
161    {
162        $this->d = 'D:' . $d;
163    }
164}
165