1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Tests\Metadata\Driver; 6 7use JMS\Serializer\Exception\InvalidMetadataException; 8use JMS\Serializer\Expression\ExpressionEvaluator; 9use JMS\Serializer\Metadata\ClassMetadata; 10use JMS\Serializer\Metadata\ExpressionPropertyMetadata; 11use JMS\Serializer\Metadata\PropertyMetadata; 12use JMS\Serializer\Metadata\VirtualPropertyMetadata; 13use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlAttributeDiscriminatorChild; 14use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlAttributeDiscriminatorParent; 15use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlNamespaceAttributeDiscriminatorChild; 16use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlNamespaceAttributeDiscriminatorParent; 17use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlNamespaceDiscriminatorChild; 18use JMS\Serializer\Tests\Fixtures\Discriminator\ObjectWithXmlNamespaceDiscriminatorParent; 19use JMS\Serializer\Tests\Fixtures\FirstClassListCollection; 20use JMS\Serializer\Tests\Fixtures\FirstClassMapCollection; 21use JMS\Serializer\Tests\Fixtures\ObjectWithExpressionVirtualPropertiesAndExcludeAll; 22use JMS\Serializer\Tests\Fixtures\ObjectWithInvalidExpression; 23use JMS\Serializer\Tests\Fixtures\ObjectWithVirtualPropertiesAndDuplicatePropName; 24use JMS\Serializer\Tests\Fixtures\ObjectWithVirtualPropertiesAndExcludeAll; 25use JMS\Serializer\Tests\Fixtures\ParentSkipWithEmptyChild; 26use Metadata\Driver\DriverInterface; 27use PHPUnit\Framework\TestCase; 28use Symfony\Component\ExpressionLanguage\ExpressionFunction; 29use Symfony\Component\ExpressionLanguage\ExpressionLanguage; 30 31abstract class BaseDriverTest extends TestCase 32{ 33 public function testLoadBlogPostMetadata() 34 { 35 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\BlogPost')); 36 37 self::assertNotNull($m); 38 self::assertEquals('blog-post', $m->xmlRootName); 39 self::assertCount(4, $m->xmlNamespaces); 40 self::assertArrayHasKey('', $m->xmlNamespaces); 41 self::assertEquals('http://example.com/namespace', $m->xmlNamespaces['']); 42 self::assertArrayHasKey('gd', $m->xmlNamespaces); 43 self::assertEquals('http://schemas.google.com/g/2005', $m->xmlNamespaces['gd']); 44 self::assertArrayHasKey('atom', $m->xmlNamespaces); 45 self::assertEquals('http://www.w3.org/2005/Atom', $m->xmlNamespaces['atom']); 46 self::assertArrayHasKey('dc', $m->xmlNamespaces); 47 self::assertEquals('http://purl.org/dc/elements/1.1/', $m->xmlNamespaces['dc']); 48 49 self::assertFalse($m->isList); 50 self::assertFalse($m->isMap); 51 52 $p = new PropertyMetadata($m->name, 'id'); 53 $p->type = ['name' => 'string', 'params' => []]; 54 $p->groups = ['comments', 'post']; 55 $p->serializedName = 'id'; 56 $p->xmlElementCData = false; 57 self::assertEquals($p, $m->propertyMetadata['id']); 58 59 $p = new PropertyMetadata($m->name, 'title'); 60 $p->type = ['name' => 'string', 'params' => []]; 61 $p->serializedName = 'title'; 62 $p->groups = ['comments', 'post']; 63 $p->xmlNamespace = 'http://purl.org/dc/elements/1.1/'; 64 self::assertEquals($p, $m->propertyMetadata['title']); 65 66 $p = new PropertyMetadata($m->name, 'createdAt'); 67 $p->type = ['name' => 'DateTime', 'params' => []]; 68 $p->serializedName = 'createdAt'; 69 $p->xmlAttribute = true; 70 self::assertEquals($p, $m->propertyMetadata['createdAt']); 71 72 $p = new PropertyMetadata($m->name, 'published'); 73 $p->serializedName = 'published'; 74 $p->type = ['name' => 'boolean', 'params' => []]; 75 $p->serializedName = 'is_published'; 76 $p->xmlAttribute = true; 77 $p->groups = ['post']; 78 self::assertEquals($p, $m->propertyMetadata['published']); 79 80 $p = new PropertyMetadata($m->name, 'etag'); 81 $p->serializedName = 'etag'; 82 $p->type = ['name' => 'string', 'params' => []]; 83 $p->xmlAttribute = true; 84 $p->groups = ['post']; 85 $p->xmlNamespace = 'http://schemas.google.com/g/2005'; 86 self::assertEquals($p, $m->propertyMetadata['etag']); 87 88 $p = new PropertyMetadata($m->name, 'comments'); 89 $p->serializedName = 'comments'; 90 $p->type = ['name' => 'ArrayCollection', 'params' => [['name' => 'JMS\Serializer\Tests\Fixtures\Comment', 'params' => []]]]; 91 $p->xmlCollection = true; 92 $p->xmlCollectionInline = true; 93 $p->xmlEntryName = 'comment'; 94 $p->groups = ['comments']; 95 self::assertEquals($p, $m->propertyMetadata['comments']); 96 97 $p = new PropertyMetadata($m->name, 'author'); 98 $p->serializedName = 'author'; 99 $p->type = ['name' => 'JMS\Serializer\Tests\Fixtures\Author', 'params' => []]; 100 $p->groups = ['post']; 101 $p->xmlNamespace = 'http://www.w3.org/2005/Atom'; 102 self::assertEquals($p, $m->propertyMetadata['author']); 103 104 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Price')); 105 self::assertNotNull($m); 106 107 $p = new PropertyMetadata($m->name, 'price'); 108 $p->serializedName = 'price'; 109 $p->type = ['name' => 'float', 'params' => []]; 110 $p->xmlValue = true; 111 self::assertEquals($p, $m->propertyMetadata['price']); 112 } 113 114 public function testXMLListAbsentNode() 115 { 116 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\ObjectWithAbsentXmlListNode')); 117 118 self::assertArrayHasKey('absent', $m->propertyMetadata); 119 self::assertArrayHasKey('present', $m->propertyMetadata); 120 self::assertArrayHasKey('skipDefault', $m->propertyMetadata); 121 122 self::assertTrue($m->propertyMetadata['absent']->xmlCollectionSkipWhenEmpty); 123 self::assertTrue($m->propertyMetadata['skipDefault']->xmlCollectionSkipWhenEmpty); 124 self::assertFalse($m->propertyMetadata['present']->xmlCollectionSkipWhenEmpty); 125 } 126 127 public function testVirtualProperty() 128 { 129 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\ObjectWithVirtualProperties')); 130 131 self::assertArrayHasKey('existField', $m->propertyMetadata); 132 self::assertArrayHasKey('virtualValue', $m->propertyMetadata); 133 self::assertArrayHasKey('virtualSerializedValue', $m->propertyMetadata); 134 self::assertArrayHasKey('typedVirtualProperty', $m->propertyMetadata); 135 136 self::assertEquals($m->propertyMetadata['virtualSerializedValue']->serializedName, 'test', 'Serialized name is missing'); 137 138 $p = new VirtualPropertyMetadata($m->name, 'virtualValue'); 139 $p->getter = 'getVirtualValue'; 140 $p->serializedName = 'virtualValue'; 141 142 self::assertEquals($p, $m->propertyMetadata['virtualValue']); 143 } 144 145 public function testFirstClassListCollection() 146 { 147 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(FirstClassListCollection::class)); 148 self::assertTrue($m->isList); 149 self::assertFalse($m->isMap); 150 } 151 152 public function testFirstClassMapCollection() 153 { 154 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(FirstClassMapCollection::class)); 155 self::assertFalse($m->isList); 156 self::assertTrue($m->isMap); 157 } 158 159 public function testXmlKeyValuePairs() 160 { 161 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\ObjectWithXmlKeyValuePairs')); 162 163 self::assertArrayHasKey('array', $m->propertyMetadata); 164 self::assertTrue($m->propertyMetadata['array']->xmlKeyValuePairs); 165 } 166 167 public function testInvalidExpression() 168 { 169 $this->expectException(InvalidMetadataException::class); 170 171 $a = new ObjectWithInvalidExpression(); 172 $this->getDriver()->loadMetadataForClass(new \ReflectionClass($a)); 173 } 174 175 public function testExpressionVirtualPropertyWithExcludeAll() 176 { 177 $a = new ObjectWithExpressionVirtualPropertiesAndExcludeAll(); 178 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass($a)); 179 180 self::assertArrayHasKey('virtualValue', $m->propertyMetadata); 181 182 $p = new ExpressionPropertyMetadata($m->name, 'virtualValue', 'object.getVirtualValue()'); 183 $p->serializedName = 'virtualValue'; 184 self::assertEquals($p, $m->propertyMetadata['virtualValue']); 185 } 186 187 public function testVirtualPropertyWithExcludeAll() 188 { 189 $a = new ObjectWithVirtualPropertiesAndExcludeAll(); 190 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass($a)); 191 192 self::assertArrayHasKey('virtualValue', $m->propertyMetadata); 193 194 $p = new VirtualPropertyMetadata($m->name, 'virtualValue'); 195 $p->getter = 'getVirtualValue'; 196 $p->serializedName = 'virtualValue'; 197 198 self::assertEquals($p, $m->propertyMetadata['virtualValue']); 199 } 200 201 public function testReadOnlyDefinedBeforeGetterAndSetter() 202 { 203 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\AuthorReadOnly')); 204 205 self::assertNotNull($m); 206 } 207 208 public function testExpressionVirtualProperty() 209 { 210 /** @var ClassMetadata $m */ 211 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\AuthorExpressionAccess')); 212 213 $keys = array_keys($m->propertyMetadata); 214 self::assertEquals(['firstName', 'lastName', 'id'], $keys); 215 } 216 217 public function testLoadDiscriminator() 218 { 219 /** @var ClassMetadata $m */ 220 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Discriminator\Vehicle')); 221 222 self::assertNotNull($m); 223 self::assertEquals('type', $m->discriminatorFieldName); 224 self::assertEquals($m->name, $m->discriminatorBaseClass); 225 self::assertEquals( 226 [ 227 'car' => 'JMS\Serializer\Tests\Fixtures\Discriminator\Car', 228 'moped' => 'JMS\Serializer\Tests\Fixtures\Discriminator\Moped', 229 ], 230 $m->discriminatorMap 231 ); 232 } 233 234 public function testLoadDiscriminatorWhenParentIsInDiscriminatorMap() 235 { 236 /** @var ClassMetadata $m */ 237 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Discriminator\Post')); 238 239 self::assertNotNull($m); 240 self::assertEquals('type', $m->discriminatorFieldName); 241 self::assertEquals($m->name, $m->discriminatorBaseClass); 242 self::assertEquals( 243 [ 244 'post' => 'JMS\Serializer\Tests\Fixtures\Discriminator\Post', 245 'image_post' => 'JMS\Serializer\Tests\Fixtures\Discriminator\ImagePost', 246 ], 247 $m->discriminatorMap 248 ); 249 } 250 251 public function testLoadXmlDiscriminator() 252 { 253 /** @var ClassMetadata $m */ 254 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(ObjectWithXmlAttributeDiscriminatorParent::class)); 255 256 self::assertNotNull($m); 257 self::assertEquals('type', $m->discriminatorFieldName); 258 self::assertEquals($m->name, $m->discriminatorBaseClass); 259 self::assertEquals( 260 [ 261 'child' => ObjectWithXmlAttributeDiscriminatorChild::class, 262 ], 263 $m->discriminatorMap 264 ); 265 self::assertTrue($m->xmlDiscriminatorAttribute); 266 self::assertFalse($m->xmlDiscriminatorCData); 267 } 268 269 public function testLoadXmlDiscriminatorWithNamespaces() 270 { 271 /** @var ClassMetadata $m */ 272 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(ObjectWithXmlNamespaceDiscriminatorParent::class)); 273 274 self::assertNotNull($m); 275 self::assertEquals('type', $m->discriminatorFieldName); 276 self::assertEquals($m->name, $m->discriminatorBaseClass); 277 self::assertEquals( 278 [ 279 'child' => ObjectWithXmlNamespaceDiscriminatorChild::class, 280 ], 281 $m->discriminatorMap 282 ); 283 self::assertEquals('http://example.com/', $m->xmlDiscriminatorNamespace); 284 self::assertFalse($m->xmlDiscriminatorAttribute); 285 } 286 287 public function testCanDefineMetadataForInternalClass() 288 { 289 /** @var ClassMetadata $m */ 290 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(\PDOStatement::class)); 291 292 self::assertNotNull($m); 293 self::assertSame('int', $m->propertyMetadata['queryString']->type['name']); 294 295 self::assertCount(1, $m->fileResources); 296 } 297 298 public function testLoadXmlDiscriminatorWithAttributeNamespaces() 299 { 300 /** @var ClassMetadata $m */ 301 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(ObjectWithXmlNamespaceAttributeDiscriminatorParent::class)); 302 303 self::assertNotNull($m); 304 self::assertEquals('type', $m->discriminatorFieldName); 305 self::assertEquals($m->name, $m->discriminatorBaseClass); 306 self::assertEquals( 307 [ 308 'child' => ObjectWithXmlNamespaceAttributeDiscriminatorChild::class, 309 ], 310 $m->discriminatorMap 311 ); 312 self::assertEquals('http://example.com/', $m->xmlDiscriminatorNamespace); 313 self::assertTrue($m->xmlDiscriminatorAttribute); 314 } 315 316 public function testLoadDiscriminatorWithGroup() 317 { 318 /** @var ClassMetadata $m */ 319 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\DiscriminatorGroup\Vehicle')); 320 321 self::assertNotNull($m); 322 self::assertEquals('type', $m->discriminatorFieldName); 323 self::assertEquals(['foo'], $m->discriminatorGroups); 324 self::assertEquals($m->name, $m->discriminatorBaseClass); 325 self::assertEquals( 326 ['car' => 'JMS\Serializer\Tests\Fixtures\DiscriminatorGroup\Car'], 327 $m->discriminatorMap 328 ); 329 } 330 331 public function testSkipWhenEmptyOption() 332 { 333 /** @var ClassMetadata $m */ 334 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass(ParentSkipWithEmptyChild::class)); 335 336 self::assertNotNull($m); 337 338 self::assertInstanceOf(PropertyMetadata::class, $m->propertyMetadata['c']); 339 self::assertInstanceOf(PropertyMetadata::class, $m->propertyMetadata['d']); 340 self::assertInstanceOf(PropertyMetadata::class, $m->propertyMetadata['child']); 341 self::assertFalse($m->propertyMetadata['c']->skipWhenEmpty); 342 self::assertFalse($m->propertyMetadata['d']->skipWhenEmpty); 343 self::assertTrue($m->propertyMetadata['child']->skipWhenEmpty); 344 } 345 346 public function testLoadDiscriminatorSubClass() 347 { 348 /** @var ClassMetadata $m */ 349 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Discriminator\Car')); 350 351 self::assertNotNull($m); 352 self::assertNull($m->discriminatorValue); 353 self::assertNull($m->discriminatorBaseClass); 354 self::assertNull($m->discriminatorFieldName); 355 self::assertEquals([], $m->discriminatorMap); 356 } 357 358 public function testLoadDiscriminatorSubClassWhenParentIsInDiscriminatorMap() 359 { 360 /** @var ClassMetadata $m */ 361 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Discriminator\ImagePost')); 362 363 self::assertNotNull($m); 364 self::assertNull($m->discriminatorValue); 365 self::assertNull($m->discriminatorBaseClass); 366 self::assertNull($m->discriminatorFieldName); 367 self::assertEquals([], $m->discriminatorMap); 368 } 369 370 public function testLoadXmlObjectWithNamespacesMetadata() 371 { 372 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\ObjectWithXmlNamespaces')); 373 self::assertNotNull($m); 374 self::assertEquals('test-object', $m->xmlRootName); 375 self::assertEquals('ex', $m->xmlRootPrefix); 376 self::assertEquals('http://example.com/namespace', $m->xmlRootNamespace); 377 self::assertCount(3, $m->xmlNamespaces); 378 self::assertArrayHasKey('', $m->xmlNamespaces); 379 self::assertEquals('http://example.com/namespace', $m->xmlNamespaces['']); 380 self::assertArrayHasKey('gd', $m->xmlNamespaces); 381 self::assertEquals('http://schemas.google.com/g/2005', $m->xmlNamespaces['gd']); 382 self::assertArrayHasKey('atom', $m->xmlNamespaces); 383 self::assertEquals('http://www.w3.org/2005/Atom', $m->xmlNamespaces['atom']); 384 385 $p = new PropertyMetadata($m->name, 'title'); 386 $p->serializedName = 'title'; 387 $p->type = ['name' => 'string', 'params' => []]; 388 $p->xmlNamespace = 'http://purl.org/dc/elements/1.1/'; 389 self::assertEquals($p, $m->propertyMetadata['title']); 390 391 $p = new PropertyMetadata($m->name, 'createdAt'); 392 $p->serializedName = 'createdAt'; 393 $p->type = ['name' => 'DateTime', 'params' => []]; 394 $p->xmlAttribute = true; 395 self::assertEquals($p, $m->propertyMetadata['createdAt']); 396 397 $p = new PropertyMetadata($m->name, 'etag'); 398 $p->serializedName = 'etag'; 399 $p->type = ['name' => 'string', 'params' => []]; 400 $p->xmlAttribute = true; 401 $p->xmlNamespace = 'http://schemas.google.com/g/2005'; 402 self::assertEquals($p, $m->propertyMetadata['etag']); 403 404 $p = new PropertyMetadata($m->name, 'author'); 405 $p->serializedName = 'author'; 406 $p->type = ['name' => 'string', 'params' => []]; 407 $p->xmlAttribute = false; 408 $p->xmlNamespace = 'http://www.w3.org/2005/Atom'; 409 self::assertEquals($p, $m->propertyMetadata['author']); 410 411 $p = new PropertyMetadata($m->name, 'language'); 412 $p->serializedName = 'language'; 413 $p->type = ['name' => 'string', 'params' => []]; 414 $p->xmlAttribute = true; 415 $p->xmlNamespace = 'http://purl.org/dc/elements/1.1/'; 416 self::assertEquals($p, $m->propertyMetadata['language']); 417 } 418 419 public function testMaxDepth() 420 { 421 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Node')); 422 423 self::assertEquals(2, $m->propertyMetadata['children']->maxDepth); 424 } 425 426 public function testPersonCData() 427 { 428 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\Person')); 429 430 self::assertNotNull($m); 431 self::assertFalse($m->propertyMetadata['name']->xmlElementCData); 432 } 433 434 public function testXmlNamespaceInheritanceMetadata() 435 { 436 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\SimpleClassObject')); 437 self::assertNotNull($m); 438 self::assertCount(3, $m->xmlNamespaces); 439 self::assertArrayHasKey('old_foo', $m->xmlNamespaces); 440 self::assertEquals('http://old.foo.example.org', $m->xmlNamespaces['old_foo']); 441 self::assertArrayHasKey('foo', $m->xmlNamespaces); 442 self::assertEquals('http://foo.example.org', $m->xmlNamespaces['foo']); 443 self::assertArrayHasKey('new_foo', $m->xmlNamespaces); 444 self::assertEquals('http://new.foo.example.org', $m->xmlNamespaces['new_foo']); 445 self::assertCount(3, $m->propertyMetadata); 446 447 $p = new PropertyMetadata($m->name, 'foo'); 448 $p->serializedName = 'foo'; 449 $p->type = ['name' => 'string', 'params' => []]; 450 $p->xmlNamespace = 'http://old.foo.example.org'; 451 $p->xmlAttribute = true; 452 self::assertEquals($p, $m->propertyMetadata['foo']); 453 454 $p = new PropertyMetadata($m->name, 'bar'); 455 $p->serializedName = 'bar'; 456 $p->type = ['name' => 'string', 'params' => []]; 457 $p->xmlNamespace = 'http://foo.example.org'; 458 self::assertEquals($p, $m->propertyMetadata['bar']); 459 460 $p = new PropertyMetadata($m->name, 'moo'); 461 $p->serializedName = 'moo'; 462 $p->type = ['name' => 'string', 'params' => []]; 463 $p->xmlNamespace = 'http://new.foo.example.org'; 464 self::assertEquals($p, $m->propertyMetadata['moo']); 465 466 $subm = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\SimpleSubClassObject')); 467 self::assertNotNull($subm); 468 self::assertCount(2, $subm->xmlNamespaces); 469 self::assertArrayHasKey('old_foo', $subm->xmlNamespaces); 470 self::assertEquals('http://foo.example.org', $subm->xmlNamespaces['old_foo']); 471 self::assertArrayHasKey('foo', $subm->xmlNamespaces); 472 self::assertEquals('http://better.foo.example.org', $subm->xmlNamespaces['foo']); 473 self::assertCount(3, $subm->propertyMetadata); 474 475 $p = new PropertyMetadata($subm->name, 'moo'); 476 $p->serializedName = 'moo'; 477 $p->type = ['name' => 'string', 'params' => []]; 478 $p->xmlNamespace = 'http://better.foo.example.org'; 479 self::assertEquals($p, $subm->propertyMetadata['moo']); 480 481 $p = new PropertyMetadata($subm->name, 'baz'); 482 $p->serializedName = 'baz'; 483 $p->type = ['name' => 'string', 'params' => []]; 484 $p->xmlNamespace = 'http://foo.example.org'; 485 self::assertEquals($p, $subm->propertyMetadata['baz']); 486 487 $p = new PropertyMetadata($subm->name, 'qux'); 488 $p->serializedName = 'qux'; 489 $p->type = ['name' => 'string', 'params' => []]; 490 $p->xmlNamespace = 'http://new.foo.example.org'; 491 self::assertEquals($p, $subm->propertyMetadata['qux']); 492 493 $m->merge($subm); 494 self::assertNotNull($m); 495 self::assertCount(3, $m->xmlNamespaces); 496 self::assertArrayHasKey('old_foo', $m->xmlNamespaces); 497 self::assertEquals('http://foo.example.org', $m->xmlNamespaces['old_foo']); 498 self::assertArrayHasKey('foo', $m->xmlNamespaces); 499 self::assertEquals('http://better.foo.example.org', $m->xmlNamespaces['foo']); 500 self::assertArrayHasKey('new_foo', $m->xmlNamespaces); 501 self::assertEquals('http://new.foo.example.org', $m->xmlNamespaces['new_foo']); 502 self::assertCount(5, $m->propertyMetadata); 503 504 $p = new PropertyMetadata($m->name, 'foo'); 505 $p->serializedName = 'foo'; 506 $p->type = ['name' => 'string', 'params' => []]; 507 $p->xmlNamespace = 'http://old.foo.example.org'; 508 $p->xmlAttribute = true; 509 $p->class = 'JMS\Serializer\Tests\Fixtures\SimpleClassObject'; 510 $this->assetMetadataEquals($p, $m->propertyMetadata['foo']); 511 512 $p = new PropertyMetadata($m->name, 'bar'); 513 $p->serializedName = 'bar'; 514 $p->type = ['name' => 'string', 'params' => []]; 515 $p->xmlNamespace = 'http://foo.example.org'; 516 $p->class = 'JMS\Serializer\Tests\Fixtures\SimpleClassObject'; 517 $this->assetMetadataEquals($p, $m->propertyMetadata['bar']); 518 519 $p = new PropertyMetadata($m->name, 'moo'); 520 $p->serializedName = 'moo'; 521 $p->type = ['name' => 'string', 'params' => []]; 522 $p->xmlNamespace = 'http://better.foo.example.org'; 523 $this->assetMetadataEquals($p, $m->propertyMetadata['moo']); 524 525 $p = new PropertyMetadata($m->name, 'baz'); 526 $p->serializedName = 'baz'; 527 $p->type = ['name' => 'string', 'params' => []]; 528 $p->xmlNamespace = 'http://foo.example.org'; 529 $this->assetMetadataEquals($p, $m->propertyMetadata['baz']); 530 531 $p = new PropertyMetadata($m->name, 'qux'); 532 $p->serializedName = 'qux'; 533 $p->type = ['name' => 'string', 'params' => []]; 534 $p->xmlNamespace = 'http://new.foo.example.org'; 535 $this->assetMetadataEquals($p, $m->propertyMetadata['qux']); 536 } 537 538 private function assetMetadataEquals(PropertyMetadata $expected, PropertyMetadata $actual) 539 { 540 $expectedVars = get_object_vars($expected); 541 $actualVars = get_object_vars($actual); 542 543 self::assertEquals($expectedVars, $actualVars); 544 } 545 546 public function testExclusionIf() 547 { 548 $class = 'JMS\Serializer\Tests\Fixtures\PersonSecret'; 549 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass($class)); 550 551 $p = new PropertyMetadata($class, 'name'); 552 $p->serializedName = 'name'; 553 $p->type = ['name' => 'string', 'params' => []]; 554 self::assertEquals($p, $m->propertyMetadata['name']); 555 556 $p = new PropertyMetadata($class, 'gender'); 557 $p->serializedName = 'gender'; 558 $p->type = ['name' => 'string', 'params' => []]; 559 $p->excludeIf = "show_data('gender')"; 560 self::assertEquals($p, $m->propertyMetadata['gender']); 561 562 $p = new PropertyMetadata($class, 'age'); 563 $p->serializedName = 'age'; 564 $p->type = ['name' => 'string', 'params' => []]; 565 $p->excludeIf = "!(show_data('age'))"; 566 self::assertEquals($p, $m->propertyMetadata['age']); 567 } 568 569 public function testObjectWithVirtualPropertiesAndDuplicatePropName() 570 { 571 $class = ObjectWithVirtualPropertiesAndDuplicatePropName::class; 572 $m = $this->getDriver()->loadMetadataForClass(new \ReflectionClass($class)); 573 574 $p = new PropertyMetadata($class, 'id'); 575 $p->serializedName = 'id'; 576 self::assertEquals($p, $m->propertyMetadata['id']); 577 578 $p = new PropertyMetadata($class, 'name'); 579 $p->serializedName = 'name'; 580 self::assertEquals($p, $m->propertyMetadata['name']); 581 582 $p = new VirtualPropertyMetadata($class, 'foo'); 583 $p->serializedName = 'id'; 584 $p->getter = 'getId'; 585 586 self::assertEquals($p, $m->propertyMetadata['foo']); 587 588 $p = new VirtualPropertyMetadata($class, 'bar'); 589 $p->serializedName = 'mood'; 590 $p->getter = 'getName'; 591 592 self::assertEquals($p, $m->propertyMetadata['bar']); 593 } 594 595 public function testExcludePropertyNoPublicAccessorException() 596 { 597 $first = $this->getDriver()->loadMetadataForClass(new \ReflectionClass('JMS\Serializer\Tests\Fixtures\ExcludePublicAccessor')); 598 599 if ($this instanceof PhpDriverTest) { 600 return; 601 } 602 self::assertArrayHasKey('id', $first->propertyMetadata); 603 self::assertArrayNotHasKey('iShallNotBeAccessed', $first->propertyMetadata); 604 } 605 606 /** 607 * @return DriverInterface 608 */ 609 abstract protected function getDriver(); 610 611 protected function getExpressionEvaluator() 612 { 613 $language = new ExpressionLanguage(); 614 615 $language->addFunction(new ExpressionFunction('show_data', static function () { 616 return 'true'; 617 }, static function () { 618 return true; 619 })); 620 return new ExpressionEvaluator($language); 621 } 622} 623