Daniel Werner has submitted this change and it was merged.

Change subject: Added equals and getHash methods to descriptions
......................................................................


Added equals and getHash methods to descriptions

Change-Id: Ibef9a25c2f66f962b2c191726bfa8142b94c1fa6
---
M Ask.classes.php
A includes/Ask/Comparable.php
A includes/Ask/Hashable.php
M includes/Ask/Language/Description/AnyValue.php
M includes/Ask/Language/Description/Conjunction.php
M includes/Ask/Language/Description/Description.php
M includes/Ask/Language/Description/DescriptionCollection.php
M includes/Ask/Language/Description/Disjunction.php
M includes/Ask/Language/Description/SomeProperty.php
M includes/Ask/Language/Description/ValueDescription.php
M tests/phpunit/Language/Description/DescriptionTest.php
11 files changed, 288 insertions(+), 8 deletions(-)

Approvals:
  Daniel Werner: Verified; Looks good to me, approved
  Daniel Kinzler: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/Ask.classes.php b/Ask.classes.php
index 6b17b9f..d7abad6 100644
--- a/Ask.classes.php
+++ b/Ask.classes.php
@@ -17,6 +17,8 @@
 
        $classes = array(
                'Ask\Arrayable',
+               'Ask\Comparable',
+               'Ask\Hashable',
                'Ask\Immutable',
 
                'Ask\Language\Description\AnyValue',
diff --git a/includes/Ask/Comparable.php b/includes/Ask/Comparable.php
new file mode 100644
index 0000000..e3be6c6
--- /dev/null
+++ b/includes/Ask/Comparable.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Ask;
+
+/**
+ * Interface for comparable objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+interface Comparable extends \Comparable {};
\ No newline at end of file
diff --git a/includes/Ask/Hashable.php b/includes/Ask/Hashable.php
new file mode 100644
index 0000000..c47322b
--- /dev/null
+++ b/includes/Ask/Hashable.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Ask;
+
+/**
+ * Interface for hashable objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.1
+ *
+ * @file
+ * @ingroup Ask
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+interface Hashable extends \Hashable {};
\ No newline at end of file
diff --git a/includes/Ask/Language/Description/AnyValue.php 
b/includes/Ask/Language/Description/AnyValue.php
index 0ccde37..334c917 100644
--- a/includes/Ask/Language/Description/AnyValue.php
+++ b/includes/Ask/Language/Description/AnyValue.php
@@ -32,7 +32,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-class AnyValue extends  Description implements \Ask\Immutable {
+final class AnyValue extends Description implements \Ask\Immutable {
 
        /**
         * {@inheritdoc}
@@ -78,4 +78,28 @@
                return null;
        }
 
-}
\ No newline at end of file
+       /**
+        * @see Comparable::equals
+        *
+        * @since 0.1
+        *
+        * @param mixed $mixed
+        *
+        * @return boolean
+        */
+       public function equals( $mixed ) {
+               return $mixed instanceof AnyValue;
+       }
+
+       /**
+        * @see Hashable::getHash
+        *
+        * @since 0.1
+        *
+        * @return string
+        */
+       public function getHash() {
+               return sha1( $this->getType() );
+       }
+
+}
diff --git a/includes/Ask/Language/Description/Conjunction.php 
b/includes/Ask/Language/Description/Conjunction.php
index cbc721a..172b9e7 100644
--- a/includes/Ask/Language/Description/Conjunction.php
+++ b/includes/Ask/Language/Description/Conjunction.php
@@ -33,7 +33,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-class Conjunction extends DescriptionCollection {
+final class Conjunction extends DescriptionCollection {
 
        /**
         * {@inheritdoc}
diff --git a/includes/Ask/Language/Description/Description.php 
b/includes/Ask/Language/Description/Description.php
index f767588..f7b5e66 100644
--- a/includes/Ask/Language/Description/Description.php
+++ b/includes/Ask/Language/Description/Description.php
@@ -30,7 +30,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-abstract class Description implements \Ask\Arrayable {
+abstract class Description implements \Ask\Arrayable, \Ask\Comparable, 
\Ask\Hashable {
 
        /**
         * Returns the size of the description.
diff --git a/includes/Ask/Language/Description/DescriptionCollection.php 
b/includes/Ask/Language/Description/DescriptionCollection.php
index 82a06f7..3b07e81 100644
--- a/includes/Ask/Language/Description/DescriptionCollection.php
+++ b/includes/Ask/Language/Description/DescriptionCollection.php
@@ -2,6 +2,8 @@
 
 namespace Ask\Language\Description;
 
+use Ask\Hashable;
+
 /**
  * Description of a collection of many descriptions.
  *
@@ -28,7 +30,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-abstract class DescriptionCollection extends  Description implements 
\Ask\Immutable {
+abstract class DescriptionCollection extends Description implements 
\Ask\Immutable {
 
        /**
         * @since 0.1
@@ -115,4 +117,78 @@
                );
        }
 
+       /**
+        * @see Comparable::equals
+        *
+        * @since 0.1
+        *
+        * @param mixed $mixed
+        *
+        * @return boolean
+        */
+       public function equals( $mixed ) {
+               if ( !is_object( $mixed )
+                       || ( get_class( $mixed ) !== get_called_class() ) ) {
+                       return false;
+               }
+
+               $descriptions = $this->descriptions;
+               $moreDescriptions = $mixed->getDescriptions();
+
+               if ( count( $descriptions ) !== count( $moreDescriptions ) ) {
+                       return false;
+               }
+
+               $this->sortCollection( $this->descriptions );
+               $this->sortCollection( $this->descriptions );
+               reset( $moreDescriptions );
+
+               foreach ( $descriptions as $description ) {
+                       if ( !$description->equals( current( $moreDescriptions 
) ) ) {
+                               return false;
+                       }
+
+                       next( $moreDescriptions );
+               }
+
+               return true;
+       }
+
+       /**
+        * @see Hashable::getHash
+        *
+        * @since 0.1
+        *
+        * @return string
+        */
+       public function getHash() {
+               $this->sortCollection( $this->descriptions );
+
+               return sha1( implode(
+                       '|',
+                       array_map(
+                               function( Hashable $hashable ) {
+                                       return $hashable->getHash();
+                               },
+                               $this->descriptions
+                       )
+               ) );
+       }
+
+       /**
+        * Does an associative sort that works for Hashable objects.
+        *
+        * @since 0.1
+        *
+        * @param Hashable[] $array
+        */
+       protected function sortCollection( array &$array ) {
+               usort(
+                       $array,
+                       function ( Hashable $a, Hashable $b ) {
+                               return $a->getHash() > $b->getHash() ? 1 : -1;
+                       }
+               );
+       }
+
 }
diff --git a/includes/Ask/Language/Description/Disjunction.php 
b/includes/Ask/Language/Description/Disjunction.php
index 243b6fd..5c1d2ef 100644
--- a/includes/Ask/Language/Description/Disjunction.php
+++ b/includes/Ask/Language/Description/Disjunction.php
@@ -33,7 +33,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-class Disjunction extends DescriptionCollection {
+final class Disjunction extends DescriptionCollection {
 
        /**
         * {@inheritdoc}
diff --git a/includes/Ask/Language/Description/SomeProperty.php 
b/includes/Ask/Language/Description/SomeProperty.php
index fc22ae8..a2622b3 100644
--- a/includes/Ask/Language/Description/SomeProperty.php
+++ b/includes/Ask/Language/Description/SomeProperty.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Ask\Language\Description;
+
 use DataValues\PropertyValue;
 
 /**
@@ -36,7 +37,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-class SomeProperty extends Description implements \Ask\Immutable {
+final class SomeProperty extends Description implements \Ask\Immutable {
 
        /**
         * @since 0.1
@@ -134,4 +135,30 @@
                );
        }
 
+       /**
+        * @see Comparable::equals
+        *
+        * @since 0.1
+        *
+        * @param mixed $mixed
+        *
+        * @return boolean
+        */
+       public function equals( $mixed ) {
+               return $mixed instanceof SomeProperty
+                       && $this->property->equals( $mixed->getProperty() )
+                       && $this->description->equals( $mixed->getDescription() 
);
+       }
+
+       /**
+        * @see Hashable::getHash
+        *
+        * @since 0.1
+        *
+        * @return string
+        */
+       public function getHash() {
+               return sha1( $this->property->getHash() . 
$this->description->getHash() );
+       }
+
 }
diff --git a/includes/Ask/Language/Description/ValueDescription.php 
b/includes/Ask/Language/Description/ValueDescription.php
index 7255bfa..21a9d93 100644
--- a/includes/Ask/Language/Description/ValueDescription.php
+++ b/includes/Ask/Language/Description/ValueDescription.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Ask\Language\Description;
+
 use DataValues\DataValue;
 use InvalidArgumentException;
 
@@ -39,7 +40,7 @@
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < [email protected] >
  */
-class ValueDescription extends  Description implements \Ask\Immutable {
+final class ValueDescription extends  Description implements \Ask\Immutable {
 
        const COMP_EQUAL = 1;
        const COMP_LEQ = 2; // Less than or equal
@@ -152,4 +153,30 @@
                return 'valuedescription';
        }
 
+       /**
+        * @see Comparable::equals
+        *
+        * @since 0.1
+        *
+        * @param mixed $mixed
+        *
+        * @return boolean
+        */
+       public function equals( $mixed ) {
+               return $mixed instanceof ValueDescription
+                       && $this->comparator === $mixed->getComparator()
+                       && $this->value->equals( $mixed->getValue() );
+       }
+
+       /**
+        * @see Hashable::getHash
+        *
+        * @since 0.1
+        *
+        * @return string
+        */
+       public function getHash() {
+               return sha1( $this->value->getHash() . $this->comparator );
+       }
+
 }
diff --git a/tests/phpunit/Language/Description/DescriptionTest.php 
b/tests/phpunit/Language/Description/DescriptionTest.php
index 391e471..43da1ca 100644
--- a/tests/phpunit/Language/Description/DescriptionTest.php
+++ b/tests/phpunit/Language/Description/DescriptionTest.php
@@ -131,4 +131,66 @@
                }
        }
 
