anonymous//tests/Spec/AbstractObjectUnitTest.php$0   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 7
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
wmc 1
1
<?php
2
3
namespace erasys\OpenApi\Tests\Spec;
4
5
use erasys\OpenApi\Exceptions\ArrayKeyConflictException;
6
use erasys\OpenApi\Exceptions\UndefinedPropertyException;
7
use erasys\OpenApi\Exceptions\UnsupportedTypeException;
8
use erasys\OpenApi\ExtensionProperty;
9
use erasys\OpenApi\RawValue;
10
use erasys\OpenApi\Spec\v3\AbstractObject;
11
use erasys\OpenApi\Spec\v3\Reference;
12
use erasys\OpenApi\Spec\v3\Tag;
13
use PHPUnit\Framework\TestCase;
14
use stdClass;
15
16
class AbstractObjectUnitTest extends TestCase
17
{
18
    private function getClassStub(array $properties = []): AbstractObject
19
    {
20
        return new class($properties) extends AbstractObject
21
        {
22
            public $foo;
23
24
            public function __construct(array $properties = [])
25
            {
26
                parent::__construct($properties);
27
            }
28
        };
29
    }
30
31
    public function testGetUndefinedPropertyViaGetterShouldFail()
32
    {
33
        $this->expectException(UndefinedPropertyException::class);
34
        $this->expectExceptionCode(1);
35
36
        $obj = $this->getClassStub();
37
        $obj->undefinedProperty;
38
    }
39
40
    public function testSetUndefinedPropertyViaSetterShouldFail()
41
    {
42
        $this->expectException(UndefinedPropertyException::class);
43
        $this->expectExceptionCode(2);
44
45
        $obj                    = $this->getClassStub();
46
        $obj->undefinedProperty = null;
47
    }
48
49
    public function testGetUndefinedPropertyViaArrayOffsetShouldFail()
50
    {
51
        $this->expectException(UndefinedPropertyException::class);
52
        $this->expectExceptionCode(1);
53
54
        $obj = $this->getClassStub();
55
        $obj['undefinedProperty'];
56
    }
57
58
    public function testGetOffsetIsset()
59
    {
60
        $obj = $this->getClassStub();
61
        $this->assertFalse(isset($obj['foo']));
62
        $this->assertFalse(isset($obj['undefinedProperty']));
63
        $obj->foo = 'bar';
64
        $this->assertTrue(isset($obj['foo']));
65
    }
66
67
    public function testGetOffsetUnset()
68
    {
69
        $obj = $this->getClassStub(['foo' => 'bar']);
70
        $this->assertTrue(isset($obj['foo']));
71
        unset($obj['foo']);
72
        $this->assertFalse(isset($obj['foo']));
73
    }
74
75
    public function testSetUndefinedPropertyViaArrayOffsetShouldFail()
76
    {
77
        $this->expectException(UndefinedPropertyException::class);
78
        $this->expectExceptionCode(2);
79
80
        $obj                      = $this->getClassStub();
81
        $obj['undefinedProperty'] = null;
82
    }
83
84
    public function testSetUndefinedPropertyViaConstructorShouldFail()
85
    {
86
        $this->expectException(UndefinedPropertyException::class);
87
        $this->expectExceptionCode(2);
88
89
        $this->getClassStub(['undefinedProperty' => null]);
90
    }
91
92
    public function testToArrayWithUnsupportedTypeShouldFail()
93
    {
94
        $this->expectException(UnsupportedTypeException::class);
95
        $this->expectExceptionCode(0);
96
97
        $obj      = $this->getClassStub();
98
        $obj->foo = new stdClass();
99
        $obj->toArray();
100
    }
101
102
    public function testToArrayShouldNotReturnNonPublicProperties()
103
    {
104
        $obj = new class() extends AbstractObject
105
        {
106
            public $foo = 'a';
107
            protected $bar = 'b';
108
            private $baz = 'c';
109
        };
110
111
        $expected = ['foo' => 'a'];
112
        $actual   = $obj->toArray();
113
114
        $this->assertEquals($expected, $actual);
115
    }
116
117
    public function testToArrayNullPropertiesShouldNotBeExported()
118
    {
119
        $obj = new class() extends AbstractObject
120
        {
121
            public $foo = 'a';
122
            public $bar = null;
123
            public $baz;
124
        };
125
126
        $expected = ['foo' => 'a'];
127
        $actual   = $obj->toArray();
128
129
        $this->assertEquals($expected, $actual);
130
    }
131
132
    public function testToArrayRawValueShouldBeExportedAsItIs()
133
    {
134
        $obj = new class() extends AbstractObject
135
        {
136
            public $foo = 'a';
137
            public $bar = null;
138
            public $baz;
139
        };
140
141
        $obj->bar = new RawValue('b');
142
        $obj->baz = new RawValue(null);
143
144
        $expected = ['foo' => 'a', 'bar' => 'b', 'baz' => null];
145
        $actual   = $obj->toArray();
146
147
        $this->assertEquals($expected, $actual);
148
    }
149
150
    public function testToArrayNestedAbstractObjectShouldBeExported()
151
    {
152
        $obj = new class() extends AbstractObject
153
        {
154
            public $foo = 'a';
155
            public $bar;
156
        };
157
158
        $obj->bar = new Tag('foobar');
159
160
        $expected = ['foo' => 'a', 'bar' => ['name' => 'foobar']];
161
        $actual   = $obj->toArray();
162
163
        $this->assertEquals($expected, $actual);
164
    }
165
166
    public function testToArrayExtensionPropertyObjectShouldBeMappedAndExported()
167
    {
168
        $obj = new class() extends AbstractObject
169
        {
170
            public $foo = 'a';
171
            public $xBarBaz;
172
            public $xBarBazFoo;
173
        };
174
175
        $obj->xBarBaz    = new ExtensionProperty('Hello-World', 123);
176
        $obj->xBarBazFoo = new ExtensionProperty('Hello-World-Foo', null);
177
178
        $expected = ['foo' => 'a', 'x-Hello-World' => 123];
179
        $actual   = $obj->toArray();
180
181
        $this->assertEquals($expected, $actual);
182
    }
183
184
    public function testToArrayXmlPropertyShouldNotBeTreatedAsExtension()
185
    {
186
        $obj = new class() extends AbstractObject
187
        {
188
            public $foo = 'a';
189
            public $xml = 'b';
190
            public $xML = 'c';
191
        };
192
193
        $expected = ['foo' => 'a', 'xml' => 'b', 'x-ML' => 'c'];
194
        $actual   = $obj->toArray();
195
196
        $this->assertEquals($expected, $actual);
197
    }
198
199
    public function testToArrayExtensionNameShouldBeExportedWithDashedFormatAndRespectedCase()
200
    {
201
        $obj = new class() extends AbstractObject
202
        {
203
            public $foo = 'a';
204
            public $x_bar_baz = 'b';
205
            public $x_BarBazFoo = 'c';
206
            public $xBarBaz_foo_Bar = 'd';
207
            public $xBar_baz = 'e';
208
            public $xbar_baz_foo = 'f';
209
        };
210
211
        $expected = [
212
            'foo'              => 'a',
213
            'x-bar-baz'        => 'b',
214
            'x-BarBazFoo'      => 'c',
215
            'x-BarBaz-foo-Bar' => 'd',
216
            'x-Bar-baz'        => 'e',
217
            'x-bar-baz-foo'    => 'f',
218
        ];
219
        $actual   = $obj->toArray();
220
221
        $this->assertEquals($expected, $actual);
222
    }
223
224
    public function testToArrayWithConflictingExtensionNamesShouldFail()
225
    {
226
        $this->expectException(ArrayKeyConflictException::class);
227
        $this->expectExceptionCode(0);
228
229
        $obj = new class() extends AbstractObject
230
        {
231
            public $foo = 'a';
232
            public $x_Bar_baz = 'b';
233
            public $xBar_baz = 'e';
234
        };
235
        $obj->toArray();
236
    }
237
238
    public function testToArrayRefPropertyNameShouldBeExportedWithDollarSign()
239
    {
240
        $obj = new class() extends AbstractObject
241
        {
242
            public $foo = 'a';
243
            public $ref;
244
            public $data;
245
        };
246
247
        $obj->ref  = 'b';
248
        $obj->data = new Reference('c');
249
250
        $expected = ['foo' => 'a', '$ref' => 'b', 'data' => ['$ref' => 'c']];
251
        $actual   = $obj->toArray();
252
253
        $this->assertEquals($expected, $actual);
254
    }
255
256
    public function testToJson()
257
    {
258
        $obj = $this->getClassStub();
259
        $this->assertEquals('{}', $obj->toJson());
260
261
        $obj      = $this->getClassStub();
262
        $obj->foo = 'bar';
263
264
        $this->assertEquals('{"foo":"bar"}', $obj->toJson());
265
    }
266
267
    public function testToYaml()
268
    {
269
        $obj = $this->getClassStub();
270
        $this->assertEquals('{  }', $obj->toYaml());
271
272
        $obj      = $this->getClassStub();
273
        $obj->foo = 'bar';
274
275
        $this->assertEquals("foo: bar\n", $obj->toYaml());
276
    }
277
278
    public function testToObject()
279
    {
280
        $obj = $this->getClassStub();
281
        $this->assertEquals('{}', $obj->__toString());
282
283
        $obj      = $this->getClassStub();
284
        $obj->foo = 'bar';
285
286
        $this->assertEquals('{"foo":"bar"}', $obj->__toString());
287
    }
288
289
    public function testToString()
290
    {
291
        $obj = $this->getClassStub();
292
        $this->assertEquals(new stdClass(), $obj->toObject());
293
294
        $obj           = $this->getClassStub();
295
        $obj->foo      = 'bar';
296
        $expected      = new stdClass();
297
        $expected->foo = 'bar';
298
        $this->assertEquals($expected, $obj->toObject());
299
    }
300
}
301