Jeroen De Dauw has uploaded a new change for review.
https://gerrit.wikimedia.org/r/49860
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(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Ask
refs/changes/60/49860/1
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: newchange
Gerrit-Change-Id: Ibef9a25c2f66f962b2c191726bfa8142b94c1fa6
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