Jeroen De Dauw has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/70331


Change subject: Added first serialization code
......................................................................

Added first serialization code

The idea here is to implement serialization and unserialization using
the "canHandle" pattern as suggested we do in this case by Tobias Schlitt

Change-Id: I07ca8cc2b9981078755fd25617e9251fd0d9ce9f
---
A Tests/Phpunit/Serializers/AskSerializerTest.php
A Tests/Phpunit/Serializers/DescriptionSerializerTest.php
A Tests/Phpunit/Serializers/Exceptions/UnsupportedObjectExceptionTest.php
A includes/Ask/Serializers/AskSerializer.php
A includes/Ask/Serializers/DescriptionSerializer.php
A includes/Ask/Serializers/Exceptions/SerializationException.php
A includes/Ask/Serializers/Exceptions/UnsupportedObjectException.php
A includes/Ask/Serializers/Serializer.php
8 files changed, 412 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Ask 
refs/changes/31/70331/1

diff --git a/Tests/Phpunit/Serializers/AskSerializerTest.php 
b/Tests/Phpunit/Serializers/AskSerializerTest.php
new file mode 100644
index 0000000..29a93a2
--- /dev/null
+++ b/Tests/Phpunit/Serializers/AskSerializerTest.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace Ask\Tests\Serializers;
+
+use Ask\Serializers\AskSerializer;
+
+/**
+ * @covers Ask\Serializers\AskSerializer
+ *
+ * @file
+ * @since 0.1
+ *
+ * @ingroup Ask
+ * @group Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class AskSerializerTest extends \PHPUnit_Framework_TestCase {
+
+       public function testConstructWithNoSerializers() {
+               $serializer = new AskSerializer( array() );
+
+               $this->assertFalse( $serializer->canSerialize( 'foo' ) );
+               $this->assertFalse( $serializer->canSerialize( null ) );
+
+               $this->setExpectedException( 
'Ask\Serializers\Exceptions\UnsupportedObjectException' );
+
+               $serializer->serialize( 'foo' );
+       }
+
+       public function testConstructWithInvalidArgumentsCausesException() {
+               $this->setExpectedException( 'InvalidArgumentException' );
+               new AskSerializer( array( new \stdClass() ) );
+       }
+
+       public function testCanSerialize() {
+               $subSerializer = $this->getMock( 'Ask\Serializers\Serializer' );
+
+               $subSerializer->expects( $this->exactly( 4 ) )
+                       ->method( 'canSerialize' )
+                       ->will( $this->returnCallback( function( $value ) {
+                               return $value > 9000;
+                       } ) );
+
+               $serializer = new AskSerializer( array( $subSerializer ) );
+
+               $this->assertFalse( $serializer->canSerialize( 0 ) );
+               $this->assertFalse( $serializer->canSerialize( 42 ) );
+               $this->assertTrue( $serializer->canSerialize( 9001 ) );
+               $this->assertTrue( $serializer->canSerialize( 31337 ) );
+       }
+
+       public function testSerializeWithSerializableValues() {
+               $subSerializer = $this->getMock( 'Ask\Serializers\Serializer' );
+
+               $subSerializer->expects( $this->any() )
+                       ->method( 'canSerialize' )
+                       ->will( $this->returnValue( true ) );
+
+               $subSerializer->expects( $this->any() )
+                       ->method( 'serialize' )
+                       ->will( $this->returnValue( 42 ) );
+
+               $serializer = new AskSerializer( array( $subSerializer ) );
+
+               $this->assertEquals( 42, $serializer->serialize( 'foo' ) );
+               $this->assertEquals( 42, $serializer->serialize( null ) );
+       }
+
+       public function testSerializeWithUnserializableValue() {
+               $subSerializer = $this->getMock( 'Ask\Serializers\Serializer' );
+
+               $subSerializer->expects( $this->once() )
+                       ->method( 'canSerialize' )
+                       ->will( $this->returnValue( false ) );
+
+               $serializer = new AskSerializer( array( $subSerializer ) );
+
+               $this->setExpectedException( 
'Ask\Serializers\Exceptions\UnsupportedObjectException' );
+               $serializer->serialize( 0 );
+       }
+
+       public function testSerializeWithMultipleSubSerializers() {
+               $subSerializer0 = $this->getMock( 'Ask\Serializers\Serializer' 
);
+
+               $subSerializer0->expects( $this->any() )
+                       ->method( 'canSerialize' )
+                       ->will( $this->returnValue( true ) );
+
+               $subSerializer0->expects( $this->any() )
+                       ->method( 'serialize' )
+                       ->will( $this->returnValue( 42 ) );
+
+               $subSerializer1 = $this->getMock( 'Ask\Serializers\Serializer' 
);
+
+               $subSerializer1->expects( $this->any() )
+                       ->method( 'canSerialize' )
+                       ->will( $this->returnValue( false ) );
+
+               $subSerializer2 = clone $subSerializer1;
+
+               $serializer = new AskSerializer( array( $subSerializer1, 
$subSerializer0, $subSerializer2 ) );
+
+               $this->assertEquals( 42, $serializer->serialize( 'foo' ) );
+       }
+
+}
diff --git a/Tests/Phpunit/Serializers/DescriptionSerializerTest.php 
b/Tests/Phpunit/Serializers/DescriptionSerializerTest.php
new file mode 100644
index 0000000..63e1aa3
--- /dev/null
+++ b/Tests/Phpunit/Serializers/DescriptionSerializerTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Ask\Tests\Serializers;
+
+use Ask\Serializers\DescriptionSerializer;
+
+/**
+ * @covers Ask\Serializers\DescriptionSerializer
+ *
+ * @file
+ * @since 0.1
+ *
+ * @ingroup Ask
+ * @group Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class DescriptionSerializerTest extends \PHPUnit_Framework_TestCase {
+
+       public function testSerializeDescription() {
+               $description = $this->getMock( 
'Ask\Language\Description\Description' );
+
+               // We unfortunately cannot mock out toArray as it is final.
+               $description->expects( $this->once() )
+                       ->method( 'getType' )
+                       ->will( $this->returnValue( 'the' ) );
+
+               $description->expects( $this->once() )
+                       ->method( 'getArrayValue' )
+                       ->will( $this->returnValue( 'game' ) );
+
+               $serializer = new DescriptionSerializer();
+               $actualSerialization = $serializer->serialize( $description );
+
+               $expectedSerialization = array(
+                       'type' => 'the',
+                       'value' => 'game',
+               );
+
+               $this->assertEquals( $expectedSerialization, 
$actualSerialization );
+       }
+
+       /**
+        * @dataProvider nonDescriptionProvider
+        */
+       public function testCannotSerializeNonDescriptions( $notADescription ) {
+               $serializer = new DescriptionSerializer();
+
+               $this->assertFalse( $serializer->canSerialize( $notADescription 
) );
+
+               $this->setExpectedException( 
'Ask\Serializers\Exceptions\UnsupportedObjectException' );
+               $serializer->serialize( $notADescription );
+       }
+
+       public function nonDescriptionProvider() {
+               $argLists = array();
+
+               $argLists[] = array( null );
+               $argLists[] = array( 'foo bar' );
+               $argLists[] = array( new \stdClass() );
+               $argLists[] = array( array() );
+               $argLists[] = array( 42 );
+
+               return $argLists;
+       }
+
+}
diff --git 
a/Tests/Phpunit/Serializers/Exceptions/UnsupportedObjectExceptionTest.php 
b/Tests/Phpunit/Serializers/Exceptions/UnsupportedObjectExceptionTest.php
new file mode 100644
index 0000000..c4d0c6d
--- /dev/null
+++ b/Tests/Phpunit/Serializers/Exceptions/UnsupportedObjectExceptionTest.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Ask\Tests\Serializers\Exceptions;
+
+use Ask\Serializers\Exceptions\UnsupportedObjectException;
+
+/**
+ * @covers Ask\Serializers\Exceptions\UnsupportedObjectException
+ *
+ * @file
+ * @since 0.1
+ *
+ * @ingroup Ask
+ * @group Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class UnsupportedObjectExceptionTest extends \PHPUnit_Framework_TestCase {
+
+       public function testConstructorWithOnlyRequiredArguments() {
+               $object = (object)array( 'the' => 'game' );
+               $serializer = $this->getMock( 'Ask\Serializers\Serializer' );
+
+               $exception = new UnsupportedObjectException( $object, 
$serializer );
+
+               $this->assertRequiredFieldsAreSet( $exception, $object, 
$serializer );
+       }
+
+       public function testConstructorWithAllArguments() {
+               $object = (object)array( 'the' => 'game' );
+               $serializer = $this->getMock( 'Ask\Serializers\Serializer' );
+               $message = 'NyanData all the way across the sky!';
+               $previous = new \Exception( 'Onoez!' );
+
+               $exception = new UnsupportedObjectException( $object, 
$serializer, $message, $previous );
+
+               $this->assertRequiredFieldsAreSet( $exception, $object, 
$serializer );
+               $this->assertEquals( $message, $exception->getMessage() );
+               $this->assertEquals( $previous, $exception->getPrevious() );
+       }
+
+       protected function assertRequiredFieldsAreSet( 
UnsupportedObjectException $exception, $object, $serializer ) {
+               $this->assertEquals( $object, 
$exception->getUnsupportedObject() );
+               $this->assertEquals( $serializer, $exception->getSerializer() );
+       }
+
+}
diff --git a/includes/Ask/Serializers/AskSerializer.php 
b/includes/Ask/Serializers/AskSerializer.php
new file mode 100644
index 0000000..9481700
--- /dev/null
+++ b/includes/Ask/Serializers/AskSerializer.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Ask\Serializers;
+
+use Ask\Serializers\Exceptions\UnsupportedObjectException;
+use InvalidArgumentException;
+
+/**
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class AskSerializer implements Serializer {
+
+       /**
+        * @var Serializer[]
+        */
+       protected $serializers;
+
+       public function __construct( array $serializers ) {
+               $this->assertAreSerializers( $serializers );
+               $this->serializers = $serializers;
+       }
+
+       protected function assertAreSerializers( array $serializers ) {
+               foreach ( $serializers as $serializer ) {
+                       if ( !( $serializer instanceof Serializer ) ) {
+                               throw new InvalidArgumentException( 'Got an 
object that is not an instance of Ask\Serializers\Serializer' );
+                       }
+               }
+       }
+
+       public function serialize( $askObject ) {
+               foreach ( $this->serializers as $serializer ) {
+                       if ( $serializer->canSerialize( $askObject ) ) {
+                               return $serializer->serialize( $askObject );
+                       }
+               }
+
+               throw new UnsupportedObjectException( $askObject, $this );
+       }
+
+       public function canSerialize( $askObject ) {
+               foreach ( $this->serializers as $serializer ) {
+                       if ( $serializer->canSerialize( $askObject ) ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+}
diff --git a/includes/Ask/Serializers/DescriptionSerializer.php 
b/includes/Ask/Serializers/DescriptionSerializer.php
new file mode 100644
index 0000000..471fab5
--- /dev/null
+++ b/includes/Ask/Serializers/DescriptionSerializer.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Ask\Serializers;
+
+use Ask\Language\Description\Description;
+use Ask\Serializers\Exceptions\UnsupportedObjectException;
+
+/**
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class DescriptionSerializer implements Serializer {
+
+       public function serialize( $askObject ) {
+               if ( $askObject instanceof Description ) {
+                       return $askObject->toArray();
+               }
+
+               throw new UnsupportedObjectException( $askObject, $this );
+       }
+
+       public function canSerialize( $askObject ) {
+               return $askObject instanceof Description;
+       }
+
+}
diff --git a/includes/Ask/Serializers/Exceptions/SerializationException.php 
b/includes/Ask/Serializers/Exceptions/SerializationException.php
new file mode 100644
index 0000000..c12d862
--- /dev/null
+++ b/includes/Ask/Serializers/Exceptions/SerializationException.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Ask\Serializers\Exceptions;
+
+use Ask\Serializers\Serializer;
+
+/**
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+abstract class SerializationException extends \RuntimeException {
+
+       protected $serializer;
+
+       public function __construct( Serializer $serializer, $message = '', 
\Exception $previous = null ) {
+               $this->serializer = $serializer;
+
+               parent::__construct( $message, 0, $previous );
+       }
+
+       /**
+        * @return Serializer
+        */
+       public function getSerializer() {
+               return $this->serializer;
+       }
+
+}
diff --git a/includes/Ask/Serializers/Exceptions/UnsupportedObjectException.php 
b/includes/Ask/Serializers/Exceptions/UnsupportedObjectException.php
new file mode 100644
index 0000000..634f63a
--- /dev/null
+++ b/includes/Ask/Serializers/Exceptions/UnsupportedObjectException.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Ask\Serializers\Exceptions;
+
+use Ask\Serializers\Serializer;
+
+/**
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class UnsupportedObjectException extends SerializationException {
+
+       protected $unsupportedObject;
+
+       public function __construct( $unsupportedObject, Serializer 
$serializer, $message = '', \Exception $previous = null ) {
+               $this->unsupportedObject = $unsupportedObject;
+
+               parent::__construct( $serializer, $message, $previous );
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getUnsupportedObject() {
+               return $this->unsupportedObject;
+       }
+
+}
diff --git a/includes/Ask/Serializers/Serializer.php 
b/includes/Ask/Serializers/Serializer.php
new file mode 100644
index 0000000..d0735a9
--- /dev/null
+++ b/includes/Ask/Serializers/Serializer.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Ask\Serializers;
+
+/**
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+interface Serializer {
+
+       /**
+        * @since 0.1
+        *
+        * @param mixed $askObject
+        *
+        * @return array|int|string|bool|float A possibly nested structure 
consisting of only arrays and scalar values
+        */
+       public function serialize( $askObject );
+
+       /**
+        * @since 0.1
+        *
+        * @param mixed $askObject
+        *
+        * @return boolean
+        */
+       public function canSerialize( $askObject );
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/70331
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I07ca8cc2b9981078755fd25617e9251fd0d9ce9f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Ask
Gerrit-Branch: master
Gerrit-Owner: Jeroen De Dauw <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to