Skip to content

Commit

Permalink
Add OPTION_OBJECTS_FOR_MAPS.
Browse files Browse the repository at this point in the history
This will be useful when serializing to JSON to avoid putting out empty maps as
empty lists.
  • Loading branch information
JanZerebecki committed Sep 26, 2014
1 parent e5d89b3 commit 83e9999
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 15 deletions.
32 changes: 27 additions & 5 deletions src/SerializerFactory.php
Expand Up @@ -14,6 +14,7 @@
use Wikibase\DataModel\Serializers\SiteLinkSerializer;
use Wikibase\DataModel\Serializers\SnakSerializer;
use Wikibase\DataModel\Serializers\SnaksSerializer;
use InvalidArgumentException;

/**
* Factory for constructing Serializer objects that can serialize WikibaseDataModel objects.
Expand All @@ -25,16 +26,37 @@
*/
class SerializerFactory {

const OPTION_DEFAULT = 0;
const OPTION_OBJECTS_FOR_MAPS = 1;
const OPTION_MAXIMUM_VALUE = 1;

/**
* @var integer $options
*/
private $options = 0;

/**
* @var Serializer
*/
private $dataValueSerializer;

/**
* @param Serializer $dataValueSerializer serializer for DataValue objects
* @param integer $options set multiple with bitwise or
*/
public function __construct( Serializer $dataValueSerializer ) {
public function __construct( Serializer $dataValueSerializer, $options = 0 ) {
$this->dataValueSerializer = $dataValueSerializer;
if ( $options > self::OPTION_MAXIMUM_VALUE ) {
throw new InvalidArgumentException('The value of argument 2 $options must be less than 1.');
}
$this->options = $options;
}

/**
* @return bool
*/
private function shouldUseObjectsForMaps() {
return (bool)( $this->options & self::OPTION_OBJECTS_FOR_MAPS );
}

/**
Expand All @@ -43,9 +65,9 @@ public function __construct( Serializer $dataValueSerializer ) {
* @return Serializer
*/
public function newEntitySerializer() {
$fingerprintSerializer = new FingerprintSerializer();
$fingerprintSerializer = new FingerprintSerializer( $this->shouldUseObjectsForMaps() );
return new DispatchingSerializer( array(
new ItemSerializer( $fingerprintSerializer, $this->newClaimsSerializer(), $this->newSiteLinkSerializer() ),
new ItemSerializer( $fingerprintSerializer, $this->newClaimsSerializer(), $this->newSiteLinkSerializer(), $this->shouldUseObjectsForMaps() ),
new PropertySerializer( $fingerprintSerializer, $this->newClaimsSerializer() ),
) );
}
Expand All @@ -65,7 +87,7 @@ public function newSiteLinkSerializer() {
* @return Serializer
*/
public function newClaimsSerializer() {
return new ClaimsSerializer( $this->newClaimSerializer() );
return new ClaimsSerializer( $this->newClaimSerializer(), $this->shouldUseObjectsForMaps() );
}

/**
Expand Down Expand Up @@ -101,7 +123,7 @@ public function newReferenceSerializer() {
* @return Serializer
*/
public function newSnaksSerializer() {
return new SnaksSerializer( $this->newSnakSerializer() );
return new SnaksSerializer( $this->newSnakSerializer(), $this->shouldUseObjectsForMaps() );
}

/**
Expand Down
12 changes: 11 additions & 1 deletion src/Serializers/ClaimsSerializer.php
Expand Up @@ -22,11 +22,18 @@ class ClaimsSerializer implements DispatchableSerializer {
*/
protected $claimSerializer;

/**
* @var bool
*/
protected $useObjectsForMaps;

/**
* @param Serializer $claimSerializer
* @param bool $useObjectsForMaps
*/
public function __construct( Serializer $claimSerializer ) {
public function __construct( Serializer $claimSerializer, $useObjectsForMaps ) {
$this->claimSerializer = $claimSerializer;
$this->useObjectsForMaps = $useObjectsForMaps;
}

/**
Expand Down Expand Up @@ -69,6 +76,9 @@ private function getSerialized( Claims $claims ) {
$serialization[$claim->getMainSnak()->getPropertyId()->getPrefixedId()][] = $this->claimSerializer->serialize( $claim );
}

if ( $this->useObjectsForMaps ) {
$serialization = (object)$serialization;
}
return $serialization;
}

Expand Down
18 changes: 18 additions & 0 deletions src/Serializers/FingerprintSerializer.php
Expand Up @@ -17,6 +17,18 @@
*/
class FingerprintSerializer {

/**
* @var bool
*/
protected $useObjectsForMaps;

/**
* @param bool $useObjectsForMaps
*/
public function __construct( $useObjectsForMaps ) {
$this->useObjectsForMaps = $useObjectsForMaps;
}

public function addBasicsToSerialization( Entity $entity, array &$serialization ) {
$this->addIdToSerialization( $entity, $serialization );
$this->addLabelsToSerialization( $entity, $serialization );
Expand Down Expand Up @@ -56,6 +68,9 @@ private function serializeValuePerLanguageArray( array $array ) {
);
}

if ( $this->useObjectsForMaps ) {
$serialization = (object)$serialization;
}
return $serialization;
}

Expand All @@ -77,6 +92,9 @@ private function serializeValuesPerLanguageArray( $array ) {
}
}

if ( $this->useObjectsForMaps ) {
$serialization = (object)$serialization;
}
return $serialization;
}

Expand Down
13 changes: 12 additions & 1 deletion src/Serializers/ItemSerializer.php
Expand Up @@ -35,13 +35,21 @@ class ItemSerializer implements DispatchableSerializer {
private $siteLinkSerializer;

/**
* @var bool
*/
protected $useObjectsForMaps;

/**
* @param FingerprintSerializer $fingerprintSerializer
* @param Serializer $claimsSerializer
* @param Serializer $siteLinkSerializer
* @param bool $useObjectsForMaps
*/
public function __construct( FingerprintSerializer $fingerprintSerializer, Serializer $claimsSerializer, Serializer $siteLinkSerializer ) {
public function __construct( FingerprintSerializer $fingerprintSerializer, Serializer $claimsSerializer, Serializer $siteLinkSerializer, $useObjectsForMaps ) {
$this->fingerprintSerializer = $fingerprintSerializer;
$this->claimsSerializer = $claimsSerializer;
$this->siteLinkSerializer = $siteLinkSerializer;
$this->useObjectsForMaps = $useObjectsForMaps;
}

/**
Expand Down Expand Up @@ -100,6 +108,9 @@ private function addSiteLinksToSerialization( Item $item, array &$serialization
foreach( $siteLinks as $siteLink ) {
$serialization['sitelinks'][$siteLink->getSiteId()] = $this->siteLinkSerializer->serialize( $siteLink );
}
if ( $this->useObjectsForMaps ) {
$serialization['sitelinks'] = (object)$serialization['sitelinks'];
}
}

}
12 changes: 11 additions & 1 deletion src/Serializers/SnaksSerializer.php
Expand Up @@ -22,11 +22,18 @@ class SnaksSerializer implements DispatchableSerializer {
*/
protected $snakSerializer;

/**
* @var bool
*/
protected $useObjectsForMaps;

/**
* @param Serializer $snakSerializer
* @param bool $useObjectsForMaps
*/
public function __construct( Serializer $snakSerializer ) {
public function __construct( Serializer $snakSerializer, $useObjectsForMaps ) {
$this->snakSerializer = $snakSerializer;
$this->useObjectsForMaps = $useObjectsForMaps;
}

/**
Expand Down Expand Up @@ -69,6 +76,9 @@ private function getSerialized( Snaks $snaks ) {
$serialization[$snak->getPropertyId()->getPrefixedId()][] = $this->snakSerializer->serialize( $snak );
}

if ( $this->useObjectsForMaps ) {
$serialization = (object)$serialization;
}
return $serialization;
}

Expand Down
11 changes: 11 additions & 0 deletions tests/unit/SerializerFactoryTest.php
Expand Up @@ -91,4 +91,15 @@ public function testNewSnakSerializer() {
);
}

public function testFactoryCreateWithUnexpectedValue() {
$this->setExpectedException( 'InvalidArgumentException' );
new SerializerFactory( new DataValueSerializer(), 2 );
}

public function testNewSnaksSerializerWithUseObjectsForMaps() {
$factory = new SerializerFactory( new DataValueSerializer(), SerializerFactory::OPTION_OBJECTS_FOR_MAPS );
$serializer = $factory->newSnaksSerializer();
$this->assertAttributeSame( true, 'useObjectsForMaps' , $serializer );
}

}
27 changes: 26 additions & 1 deletion tests/unit/Serializers/ClaimsSerializerTest.php
Expand Up @@ -6,6 +6,7 @@
use Wikibase\DataModel\Claim\Claims;
use Wikibase\DataModel\Serializers\ClaimsSerializer;
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
use stdClass;

/**
* @covers Wikibase\DataModel\Serializers\ClaimsSerializer
Expand All @@ -32,7 +33,7 @@ protected function buildSerializer() {
'rank' => 'normal'
) ) );

return new ClaimsSerializer( $claimSerializerMock );
return new ClaimsSerializer( $claimSerializerMock, false );
}

public function serializableProvider() {
Expand Down Expand Up @@ -93,4 +94,28 @@ public function serializationProvider() {
),
);
}

public function testClaimsSerializerWithOptionObjectsForMaps() {
$claim = new Claim( new PropertyNoValueSnak( 42 ) );
$claim->setGuid( 'test' );
$claimSerializerMock = $this->getMock( '\Serializers\Serializer' );
$claimSerializerMock->expects( $this->any() )
->method( 'serialize' )
->with( $this->equalTo( $claim ) )
->will( $this->returnValue( array(
'mockedsuff' => array(),
'type' => 'statement',
) ) );
$serializer = new ClaimsSerializer( $claimSerializerMock, true );

$claims = new Claims( array( $claim ) );

$serial = new stdClass();
$serial->P42 = array( array(
'mockedsuff' => array(),
'type' => 'statement',
) );
$this->assertEquals( $serial, $serializer->serialize( $claims ) );
}

}
43 changes: 41 additions & 2 deletions tests/unit/Serializers/FingerprintSerializerTest.php
Expand Up @@ -10,6 +10,7 @@
use Wikibase\DataModel\Serializers\FingerprintSerializer;
use Wikibase\DataModel\Serializers\ItemSerializer;
use Wikibase\DataModel\SiteLink;
use stdClass;

/**
* @covers Wikibase\DataModel\Serializers\EntitySerializer
Expand All @@ -31,9 +32,9 @@ protected function buildSerializer() {
$siteLinkSerializerMock->expects( $this->any() )
->method( 'serialize' );

$entitySerializer = new FingerprintSerializer();
$entitySerializer = new FingerprintSerializer( false );

return new ItemSerializer( $entitySerializer, $claimsSerializerMock, $siteLinkSerializerMock );
return new ItemSerializer( $entitySerializer, $claimsSerializerMock, $siteLinkSerializerMock, false );
}

public function serializableProvider() {
Expand Down Expand Up @@ -175,4 +176,42 @@ public function serializationProvider() {
return $argumentLists;
}

public function testDescriptionWithOptionObjectsForMaps() {
$entitySerializer = new FingerprintSerializer( true );

$entity = Item::newEmpty();
$entity->setDescriptions( array(
'en' => 'A Nyan Cat',
) );

$result = array();

$descriptions = new stdClass();
$descriptions->en = array(
'language' => 'en',
'value' => 'A Nyan Cat'
);
$serial = array( 'descriptions' => $descriptions );
$entitySerializer->addDescriptionsToSerialization( $entity, $result );
$this->assertEquals( $serial, $result );
}

public function testAliasesWithOptionObjectsForMaps() {
$entitySerializer = new FingerprintSerializer( true );

$entity = Item::newEmpty();
$entity->setAliases( 'fr', array( 'Cat' ) );

$result = array();

$aliases = new stdClass();
$aliases->fr = array( array(
'language' => 'fr',
'value' => 'Cat'
) );
$serial = array( 'aliases' => $aliases );
$entitySerializer->addAliasesToSerialization( $entity, $result );
$this->assertEquals( $serial, $result );
}

}
46 changes: 44 additions & 2 deletions tests/unit/Serializers/ItemSerializerTest.php
Expand Up @@ -10,6 +10,7 @@
use Wikibase\DataModel\Serializers\ItemSerializer;
use Wikibase\DataModel\Serializers\FingerprintSerializer;
use Wikibase\DataModel\SiteLink;
use stdClass;

/**
* @covers Wikibase\DataModel\Serializers\ItemSerializer
Expand Down Expand Up @@ -53,9 +54,9 @@ protected function buildSerializer() {
'badges' => array()
) ) );

$fingerprintSerializer = new FingerprintSerializer();
$fingerprintSerializer = new FingerprintSerializer( false );

return new ItemSerializer( $fingerprintSerializer, $claimsSerializerMock, $siteLinkSerializerMock );
return new ItemSerializer( $fingerprintSerializer, $claimsSerializerMock, $siteLinkSerializerMock, false );
}

public function serializableProvider() {
Expand Down Expand Up @@ -143,4 +144,45 @@ public function serializationProvider() {
return $provider;
}

public function testItemSerializerWithOptionObjectsForMaps() {
$claimsSerializerMock = $this->getMock( '\Serializers\Serializer' );
$claimsSerializerMock->expects( $this->any() )
->method( 'serialize' )
->with( $this->equalTo( new Claims() ) )
->will( $this->returnValue( array() ) );

$siteLinkSerializerMock = $this->getMock( '\Serializers\Serializer' );
$siteLinkSerializerMock->expects( $this->any() )
->method( 'serialize' )
->with( $this->equalTo( new SiteLink( 'enwiki', 'Nyan Cat' ) ) )
->will( $this->returnValue( array(
'site' => 'enwiki',
'title' => 'Nyan Cat',
'badges' => array()
) ) );

$fingerprintSerializer = new FingerprintSerializer( false );

$serializer = new ItemSerializer( $fingerprintSerializer, $claimsSerializerMock, $siteLinkSerializerMock, true );

$item = Item::newEmpty();
$item->addSiteLink( new SiteLink( 'enwiki', 'Nyan Cat' ) );

$sitelinks = new stdClass();
$sitelinks->enwiki = array(
'site' => 'enwiki',
'title' => 'Nyan Cat',
'badges' => array(),
);
$serial = array(
'type' => 'item',
'labels' => array(),
'descriptions' => array(),
'aliases' => array(),
'claims' => array(),
'sitelinks' => $sitelinks,
);
$this->assertEquals( $serial, $serializer->serialize( $item ) );
}

}

0 comments on commit 83e9999

Please sign in to comment.