[MediaWiki-commits] [Gerrit] Made SnakList/Reference order-aware - change (mediawiki...WikibaseDataModel)
jenkins-bot has submitted this change and it was merged. Change subject: Made SnakList/Reference order-aware .. Made SnakList/Reference order-aware Change-Id: I2ce18fb2151d7d940bb020bcb7a594d74bfea35d --- M DataModel/Reference.php M DataModel/Snak/SnakList.php M tests/phpunit/ReferenceTest.php M tests/phpunit/Snak/SnakListTest.php 4 files changed, 200 insertions(+), 6 deletions(-) Approvals: Tobias Gritschacher: Looks good to me, approved jenkins-bot: Verified diff --git a/DataModel/Reference.php b/DataModel/Reference.php index b8f6e8f..cca512c 100644 --- a/DataModel/Reference.php +++ b/DataModel/Reference.php @@ -65,7 +65,14 @@ * @return string */ public function getHash() { - return $this-snaks-getHash(); + // For considering the reference snaks' property order without actually manipulating the + // reference snaks's order, a new SnakList is generated. The new SnakList is ordered + // by property and its hash is returned. + $orderedSnaks = new SnakList( $this-snaks ); + + $orderedSnaks-orderByProperty(); + + return $orderedSnaks-getHash(); } /** diff --git a/DataModel/Snak/SnakList.php b/DataModel/Snak/SnakList.php index 5ba78cf..66d2619 100644 --- a/DataModel/Snak/SnakList.php +++ b/DataModel/Snak/SnakList.php @@ -102,6 +102,49 @@ } /** +* @see HashArray::getHash +* +* @since 0.5 +* +* @return string +*/ + public function getHash() { + $args = func_get_args(); + + /** +* @var MapHasher $hasher +*/ + $hasher = array_key_exists( 0, $args ) ? $args[0] : new MapValueHasher( true ); + + return parent::getHash( $hasher ); + } + + /** +* Orders the snaks in the list grouping them by property. +* +* @since 0.5 +*/ + public function orderByProperty() { + $snaksByProperty = array(); + + foreach( $this as $snak ) { + $propertyId = $snak-getPropertyId()-getSerialization(); + + if( !isset( $snaksByProperty[$propertyId] ) ) { + $snaksByProperty[$propertyId] = array(); + } + $snaksByProperty[$propertyId][] = $snak; + } + + foreach( $snaksByProperty as $snaks ) { + foreach( $snaks as $snak ) { + $this-removeSnak( $snak ); + $this-addSnak( $snak ); + } + } + } + + /** * @see Snaks::toArray * * @since 0.3 diff --git a/tests/phpunit/ReferenceTest.php b/tests/phpunit/ReferenceTest.php index 3d02be9..3fe5925 100644 --- a/tests/phpunit/ReferenceTest.php +++ b/tests/phpunit/ReferenceTest.php @@ -3,6 +3,10 @@ namespace Wikibase\Test; use DataValues\StringValue; +use Wikibase\DataModel\Entity\EntityId; +use Wikibase\Property; +use Wikibase\PropertyNoValueSnak; +use Wikibase\PropertySomeValueSnak; use Wikibase\PropertyValueSnak; use Wikibase\Reference; use Wikibase\SnakList; @@ -32,13 +36,13 @@ $snakLists[] = new SnakList(); $snakLists[] = new SnakList( - array( new PropertyValueSnak( new \Wikibase\EntityId( \Wikibase\Property::ENTITY_TYPE, 1 ), new StringValue( 'a' ) ) ) + array( new PropertyValueSnak( new EntityId( Property::ENTITY_TYPE, 1 ), new StringValue( 'a' ) ) ) ); $snakLists[] = new SnakList( array( - new PropertyValueSnak( new \Wikibase\EntityId( \Wikibase\Property::ENTITY_TYPE, 1 ), new StringValue( 'a' ) ), - new \Wikibase\PropertySomeValueSnak( new \Wikibase\EntityId( \Wikibase\Property::ENTITY_TYPE, 2 ) ), - new \Wikibase\PropertyNoValueSnak( new \Wikibase\EntityId( \Wikibase\Property::ENTITY_TYPE, 3 ) ) + new PropertyValueSnak( new EntityId( Property::ENTITY_TYPE, 1 ), new StringValue( 'a' ) ), + new PropertySomeValueSnak( new EntityId( Property::ENTITY_TYPE, 2 ) ), + new PropertyNoValueSnak( new EntityId( Property::ENTITY_TYPE, 3 ) ) ) ); $argLists = array(); @@ -56,7 +60,7 @@ $references[] = new Reference(); $references[] = new Reference( new SnakList( array( new PropertyValueSnak( - new \Wikibase\EntityId( \Wikibase\Property::ENTITY_TYPE, 1 ), + new EntityId( Property::ENTITY_TYPE, 1 ), new StringValue( 'a' ) ) ) ) ); @@ -99,4 +103,69 @@
[MediaWiki-commits] [Gerrit] Made SnakList/Reference order-aware - change (mediawiki...WikibaseDataModel)
Henning Snater has uploaded a new change for review. https://gerrit.wikimedia.org/r/84505 Change subject: Made SnakList/Reference order-aware .. Made SnakList/Reference order-aware Change-Id: I2ce18fb2151d7d940bb020bcb7a594d74bfea35d --- M DataModel/Reference.php M DataModel/Snak/SnakList.php M tests/phpunit/Snak/SnakListTest.php 3 files changed, 100 insertions(+), 1 deletion(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikibaseDataModel refs/changes/05/84505/1 diff --git a/DataModel/Reference.php b/DataModel/Reference.php index b8f6e8f..7586d12 100644 --- a/DataModel/Reference.php +++ b/DataModel/Reference.php @@ -65,7 +65,18 @@ * @return string */ public function getHash() { - return $this-snaks-getHash(); + // For considering the reference snaks' property order without actually manipulating the + // reference snaks's order, a new SnakList is generated. The new SnakList is ordered + // by property and its hash is returned. + $orderedSnaks = new SnakList(); + + foreach( $this-snaks as $snak ) { + $orderedSnaks-addSnak( $snak ); + } + + $orderedSnaks-orderByProperty(); + + return $orderedSnaks-getHash(); } /** diff --git a/DataModel/Snak/SnakList.php b/DataModel/Snak/SnakList.php index 5ba78cf..0b1e8bd 100644 --- a/DataModel/Snak/SnakList.php +++ b/DataModel/Snak/SnakList.php @@ -102,6 +102,49 @@ } /** +* @see HashArray::getHash +* +* @since 0.1 +* +* @return string +*/ + public function getHash() { + $args = func_get_args(); + + /** +* @var MapHasher $hasher +*/ + $hasher = array_key_exists( 0, $args ) ? $args[0] : new MapValueHasher( true ); + + return parent::getHash( $hasher ); + } + + /** +* Orders the snaks in the list grouping them by property. +* +* @since 0.1 +*/ + public function orderByProperty() { + $snaksByProperty = array(); + + foreach( $this as $snak ) { + $propertyId = $snak-getPropertyId()-getNumericId(); + + if( !isset( $snaksByProperty[$propertyId] ) ) { + $snaksByProperty[$propertyId] = array(); + } + $snaksByProperty[$propertyId][] = $snak; + } + + foreach( $snaksByProperty as $snaks ) { + foreach( $snaks as $snak ) { + $this-removeSnak( $snak ); + $this-addSnak( $snak ); + } + } + } + + /** * @see Snaks::toArray * * @since 0.3 diff --git a/tests/phpunit/Snak/SnakListTest.php b/tests/phpunit/Snak/SnakListTest.php index 515504c..256fc92 100644 --- a/tests/phpunit/Snak/SnakListTest.php +++ b/tests/phpunit/Snak/SnakListTest.php @@ -152,6 +152,51 @@ /** * @dataProvider instanceProvider +* +* @param SnakList $snakList +*/ + public function testOrderByProperty( SnakList $snakList ) { + $initialCount = count( $snakList ); + $initialHash = $snakList-getHash(); + $initialPropertyIds = array(); + + foreach( $snakList as $snak ) { + $propertyId = $snak-getPropertyId()-getPrefixedId(); + + if( count( $initialPropertyIds ) === 0 || $initialPropertyIds[count( $initialPropertyIds ) - 1] !== $propertyId ) { + $initialPropertyIds[] = $propertyId; + } + } + + $snakList-orderByProperty(); + + $this-assertEquals( $initialCount, count( $snakList ), 'No content manipulation is taking place.' ); + + $propertyIds = array(); + + foreach( $snakList as $snak ) { + $propertyId = $snak-getPropertyId()-getPrefixedId(); + + $this-assertTrue( + !in_array( $propertyId, $propertyIds ) || $propertyIds[count( $propertyIds ) - 1] === $propertyId, + 'Verified order of snak with property ' . $propertyId . '.' + ); + + if( !in_array( $propertyId, $propertyIds ) ) { + $propertyIds[] = $propertyId; + } + } + + if( count( $initialPropertyIds ) !== count( $propertyIds ) ) { + $this-assertFalse( $initialHash === $snakList-getHash(), 'Hash is different after reordering.' ); +