+       /**
+        * @dataProvider instanceProvider
+        *
+        * @since 0.1
+        *
+        * @param Description $description
+        */
+       public function testComparableSelfIsEqual( Description $description ) {
+               $this->assertTrue( $description->equals( $description ), 
'Description is equal to itself' );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        *
+        * @since 0.1
+        *
+        * @param Description $description
+        */
+       public function testComparableNotEqual( Description $description ) {
+               $this->assertFalse( $description->equals( '~[,,_,,]:3' ), 
'Description not equal to string' );
+               $this->assertFalse( $description->equals( new \stdClass() ), 
'Description not equal to empty object' );
+               $this->assertFalse( $description->equals( new FooDescription() 
), 'Description not equal to empty object' );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        *
+        * @since 0.1
+        *
+        * @param Description $description
+        */
+       public function testGetHashReturnType( Description $description ) {
+               $this->assertInternalType( 'string', $description->getHash() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        *
+        * @since 0.1
+        *
+        * @param Description $description
+        */
+       public function testGetHashStability( Description $description ) {
+               $this->assertEquals( $description->getHash(), 
$description->getHash() );
+       }
+
+}
+
+class FooDescription extends \Ask\Language\Description\DescriptionCollection {
+
+       public function __construct() {
+               parent::__construct( array() );
+       }
+
+       public function getType() {
+               return 'foo';
+       }
+
+       public function equals( $t ) {
+               return false;
+       }
+
 }
\ No newline at end of file

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ibef9a25c2f66f962b2c191726bfa8142b94c1fa6
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Ask
Gerrit-Branch: master
Gerrit-Owner: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: John Erling Blad <[email protected]>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to