From 7cd36ba30b1e8d6e1d0558c986f01a3b26e87f4a Mon Sep 17 00:00:00 2001 From: Bene Date: Mon, 22 Sep 2014 23:55:56 +0200 Subject: [PATCH 01/14] Create rewrite of ByPropertyIdArray --- src/ByPropertyIdArrayNew.php | 166 +++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 src/ByPropertyIdArrayNew.php diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php new file mode 100644 index 00000000..07565ed5 --- /dev/null +++ b/src/ByPropertyIdArrayNew.php @@ -0,0 +1,166 @@ + + */ +class ByPropertyIdArrayNew { + + /** + * @var ByPropertyIdGrouper + */ + private $byPropertyIdGrouper; + + /** + * @var PropertyIdProvider[] + */ + private $flatArray; + + /** + * @param PropertyIdProvider[] $propertyIdProviders + * @throws InvalidArgumentException + */ + public function __construct( array $propertyIdProviders ) { + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); + $this->flatArray = array(); + + foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { + $propertyIdProviders = $this->byPropertyIdGrouper->getForPropertyId( $propertyId ); + $this->flatArray = array_merge( $this->flatArray, $propertyIdProviders ); + } + } + + private function updatePropertySuggester() { + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); + } + + /** + * Returns a list of all PropertyIdProvider instances grouped by their PropertyId. + * + * @since 1.1 + * + * @return PropertyIdProvider[] + */ + public function getFlatArray() { + return $this->flatArray; + } + + /** + * + * @param PropertyIdProvider $propertyIdProvider + * @param integer $index + */ + public function addAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { + $this->assertValidIndex( $index ); + + $groupIndices = $this->getFlatArrayGroupIndices(); + $propertyId = $propertyIdProvider->getPropertyId(); + $idSerialization = $propertyId->getSerialization(); + + if ( isset( $groupIndices[$idSerialization] ) ) { + $groupIndex = $groupIndices[$idSerialization]; + $count = count( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) ); + } else { + $groupIndex = 0; + $count = 0; + } + + // if not inside of group also move property group + if ( $index < $groupIndex || $groupIndex + $count <= $index ) { + // find real index to insert + $index = $index === 0 ? 0 : $this->findNextIndex( $index ); + $this->moveGroupInFlatArray( $groupIndex, $count, $index ); + } + + $this->addtoFlatArray( $propertyIdProvider, $index ); + + $this->updatePropertySuggester(); + } + + /** + * + * @param integer $index + */ + public function removeAtIndex( $index ) { + $this->assertValidIndex( $index ); + + $object = $this->removeFromFlatArray( $index ); + $this->updatePropertySuggester(); + + return $object; + } + + /** + * + * @param integer $oldIndex + * @param integer $newIndex + */ + public function moveToIndex( $oldIndex, $newIndex ) { + $this->assertValidIndex( $oldIndex ); + $this->assertValidIndex( $newIndex ); + + $object = $this->removeAtIndex( $oldIndex ); + $this->addAtIndex( $object, $newIndex ); + } + + private function addtoFlatArray( PropertyIdProvider $propertyIdProvider, $index ) { + array_splice( $this->flatArray, $index, 0, array( $propertyIdProvider ) ); + } + + private function removeFromFlatArray( $index ) { + return array_splice( $this->flatArray, $index, 1 )[0]; + } + + private function moveGroupInFlatArray( $start, $length, $to ) { + if ( $start < $to ) { + $to = $to - $length; + } + + $objects = array_splice( $this->flatArray, $start, $length ); + array_splice( $this->flatArray, $to, 0, $objects ); + } + + private function findNextIndex( $index ) { + $groupIndices = $this->getFlatArrayGroupIndices(); + + foreach ( $groupIndices as $groupIndex ) { + if ( $groupIndex > $index ) { + return $groupIndex; + } + } + + return count( $this->flatArray ); + } + + private function getFlatArrayGroupIndices() { + $indices = array(); + $index = 0; + + foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { + $indices[$propertyId->getSerialization()] = $index; + $index += count( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) ); + } + + return $indices; + } + + private function assertValidIndex( $index ) { + if ( !is_int( $index ) ) { + throw new InvalidArgumentException( 'Only integer indices are supported.' ); + } + + if ( $index < 0 || $index >= count( $this->flatArray ) ) { + throw new OutOfBoundsException( 'The index exceeds the array dimensions.' ); + } + } + +} From c18f7297373c3fccaa073119b005600a510b760c Mon Sep 17 00:00:00 2001 From: Bene Date: Tue, 23 Sep 2014 22:58:22 +0200 Subject: [PATCH 02/14] Add comments --- src/ByPropertyIdArrayNew.php | 100 ++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 20 deletions(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index 07565ed5..999b48da 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -6,7 +6,7 @@ use OutOfBoundsException; /** - * Description of ByPropertyIdArrayNew + * Helper for managing objects grouped by property id. * * @since 1.1 * @@ -27,6 +27,7 @@ class ByPropertyIdArrayNew { /** * @param PropertyIdProvider[] $propertyIdProviders + * * @throws InvalidArgumentException */ public function __construct( array $propertyIdProviders ) { @@ -39,10 +40,6 @@ public function __construct( array $propertyIdProviders ) { } } - private function updatePropertySuggester() { - $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); - } - /** * Returns a list of all PropertyIdProvider instances grouped by their PropertyId. * @@ -55,9 +52,15 @@ public function getFlatArray() { } /** - * + * Adds the given PropertyIdProvider to the array at the given index. + * + * @since 1.1 + * * @param PropertyIdProvider $propertyIdProvider - * @param integer $index + * @param int $index + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ public function addAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { $this->assertValidIndex( $index ); @@ -82,27 +85,40 @@ public function addAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { } $this->addtoFlatArray( $propertyIdProvider, $index ); - - $this->updatePropertySuggester(); + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); } /** - * - * @param integer $index + * Removes the PropertyIdProvider at the given index and returns it. + * + * @since 1.1 + * + * @param int $index + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ public function removeAtIndex( $index ) { $this->assertValidIndex( $index ); $object = $this->removeFromFlatArray( $index ); - $this->updatePropertySuggester(); + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); return $object; } /** - * - * @param integer $oldIndex - * @param integer $newIndex + * Moves the PropertyIdProvider from the old to the new index and returns it. + * + * @since 1.1 + * + * @param int $oldIndex + * @param int $newIndex + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ public function moveToIndex( $oldIndex, $newIndex ) { $this->assertValidIndex( $oldIndex ); @@ -110,25 +126,56 @@ public function moveToIndex( $oldIndex, $newIndex ) { $object = $this->removeAtIndex( $oldIndex ); $this->addAtIndex( $object, $newIndex ); + + return $object; } + /** + * Adds the object at the given index. + * @see array_splice + * + * @param PropertyIdProvider $propertyIdProvider + * @param int $index + */ private function addtoFlatArray( PropertyIdProvider $propertyIdProvider, $index ) { array_splice( $this->flatArray, $index, 0, array( $propertyIdProvider ) ); } + /** + * Removes the object at the given index and returns it. + * @see array_splice + * + * @param int $index + * @return PropertyIdProvider + */ private function removeFromFlatArray( $index ) { return array_splice( $this->flatArray, $index, 1 )[0]; } - private function moveGroupInFlatArray( $start, $length, $to ) { - if ( $start < $to ) { - $to = $to - $length; + /** + * Moves a list of objects with the given length from the start to the target index. + * @see array_splice + * + * @param int $start + * @param int $length + * @param int $target + */ + private function moveGroupInFlatArray( $start, $length, $target ) { + // make sure we do not exceed the limits + if ( $start < $target ) { + $target = $target - $length; } $objects = array_splice( $this->flatArray, $start, $length ); - array_splice( $this->flatArray, $to, 0, $objects ); + array_splice( $this->flatArray, $target, 0, $objects ); } + /** + * Finds the next index in the flat array which starts a new PropertyId group. + * + * @param int $index + * @return int + */ private function findNextIndex( $index ) { $groupIndices = $this->getFlatArrayGroupIndices(); @@ -141,6 +188,11 @@ private function findNextIndex( $index ) { return count( $this->flatArray ); } + /** + * Finds all indeces where a new PropertyId group starts. + * + * @return int[] + */ private function getFlatArrayGroupIndices() { $indices = array(); $index = 0; @@ -153,12 +205,20 @@ private function getFlatArrayGroupIndices() { return $indices; } + /** + * Asserts that the given paramter is a valid index. + * + * @param int $index + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException + */ private function assertValidIndex( $index ) { if ( !is_int( $index ) ) { throw new InvalidArgumentException( 'Only integer indices are supported.' ); } - if ( $index < 0 || $index >= count( $this->flatArray ) ) { + if ( $index < 0 || $index > count( $this->flatArray ) ) { throw new OutOfBoundsException( 'The index exceeds the array dimensions.' ); } } From 53b799e87ac7957f9b595b49075184bb5ab525e4 Mon Sep 17 00:00:00 2001 From: Bene Date: Tue, 23 Sep 2014 23:06:07 +0200 Subject: [PATCH 03/14] Rename methods in ByPropertyIdGrouper --- src/ByPropertyIdGrouper.php | 12 +++++++----- src/Statement/BestStatementsFinder.php | 2 +- tests/unit/ByPropertyIdGrouperTest.php | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ByPropertyIdGrouper.php b/src/ByPropertyIdGrouper.php index de767231..677ae84f 100644 --- a/src/ByPropertyIdGrouper.php +++ b/src/ByPropertyIdGrouper.php @@ -20,7 +20,7 @@ class ByPropertyIdGrouper { /** * @var PropertyIdProvider[][] */ - private $byPropertyId = array(); + private $byPropertyId; /** * @param PropertyIdProvider[] $propertyIdProviders @@ -44,6 +44,8 @@ private function assertArePropertyIdProviders( $propertyIdProviders ) { } private function indexPropertyIdProviders( $propertyIdProviders ) { + $this->byPropertyId = array(); + foreach ( $propertyIdProviders as $propertyIdProvider ) { $this->addPropertyIdProvider( $propertyIdProvider ); } @@ -60,7 +62,7 @@ private function addPropertyIdProvider( PropertyIdProvider $propertyIdProvider ) } /** - * Returns all property ids which were found. + * Returns all PropertyId instances which were found. * * @since 1.1 * @@ -85,11 +87,11 @@ public function getPropertyIds() { * @return PropertyIdProvider[] * @throws OutOfBoundsException */ - public function getByPropertyId( PropertyId $propertyId ) { + public function getForPropertyId( PropertyId $propertyId ) { $idSerialization = $propertyId->getSerialization(); if ( !isset( $this->byPropertyId[$idSerialization] ) ) { - throw new OutOfBoundsException( 'Property id does not exist.' ); + throw new OutOfBoundsException( 'Could not find the given PropertyId.' ); } return $this->byPropertyId[$idSerialization]; @@ -103,7 +105,7 @@ public function getByPropertyId( PropertyId $propertyId ) { * @param PropertyId $propertyId * @return boolean */ - public function hasPropertyId( PropertyId $propertyId ) { + public function hasForPropertyId( PropertyId $propertyId ) { return isset( $this->byPropertyId[$propertyId->getSerialization()] ); } diff --git a/src/Statement/BestStatementsFinder.php b/src/Statement/BestStatementsFinder.php index b3cf1a48..04e2ab81 100644 --- a/src/Statement/BestStatementsFinder.php +++ b/src/Statement/BestStatementsFinder.php @@ -69,7 +69,7 @@ public function getBestStatementsForProperty( PropertyId $propertyId ) { $statements = array(); /** @var Statement $statement */ - foreach ( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) as $statement ) { + foreach ( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) as $statement ) { $rank = $statement->getRank(); if ( $rank > $bestRank ) { // clear statements if we found a better one diff --git a/tests/unit/ByPropertyIdGrouperTest.php b/tests/unit/ByPropertyIdGrouperTest.php index 26af4965..680093d0 100644 --- a/tests/unit/ByPropertyIdGrouperTest.php +++ b/tests/unit/ByPropertyIdGrouperTest.php @@ -88,7 +88,7 @@ public function provideGetByPropertyId() { */ public function testGetByPropertyId( array $propertyIdProviders, $propertyId, array $expectedValues ) { $byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); - $values = $byPropertyIdGrouper->getByPropertyId( new PropertyId( $propertyId ) ); + $values = $byPropertyIdGrouper->getForPropertyId( new PropertyId( $propertyId ) ); array_walk( $values, function( &$value ) { $value = $value->getType(); } ); @@ -100,7 +100,7 @@ public function testGetByPropertyId( array $propertyIdProviders, $propertyId, ar */ public function testGetByPropertyIdThrowsException() { $byPropertyIdGrouper = new ByPropertyIdGrouper( $this->getPropertyIdProviders() ); - $byPropertyIdGrouper->getByPropertyId( new PropertyId( 'P11' ) ); + $byPropertyIdGrouper->getForPropertyId( new PropertyId( 'P11' ) ); } public function provideHasPropertyId() { @@ -127,7 +127,7 @@ public function provideHasPropertyId() { */ public function testHasPropertyId( array $propertyIdProviders, $propertyId, $expectedValue ) { $byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); - $this->assertEquals( $expectedValue, $byPropertyIdGrouper->hasPropertyId( new PropertyId( $propertyId ) ) ); + $this->assertEquals( $expectedValue, $byPropertyIdGrouper->hasForPropertyId( new PropertyId( $propertyId ) ) ); } /** From ca1ab09b5ffd8fde81986dda4487da0791246abe Mon Sep 17 00:00:00 2001 From: Bene Date: Tue, 23 Sep 2014 23:13:52 +0200 Subject: [PATCH 04/14] Create convenience functions --- src/ByPropertyIdArrayNew.php | 53 +++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index 999b48da..d3fc575b 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -51,6 +51,26 @@ public function getFlatArray() { return $this->flatArray; } + /** + * Returns the index of the given PropertyIdPovider in the flat array. + * + * @since 1.1 + * + * @param PropertyIdProvider $propertyIdProvider + * @return int + * + * @throws OutOfBoundsException + */ + public function getIndex( PropertyIdProvider $propertyIdProvider ) { + $index = array_search( $propertyIdProvider, $this->flatArray, true ); + + if ( $index === false ) { + throw new OutOfBoundsException( 'The given PropertyIdProvider was not found.' ); + } + + return $index; + } + /** * Adds the given PropertyIdProvider to the array at the given index. * @@ -109,7 +129,22 @@ public function removeAtIndex( $index ) { } /** - * Moves the PropertyIdProvider from the old to the new index and returns it. + * Removes the given PropertyIdProvider and returns it. + * + * @since 1.1 + * + * @param PropertyIdProvider $propertyIdProvider + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException + */ + public function removeObject( PropertyIdProvider $propertyIdProvider ) { + return $this->removeAtIndex( $this->getIndex( $propertyIdProvider ) ); + } + + /** + * Moves a PropertyIdProvider from the old to the new index and returns it. * * @since 1.1 * @@ -130,6 +165,22 @@ public function moveToIndex( $oldIndex, $newIndex ) { return $object; } + /** + * Moves the given PropertyIdProvider to the new index and returns it. + * + * @since 1.1 + * + * @param PropertyIdProvider $propertyIdProvider + * @param int $index + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException + */ + public function moveObject( PropertyIdProvider $propertyIdProvider, $index ) { + return $this->moveToIndex( $this->getIndex( $propertyIdProvider ), $index ); + } + /** * Adds the object at the given index. * @see array_splice From e3543c156209876f845b4bc52b37e9f8af501948 Mon Sep 17 00:00:00 2001 From: Bene Date: Tue, 23 Sep 2014 23:30:11 +0200 Subject: [PATCH 05/14] Test addAtIndex --- tests/unit/ByPropertyIdArrayNewTest.php | 97 +++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/unit/ByPropertyIdArrayNewTest.php diff --git a/tests/unit/ByPropertyIdArrayNewTest.php b/tests/unit/ByPropertyIdArrayNewTest.php new file mode 100644 index 00000000..eb35a14e --- /dev/null +++ b/tests/unit/ByPropertyIdArrayNewTest.php @@ -0,0 +1,97 @@ +getSnakMock( 'P1', 'x' ), + 1, + array( 'a', 'x', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ) + ); + + $cases[] = array( + $this->getSnakMock( 'P1', 'x' ), + 5, + array( 'c', 'd', 'e', 'f', 'a', 'b', 'x', 'g', 'h' ) + ); + + $cases[] = array( + $this->getSnakMock( 'P2', 'x' ), + 0, + array( 'x', 'c', 'd', 'e', 'a', 'b', 'f', 'g', 'h' ) + ); + + $cases[] = array( + $this->getSnakMock( 'P2', 'x' ), + 8, + array( 'a', 'b', 'f', 'g', 'h', 'c', 'd', 'e', 'x' ) + ); + + $cases[] = array( + $this->getSnakMock( 'P2', 'x' ), + 7, + array( 'a', 'b', 'f', 'g', 'h', 'c', 'd', 'e', 'x' ) + ); + + return $cases; + } + + /** + * @dataProvider provideAddAtIndex + */ + public function testAddAtIndex( PropertyIdProvider $propertyIdProvider, $index, $expectedTypes ) { + $byPropertyIdArray = $this->getByPropertyIdArray(); + $byPropertyIdArray->addAtIndex( $propertyIdProvider, $index ); + $types = array_map( function( Snak $snak ) { + return $snak->getType(); + }, $byPropertyIdArray->getFlatArray() ); + $this->assertEquals( $expectedTypes, $types ); + } + + private function getByPropertyIdArray() { + return new ByPropertyIdArrayNew( array( + $this->getSnakMock( 'P1', 'a' ), + $this->getSnakMock( 'P1', 'b' ), + $this->getSnakMock( 'P2', 'c' ), + $this->getSnakMock( 'P2', 'd' ), + $this->getSnakMock( 'P2', 'e' ), + $this->getSnakMock( 'P3', 'f' ), + $this->getSnakMock( 'P4', 'g' ), + $this->getSnakMock( 'P4', 'h' ) + ) ); + } + + /** + * @param string $propertyId + * @param string $type + * @return Snak + */ + private function getSnakMock( $propertyId, $type ) { + $snak = $this->getMock( 'Wikibase\DataModel\Snak\Snak' ); + + $snak->expects( $this->any() ) + ->method( 'getPropertyId' ) + ->will( $this->returnValue( new PropertyId( $propertyId ) ) ); + + $snak->expects( $this->any() ) + ->method( 'getType' ) + ->will( $this->returnValue( $type ) ); + + return $snak; + } + +} From dafa9b8b0f93ec5bbd6a789d619ace5543b0f338 Mon Sep 17 00:00:00 2001 From: Bene Date: Tue, 23 Sep 2014 23:36:25 +0200 Subject: [PATCH 06/14] Add some further tests --- tests/unit/ByPropertyIdArrayNewTest.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/unit/ByPropertyIdArrayNewTest.php b/tests/unit/ByPropertyIdArrayNewTest.php index eb35a14e..b8f50b6e 100644 --- a/tests/unit/ByPropertyIdArrayNewTest.php +++ b/tests/unit/ByPropertyIdArrayNewTest.php @@ -14,6 +14,19 @@ */ class ByPropertyIdArrayNewTest extends \PHPUnit_Framework_TestCase { + public function testGetFlatArray() { + $byPropertyIdArray = $this->getByPropertyIdArray(); + $expectedTypes = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ); + $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->getFlatArray() ) ); + } + + public function testGetIndex() { + $byPropertyIdArray = $this->getByPropertyIdArray(); + $propertyIdProvider = $this->getSnakMock( 'P42', 'foo bar' ); + $byPropertyIdArray->addAtIndex( $propertyIdProvider, 1 ); + $this->assertEquals( 1, $byPropertyIdArray->getIndex( $propertyIdProvider ) ); + } + public function provideAddAtIndex() { $cases = array(); @@ -56,10 +69,7 @@ public function provideAddAtIndex() { public function testAddAtIndex( PropertyIdProvider $propertyIdProvider, $index, $expectedTypes ) { $byPropertyIdArray = $this->getByPropertyIdArray(); $byPropertyIdArray->addAtIndex( $propertyIdProvider, $index ); - $types = array_map( function( Snak $snak ) { - return $snak->getType(); - }, $byPropertyIdArray->getFlatArray() ); - $this->assertEquals( $expectedTypes, $types ); + $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->getFlatArray() ) ); } private function getByPropertyIdArray() { @@ -75,6 +85,12 @@ private function getByPropertyIdArray() { ) ); } + private function getTypes( array $snaks ) { + return array_map( function( Snak $snak ) { + return $snak->getType(); + }, $snaks ); + } + /** * @param string $propertyId * @param string $type From e78cb18fe787b0027dce273842b22facac6fdee6 Mon Sep 17 00:00:00 2001 From: Bene Date: Wed, 24 Sep 2014 21:32:43 +0200 Subject: [PATCH 07/14] Fix when index is group index --- src/ByPropertyIdArrayNew.php | 2 +- tests/unit/ByPropertyIdArrayNewTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index d3fc575b..ff2c3ba9 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -231,7 +231,7 @@ private function findNextIndex( $index ) { $groupIndices = $this->getFlatArrayGroupIndices(); foreach ( $groupIndices as $groupIndex ) { - if ( $groupIndex > $index ) { + if ( $groupIndex >= $index ) { return $groupIndex; } } diff --git a/tests/unit/ByPropertyIdArrayNewTest.php b/tests/unit/ByPropertyIdArrayNewTest.php index b8f50b6e..44a5eee7 100644 --- a/tests/unit/ByPropertyIdArrayNewTest.php +++ b/tests/unit/ByPropertyIdArrayNewTest.php @@ -23,8 +23,8 @@ public function testGetFlatArray() { public function testGetIndex() { $byPropertyIdArray = $this->getByPropertyIdArray(); $propertyIdProvider = $this->getSnakMock( 'P42', 'foo bar' ); - $byPropertyIdArray->addAtIndex( $propertyIdProvider, 1 ); - $this->assertEquals( 1, $byPropertyIdArray->getIndex( $propertyIdProvider ) ); + $byPropertyIdArray->addAtIndex( $propertyIdProvider, 2 ); + $this->assertEquals( 2, $byPropertyIdArray->getIndex( $propertyIdProvider ) ); } public function provideAddAtIndex() { @@ -39,7 +39,7 @@ public function provideAddAtIndex() { $cases[] = array( $this->getSnakMock( 'P1', 'x' ), 5, - array( 'c', 'd', 'e', 'f', 'a', 'b', 'x', 'g', 'h' ) + array( 'c', 'd', 'e', 'a', 'b', 'x', 'f', 'g', 'h' ) ); $cases[] = array( From 9774823723a3049861791a26af9fc3600af019ec Mon Sep 17 00:00:00 2001 From: Bene Date: Wed, 24 Sep 2014 21:45:15 +0200 Subject: [PATCH 08/14] Fix PHP 5.3 weirdness --- src/ByPropertyIdArrayNew.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index ff2c3ba9..d56bc1d2 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -200,7 +200,8 @@ private function addtoFlatArray( PropertyIdProvider $propertyIdProvider, $index * @return PropertyIdProvider */ private function removeFromFlatArray( $index ) { - return array_splice( $this->flatArray, $index, 1 )[0]; + $objects = array_splice( $this->flatArray, $index, 1 ); + return $objects[0]; } /** From 91491185f42e7299716396e46d6718a41ee47557 Mon Sep 17 00:00:00 2001 From: Bene Date: Wed, 24 Sep 2014 21:56:32 +0200 Subject: [PATCH 09/14] Add backwards compatibility with ByPropertyIdArray --- RELEASE-NOTES.md | 4 +++ src/ByPropertyIdArrayNew.php | 42 +++++++++++++++++++++---- tests/unit/ByPropertyIdArrayNewTest.php | 14 ++++----- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 82a80818..1f13c72c 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -16,6 +16,10 @@ * The `Reference` constructor now accepts a `Snak` array * Added `ReferenceList::addNewReference` +#### Deprecations + +* Deprecated `ByPropertyIdArray::buildIndex`, `ByPropertyIdArray::getByPropertyId` and `ByPropertyIdArray::getPropertyIds` + ## Version 1.0 (2014-09-02) #### Breaking changes diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index d56bc1d2..6eb75cba 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -4,6 +4,7 @@ use InvalidArgumentException; use OutOfBoundsException; +use Wikibase\DataModel\Entity\PropertyId; /** * Helper for managing objects grouped by property id. @@ -40,14 +41,43 @@ public function __construct( array $propertyIdProviders ) { } } + /** + * @since 0.2 + * @deprecated since 1.1 + */ + public function buildIndex() {} + + /** + * @since 0.2 + * @deprecated since 1.1 + * + * @param PropertyId $propertyId + * @return PropertyIdProvider[] + * + * @throws OutOfBoundsException + */ + public function getByPropertyId( PropertyId $propertyId ) { + return $this->byPropertyIdGrouper->getForPropertyId( $propertyId ); + } + + /** + * @since 0.2 + * @deprecated since 1.1 + * + * @return PropertyId[] + */ + public function getPropertyIds() { + return $this->byPropertyIdGrouper->getPropertyIds(); + } + /** * Returns a list of all PropertyIdProvider instances grouped by their PropertyId. * - * @since 1.1 + * @since 0.2 * * @return PropertyIdProvider[] */ - public function getFlatArray() { + public function toFlatArray() { return $this->flatArray; } @@ -74,7 +104,7 @@ public function getIndex( PropertyIdProvider $propertyIdProvider ) { /** * Adds the given PropertyIdProvider to the array at the given index. * - * @since 1.1 + * @since 0.2 * * @param PropertyIdProvider $propertyIdProvider * @param int $index @@ -82,7 +112,7 @@ public function getIndex( PropertyIdProvider $propertyIdProvider ) { * @throws InvalidArgumentException * @throws OutOfBoundsException */ - public function addAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { + public function addObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { $this->assertValidIndex( $index ); $groupIndices = $this->getFlatArrayGroupIndices(); @@ -168,7 +198,7 @@ public function moveToIndex( $oldIndex, $newIndex ) { /** * Moves the given PropertyIdProvider to the new index and returns it. * - * @since 1.1 + * @since 0.2 * * @param PropertyIdProvider $propertyIdProvider * @param int $index @@ -177,7 +207,7 @@ public function moveToIndex( $oldIndex, $newIndex ) { * @throws InvalidArgumentException * @throws OutOfBoundsException */ - public function moveObject( PropertyIdProvider $propertyIdProvider, $index ) { + public function moveObjectToIndex( PropertyIdProvider $propertyIdProvider, $index ) { return $this->moveToIndex( $this->getIndex( $propertyIdProvider ), $index ); } diff --git a/tests/unit/ByPropertyIdArrayNewTest.php b/tests/unit/ByPropertyIdArrayNewTest.php index 44a5eee7..9916cf67 100644 --- a/tests/unit/ByPropertyIdArrayNewTest.php +++ b/tests/unit/ByPropertyIdArrayNewTest.php @@ -17,17 +17,17 @@ class ByPropertyIdArrayNewTest extends \PHPUnit_Framework_TestCase { public function testGetFlatArray() { $byPropertyIdArray = $this->getByPropertyIdArray(); $expectedTypes = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ); - $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->getFlatArray() ) ); + $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->toFlatArray() ) ); } public function testGetIndex() { $byPropertyIdArray = $this->getByPropertyIdArray(); $propertyIdProvider = $this->getSnakMock( 'P42', 'foo bar' ); - $byPropertyIdArray->addAtIndex( $propertyIdProvider, 2 ); + $byPropertyIdArray->addObjectAtIndex( $propertyIdProvider, 2 ); $this->assertEquals( 2, $byPropertyIdArray->getIndex( $propertyIdProvider ) ); } - public function provideAddAtIndex() { + public function provideAddObjectAtIndex() { $cases = array(); $cases[] = array( @@ -64,12 +64,12 @@ public function provideAddAtIndex() { } /** - * @dataProvider provideAddAtIndex + * @dataProvider provideAddObjectAtIndex */ - public function testAddAtIndex( PropertyIdProvider $propertyIdProvider, $index, $expectedTypes ) { + public function testAddObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index, $expectedTypes ) { $byPropertyIdArray = $this->getByPropertyIdArray(); - $byPropertyIdArray->addAtIndex( $propertyIdProvider, $index ); - $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->getFlatArray() ) ); + $byPropertyIdArray->addObjectAtIndex( $propertyIdProvider, $index ); + $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->toFlatArray() ) ); } private function getByPropertyIdArray() { From 0669ab7da93bf8277abef425218983c761eceb2d Mon Sep 17 00:00:00 2001 From: Bene Date: Thu, 9 Oct 2014 19:15:15 +0200 Subject: [PATCH 10/14] Fix versions and add deprecated method --- src/ByPropertyIdArrayNew.php | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index 6eb75cba..25792175 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -9,7 +9,7 @@ /** * Helper for managing objects grouped by property id. * - * @since 1.1 + * @since 0.2 * * @license GNU GPL v2+ * @author Bene* < benestar.wikimedia@gmail.com > @@ -43,13 +43,13 @@ public function __construct( array $propertyIdProviders ) { /** * @since 0.2 - * @deprecated since 1.1 + * @deprecated since 1.2 */ public function buildIndex() {} /** * @since 0.2 - * @deprecated since 1.1 + * @deprecated since 1.2 * * @param PropertyId $propertyId * @return PropertyIdProvider[] @@ -60,9 +60,24 @@ public function getByPropertyId( PropertyId $propertyId ) { return $this->byPropertyIdGrouper->getForPropertyId( $propertyId ); } + /** + * Returns the absolute index of an object or false if the object could not be found. + * + * @since 0.5 + * @deprecated since 1.2 + * + * @param object $object + * @return bool|int + * + * @throws RuntimeException + */ + public function getFlatArrayIndexOfObject( $object ) { + return array_search( $object, $this->flatArray ); + } + /** * @since 0.2 - * @deprecated since 1.1 + * @deprecated since 1.2 * * @return PropertyId[] */ @@ -84,7 +99,7 @@ public function toFlatArray() { /** * Returns the index of the given PropertyIdPovider in the flat array. * - * @since 1.1 + * @since 1.2 * * @param PropertyIdProvider $propertyIdProvider * @return int @@ -141,7 +156,7 @@ public function addObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index /** * Removes the PropertyIdProvider at the given index and returns it. * - * @since 1.1 + * @since 1.2 * * @param int $index * @return PropertyIdProvider @@ -161,7 +176,7 @@ public function removeAtIndex( $index ) { /** * Removes the given PropertyIdProvider and returns it. * - * @since 1.1 + * @since 1.2 * * @param PropertyIdProvider $propertyIdProvider * @return PropertyIdProvider @@ -176,7 +191,7 @@ public function removeObject( PropertyIdProvider $propertyIdProvider ) { /** * Moves a PropertyIdProvider from the old to the new index and returns it. * - * @since 1.1 + * @since 1.2 * * @param int $oldIndex * @param int $newIndex From fbfca360393e3d291b5a47699dc4813c69b04915 Mon Sep 17 00:00:00 2001 From: Bene Date: Thu, 9 Oct 2014 19:19:05 +0200 Subject: [PATCH 11/14] Update release notes --- RELEASE-NOTES.md | 20 ++++++++++++++++---- src/ByPropertyIdArrayNew.php | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 1f13c72c..851fde33 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,21 @@ # Wikibase DataModel release notes +## Version 1.2 (dev) + +#### Additions + +* Added `ByPropertyIdArray::getIndex` +* Added `ByPropertyIdArray::removeAtIndex` +* Added `ByPropertyIdArray::removeObject` +* Added `ByPropertyIdArray::moveToIndex` + +#### Deprecations + +* `ByPropertyIdArray::buildIndex` +* `ByPropertyIdArray::getByPropertyId` +* `ByPropertyIdArray::getFlatArrayIndexOfObject` +* `ByPropertyIdArray::getPropertyIds` + ## Version 1.1 (2014-09-29) #### Additions @@ -16,10 +32,6 @@ * The `Reference` constructor now accepts a `Snak` array * Added `ReferenceList::addNewReference` -#### Deprecations - -* Deprecated `ByPropertyIdArray::buildIndex`, `ByPropertyIdArray::getByPropertyId` and `ByPropertyIdArray::getPropertyIds` - ## Version 1.0 (2014-09-02) #### Breaking changes diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index 25792175..cedbd277 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -72,7 +72,7 @@ public function getByPropertyId( PropertyId $propertyId ) { * @throws RuntimeException */ public function getFlatArrayIndexOfObject( $object ) { - return array_search( $object, $this->flatArray ); + return array_search( $object, $this->flatArray, true ); } /** From 04a2b86ff7264a5cd77c1885d33394eda97931da Mon Sep 17 00:00:00 2001 From: Bene Date: Thu, 9 Oct 2014 19:23:59 +0200 Subject: [PATCH 12/14] Undo rename --- src/ByPropertyIdArrayNew.php | 10 +++++----- src/ByPropertyIdGrouper.php | 4 ++-- src/Statement/BestStatementsFinder.php | 2 +- tests/unit/ByPropertyIdGrouperTest.php | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php index cedbd277..81194490 100644 --- a/src/ByPropertyIdArrayNew.php +++ b/src/ByPropertyIdArrayNew.php @@ -36,7 +36,7 @@ public function __construct( array $propertyIdProviders ) { $this->flatArray = array(); foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { - $propertyIdProviders = $this->byPropertyIdGrouper->getForPropertyId( $propertyId ); + $propertyIdProviders = $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); $this->flatArray = array_merge( $this->flatArray, $propertyIdProviders ); } } @@ -57,7 +57,7 @@ public function buildIndex() {} * @throws OutOfBoundsException */ public function getByPropertyId( PropertyId $propertyId ) { - return $this->byPropertyIdGrouper->getForPropertyId( $propertyId ); + return $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); } /** @@ -136,7 +136,7 @@ public function addObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index if ( isset( $groupIndices[$idSerialization] ) ) { $groupIndex = $groupIndices[$idSerialization]; - $count = count( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) ); + $count = count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); } else { $groupIndex = 0; $count = 0; @@ -205,7 +205,7 @@ public function moveToIndex( $oldIndex, $newIndex ) { $this->assertValidIndex( $newIndex ); $object = $this->removeAtIndex( $oldIndex ); - $this->addAtIndex( $object, $newIndex ); + $this->addObjectAtIndex( $object, $newIndex ); return $object; } @@ -296,7 +296,7 @@ private function getFlatArrayGroupIndices() { foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { $indices[$propertyId->getSerialization()] = $index; - $index += count( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) ); + $index += count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); } return $indices; diff --git a/src/ByPropertyIdGrouper.php b/src/ByPropertyIdGrouper.php index 677ae84f..cf99defe 100644 --- a/src/ByPropertyIdGrouper.php +++ b/src/ByPropertyIdGrouper.php @@ -87,7 +87,7 @@ public function getPropertyIds() { * @return PropertyIdProvider[] * @throws OutOfBoundsException */ - public function getForPropertyId( PropertyId $propertyId ) { + public function getByPropertyId( PropertyId $propertyId ) { $idSerialization = $propertyId->getSerialization(); if ( !isset( $this->byPropertyId[$idSerialization] ) ) { @@ -105,7 +105,7 @@ public function getForPropertyId( PropertyId $propertyId ) { * @param PropertyId $propertyId * @return boolean */ - public function hasForPropertyId( PropertyId $propertyId ) { + public function hasPropertyId( PropertyId $propertyId ) { return isset( $this->byPropertyId[$propertyId->getSerialization()] ); } diff --git a/src/Statement/BestStatementsFinder.php b/src/Statement/BestStatementsFinder.php index 04e2ab81..b3cf1a48 100644 --- a/src/Statement/BestStatementsFinder.php +++ b/src/Statement/BestStatementsFinder.php @@ -69,7 +69,7 @@ public function getBestStatementsForProperty( PropertyId $propertyId ) { $statements = array(); /** @var Statement $statement */ - foreach ( $this->byPropertyIdGrouper->getForPropertyId( $propertyId ) as $statement ) { + foreach ( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) as $statement ) { $rank = $statement->getRank(); if ( $rank > $bestRank ) { // clear statements if we found a better one diff --git a/tests/unit/ByPropertyIdGrouperTest.php b/tests/unit/ByPropertyIdGrouperTest.php index 680093d0..26af4965 100644 --- a/tests/unit/ByPropertyIdGrouperTest.php +++ b/tests/unit/ByPropertyIdGrouperTest.php @@ -88,7 +88,7 @@ public function provideGetByPropertyId() { */ public function testGetByPropertyId( array $propertyIdProviders, $propertyId, array $expectedValues ) { $byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); - $values = $byPropertyIdGrouper->getForPropertyId( new PropertyId( $propertyId ) ); + $values = $byPropertyIdGrouper->getByPropertyId( new PropertyId( $propertyId ) ); array_walk( $values, function( &$value ) { $value = $value->getType(); } ); @@ -100,7 +100,7 @@ public function testGetByPropertyId( array $propertyIdProviders, $propertyId, ar */ public function testGetByPropertyIdThrowsException() { $byPropertyIdGrouper = new ByPropertyIdGrouper( $this->getPropertyIdProviders() ); - $byPropertyIdGrouper->getForPropertyId( new PropertyId( 'P11' ) ); + $byPropertyIdGrouper->getByPropertyId( new PropertyId( 'P11' ) ); } public function provideHasPropertyId() { @@ -127,7 +127,7 @@ public function provideHasPropertyId() { */ public function testHasPropertyId( array $propertyIdProviders, $propertyId, $expectedValue ) { $byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); - $this->assertEquals( $expectedValue, $byPropertyIdGrouper->hasForPropertyId( new PropertyId( $propertyId ) ) ); + $this->assertEquals( $expectedValue, $byPropertyIdGrouper->hasPropertyId( new PropertyId( $propertyId ) ) ); } /** From 5935c7d6929d3fb5c3862c289ad195b34a04c954 Mon Sep 17 00:00:00 2001 From: Bene Date: Thu, 9 Oct 2014 20:15:19 +0200 Subject: [PATCH 13/14] Replace old implementation and adjust tests --- src/ByPropertyIdArray.php | 547 +++++++++------------------ tests/unit/ByPropertyIdArrayTest.php | 71 +--- 2 files changed, 204 insertions(+), 414 deletions(-) diff --git a/src/ByPropertyIdArray.php b/src/ByPropertyIdArray.php index 37a7d64c..ce2a6c13 100644 --- a/src/ByPropertyIdArray.php +++ b/src/ByPropertyIdArray.php @@ -2,135 +2,68 @@ namespace Wikibase\DataModel; +use InvalidArgumentException; use OutOfBoundsException; -use RuntimeException; use Wikibase\DataModel\Entity\PropertyId; /** - * Helper for managing objects indexed by property id. - * - * This is a light weight alternative approach to using something - * like GenericArrayObject with the advantages that no extra interface - * is needed and that indexing does not happen automatically. - * - * Lack of automatic indexing means that you will need to call the - * buildIndex method before doing any look-ups. - * - * Since no extra interface is used, the user is responsible for only - * adding objects that have a getPropertyId method that returns either - * a string or integer when called with no arguments. - * - * Objects may be added or moved within the structure. Absolute indices (indices according to the - * flat list of objects) may be specified to add or move objects. These management operations take - * the property grouping into account. Adding or moving objects outside their "property groups" - * shifts the whole group towards that index. - * - * Example of moving an object within its "property group": - * o1 (p1) o1 (p1) - * o2 (p2) /-> o3 (p2) - * o3 (p2) ---> move to index 1 -/ o2 (p2) - * - * Example of moving an object that triggers moving the whole "property group": - * o1 (p1) /-> o3 (p2) - * o2 (p2) | o2 (p2) - * o3 (p2) ---> move to index 0 -/ o1 (p1) + * Helper for managing objects grouped by property id. * * @since 0.2 * - * @licence GNU GPL v2+ - * @author H. Snater < mediawiki@snater.com > + * @license GNU GPL v2+ + * @author Bene* < benestar.wikimedia@gmail.com > */ -class ByPropertyIdArray extends \ArrayObject { +class ByPropertyIdArray { /** - * @since 0.2 - * - * @var array[]|null + * @var ByPropertyIdGrouper */ - private $byId = null; + private $byPropertyIdGrouper; /** - * @see \ArrayObject::__construct - * - * @param array|object $input + * @var PropertyIdProvider[] */ - public function __construct( $input = null ) { - parent::__construct( (array)$input ); - } + private $flatArray; /** - * Builds the index for doing look-ups by property id. - * - * @since 0.2 + * @param PropertyIdProvider[] $propertyIdProviders + * @throws InvalidArgumentException */ - public function buildIndex() { - $this->byId = array(); - - foreach ( $this as $object ) { - $propertyId = $object->getPropertyId()->getSerialization(); - - if ( !array_key_exists( $propertyId, $this->byId ) ) { - $this->byId[$propertyId] = array(); - } + public function __construct( $propertyIdProviders = array() ) { + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); + $this->flatArray = array(); - $this->byId[$propertyId][] = $object; + foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { + $propertyIdProviders = $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); + $this->flatArray = array_merge( $this->flatArray, $propertyIdProviders ); } } /** - * Checks whether id indexed array has been generated. - * @since 0.5 - * - * @throws RuntimeException - */ - private function assertIndexIsBuild() { - if ( $this->byId === null ) { - throw new RuntimeException( 'Index not build, call buildIndex first' ); - } - } - - /** - * Returns the property ids used for indexing. - * * @since 0.2 - * - * @return PropertyId[] - * @throws RuntimeException + * @deprecated since 1.2 */ - public function getPropertyIds() { - $this->assertIndexIsBuild(); - - return array_map( - function( $serializedPropertyId ) { - return new PropertyId( $serializedPropertyId ); - }, - array_keys( $this->byId ) - ); - } + public function buildIndex() {} /** - * Returns the objects featuring the provided property id in the index. - * * @since 0.2 + * @deprecated since 1.2 * * @param PropertyId $propertyId + * @return PropertyIdProvider[] * - * @return object[] - * @throws RuntimeException|OutOfBoundsException + * @throws OutOfBoundsException */ public function getByPropertyId( PropertyId $propertyId ) { - $this->assertIndexIsBuild(); - - if ( !( array_key_exists( $propertyId->getSerialization(), $this->byId ) ) ) { - throw new OutOfBoundsException( 'Property id array key does not exist.' ); - } - - return $this->byId[$propertyId->getSerialization()]; + return $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); } /** * Returns the absolute index of an object or false if the object could not be found. + * * @since 0.5 + * @deprecated since 1.2 * * @param object $object * @return bool|int @@ -138,363 +71,257 @@ public function getByPropertyId( PropertyId $propertyId ) { * @throws RuntimeException */ public function getFlatArrayIndexOfObject( $object ) { - $this->assertIndexIsBuild(); + return array_search( $object, $this->flatArray, true ); + } - $i = 0; - foreach( $this as $o ) { - if( $o === $object ) { - return $i; - } - $i++; - } - return false; + /** + * @since 0.2 + * @deprecated since 1.2 + * + * @return PropertyId[] + */ + public function getPropertyIds() { + return $this->byPropertyIdGrouper->getPropertyIds(); } /** - * Returns the objects in a flat array (using the indexed form for generating the array). - * @since 0.5 + * Returns a list of all PropertyIdProvider instances grouped by their PropertyId. * - * @return object[] + * @since 0.2 * - * @throws RuntimeException + * @return PropertyIdProvider[] */ public function toFlatArray() { - $this->assertIndexIsBuild(); - - $array = array(); - foreach( $this->byId as $objects ) { - $array = array_merge( $array, $objects ); - } - return $array; + return $this->flatArray; } /** - * Returns the absolute numeric indices of objects featuring the same property id. - * @since 0.5 + * Returns the index of the given PropertyIdPovider in the flat array. * - * @param PropertyId $propertyId - * @return int[] + * @since 1.2 * - * @throws RuntimeException + * @param PropertyIdProvider $propertyIdProvider + * @return int + * + * @throws OutOfBoundsException */ - private function getFlatArrayIndices( PropertyId $propertyId ) { - $this->assertIndexIsBuild(); - - $propertyIndices = array(); - $i = 0; - - foreach( $this->byId as $serializedPropertyId => $objects ) { - if( $serializedPropertyId === $propertyId->getSerialization() ) { - $propertyIndices = range( $i, $i + count( $objects ) - 1 ); - break; - } else { - $i += count( $objects ); - } + public function getIndex( PropertyIdProvider $propertyIdProvider ) { + $index = array_search( $propertyIdProvider, $this->flatArray, true ); + + if ( $index === false ) { + throw new OutOfBoundsException( 'The given PropertyIdProvider was not found.' ); } - return $propertyIndices; + return $index; } /** - * Moves an object within its "property group". - * @since 0.5 + * Adds the given PropertyIdProvider to the array at the given index. * - * @param object $object - * @param int $toIndex Absolute index within a "property group". + * @since 0.2 * + * @param PropertyIdProvider $propertyIdProvider + * @param int $index + * + * @throws InvalidArgumentException * @throws OutOfBoundsException */ - private function moveObjectInPropertyGroup( $object, $toIndex ) { - $currentIndex = $this->getFlatArrayIndexOfObject( $object ); - - if( $toIndex === $currentIndex ) { - return; - } - - $propertyId = $object->getPropertyId(); + public function addObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { + $this->assertValidIndex( $index, false ); - $numericIndices = $this->getFlatArrayIndices( $propertyId ); - $lastIndex = $numericIndices[count( $numericIndices ) - 1]; + $groupIndices = $this->getFlatArrayGroupIndices(); + $propertyId = $propertyIdProvider->getPropertyId(); + $idSerialization = $propertyId->getSerialization(); - if( $toIndex > $lastIndex + 1 || $toIndex < $numericIndices[0] ) { - throw new OutOfBoundsException( 'Object cannot be moved to ' . $toIndex ); - } - - if( $toIndex >= $lastIndex ) { - $this->moveObjectToEndOfPropertyGroup( $object ); + if ( isset( $groupIndices[$idSerialization] ) ) { + $groupIndex = $groupIndices[$idSerialization]; + $count = count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); } else { - $this->removeObject( $object ); - - $propertyGroup = array_combine( - $this->getFlatArrayIndices( $propertyId ), - $this->getByPropertyId( $propertyId ) - ); + $groupIndex = 0; + $count = 0; + } - $insertBefore = $propertyGroup[$toIndex]; - $this->insertObjectAtIndex( $object, $this->getFlatArrayIndexOfObject( $insertBefore ) ); + // if not inside of group also move property group + if ( $index < $groupIndex || $groupIndex + $count <= $index ) { + // find real index to insert + $index = $index === 0 ? 0 : $this->findNextIndex( $index ); + $this->moveGroupInFlatArray( $groupIndex, $count, $index ); } + + $this->addtoFlatArray( $propertyIdProvider, $index ); + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); } /** - * Moves an object to the end of its "property group". - * @since 0.5 + * Removes the PropertyIdProvider at the given index and returns it. * - * @param object $object + * @since 1.2 + * + * @param int $index + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ - private function moveObjectToEndOfPropertyGroup( $object ) { - $this->removeObject( $object ); - - /** @var PropertyId $propertyId */ - $propertyId = $object->getPropertyId(); - $propertyIdSerialization = $propertyId->getSerialization(); + public function removeAtIndex( $index ) { + $this->assertValidIndex( $index ); - $propertyGroup = in_array( $propertyIdSerialization, $this->getPropertyIds() ) - ? $this->getByPropertyId( $propertyId ) - : array(); + $object = $this->removeFromFlatArray( $index ); + $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); - $propertyGroup[] = $object; - $this->byId[$propertyIdSerialization] = $propertyGroup; - - $this->exchangeArray( $this->toFlatArray() ); + return $object; } /** - * Removes an object from the array structures. - * @since 0.5 + * Removes the given PropertyIdProvider and returns it. * - * @param object $object + * @since 1.2 + * + * @param PropertyIdProvider $propertyIdProvider + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ - private function removeObject( $object ) { - $flatArray = $this->toFlatArray(); - $this->exchangeArray( $flatArray ); - $this->offsetUnset( array_search( $object, $flatArray ) ); - $this->buildIndex(); + public function removeObject( PropertyIdProvider $propertyIdProvider ) { + return $this->removeAtIndex( $this->getIndex( $propertyIdProvider ) ); } /** - * Inserts an object at a specific index. - * @since 0.5 + * Moves a PropertyIdProvider from the old to the new index and returns it. * - * @param object $object - * @param int $index Absolute index within the flat list of objects. + * @since 1.2 + * + * @param int $oldIndex + * @param int $newIndex + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ - private function insertObjectAtIndex( $object, $index ) { - $flatArray = $this->toFlatArray(); + public function moveToIndex( $oldIndex, $newIndex ) { + $this->assertValidIndex( $oldIndex ); + $this->assertValidIndex( $newIndex ); - $this->exchangeArray( array_merge( - array_slice( $flatArray, 0, $index ), - array( $object ), - array_slice( $flatArray, $index ) - ) ); + $object = $this->removeAtIndex( $oldIndex ); + $this->addObjectAtIndex( $object, $newIndex ); - $this->buildIndex(); + return $object; } /** - * @since 0.5 + * Moves the given PropertyIdProvider to the new index and returns it. * - * @param PropertyId $propertyId - * @param int $toIndex + * @since 0.2 + * + * @param PropertyIdProvider $propertyIdProvider + * @param int $index + * @return PropertyIdProvider + * + * @throws InvalidArgumentException + * @throws OutOfBoundsException */ - private function movePropertyGroup( PropertyId $propertyId, $toIndex ) { - if( $this->getPropertyGroupIndex( $propertyId ) === $toIndex ) { - return; - } - - /** - * @var PropertyId - */ - $insertBefore = null; - - $oldIndex = $this->getPropertyGroupIndex( $propertyId ); - $byIdClone = $this->byId; - - // Remove "property group" to calculate the groups new index: - unset( $this->byId[$propertyId->getSerialization()] ); - - if( $toIndex > $oldIndex ) { - // If the group shall be moved towards the bottom, the number of objects within the - // group needs to be subtracted from the absolute toIndex: - $toIndex -= count( $byIdClone[$propertyId->getSerialization()] ); - } - - foreach( $this->getPropertyIds() as $pId ) { - // Accepting other than the exact index by using <= letting the "property group" "latch" - // in the next slot. - if( $toIndex <= $this->getPropertyGroupIndex( $pId ) ) { - $insertBefore = $pId; - break; - } - } - - $serializedPropertyId = $propertyId->getSerialization(); - $this->byId = array(); - - foreach( $byIdClone as $serializedPId => $objects ) { - $pId = new PropertyId( $serializedPId ); - if( $pId->equals( $propertyId ) ) { - continue; - } elseif( $pId->equals( $insertBefore ) ) { - $this->byId[$serializedPropertyId] = $byIdClone[$serializedPropertyId]; - } - $this->byId[$serializedPId] = $objects; - } - - if( is_null( $insertBefore ) ) { - $this->byId[$serializedPropertyId] = $byIdClone[$serializedPropertyId]; - } - - $this->exchangeArray( $this->toFlatArray() ); + public function moveObjectToIndex( PropertyIdProvider $propertyIdProvider, $index ) { + return $this->moveToIndex( $this->getIndex( $propertyIdProvider ), $index ); } /** - * Returns the index of a "property group" (the first object in the flat array that features - * the specified property). Returns false if property id could not be found. - * @since 0.5 + * Adds the object at the given index. + * @see array_splice * - * @param PropertyId $propertyId - * @return bool|int + * @param PropertyIdProvider $propertyIdProvider + * @param int $index */ - private function getPropertyGroupIndex( PropertyId $propertyId ) { - $i = 0; - - foreach( $this->byId as $serializedPropertyId => $objects ) { - $pId = new PropertyId( $serializedPropertyId ); - if( $pId->equals( $propertyId ) ) { - return $i; - } - $i += count( $objects ); - } - - return false; + private function addtoFlatArray( PropertyIdProvider $propertyIdProvider, $index ) { + array_splice( $this->flatArray, $index, 0, array( $propertyIdProvider ) ); } /** - * Moves an existing object to a new index. Specifying an index outside the object's "property - * group" will move the object to the edge of the "property group" and shift the whole group - * to achieve the designated index for the object to move. - * @since 0.5 + * Removes the object at the given index and returns it. + * @see array_splice * - * @param object $object - * @param int $toIndex Absolute index where to move the object to. + * @param int $index + * @return PropertyIdProvider + */ + private function removeFromFlatArray( $index ) { + $objects = array_splice( $this->flatArray, $index, 1 ); + return $objects[0]; + } + + /** + * Moves a list of objects with the given length from the start to the target index. + * @see array_splice * - * @throws RuntimeException|OutOfBoundsException + * @param int $start + * @param int $length + * @param int $target */ - public function moveObjectToIndex( $object, $toIndex ) { - $this->assertIndexIsBuild(); - - if( !in_array( $object, $this->toFlatArray() ) ) { - throw new OutOfBoundsException( 'Object not present in array' ); - } elseif( $toIndex < 0 || $toIndex > count( $this ) ) { - throw new OutOfBoundsException( 'Specified index is out of bounds' ); - } elseif( $this->getFlatArrayIndexOfObject( $object ) === $toIndex ) { - return; + private function moveGroupInFlatArray( $start, $length, $target ) { + // make sure we do not exceed the limits + if ( $start < $target ) { + $target = $target - $length; } - // Determine whether to simply reindex the object within its "property group": - $propertyIndices = $this->getFlatArrayIndices( $object->getPropertyId() ); + $objects = array_splice( $this->flatArray, $start, $length ); + array_splice( $this->flatArray, $target, 0, $objects ); + } - if( in_array( $toIndex, $propertyIndices ) ) { - $this->moveObjectInPropertyGroup( $object, $toIndex ); - } else { - $edgeIndex = ( $toIndex <= $propertyIndices[0] ) - ? $propertyIndices[0] - : $propertyIndices[count( $propertyIndices ) - 1]; + /** + * Finds the next index in the flat array which starts a new PropertyId group. + * + * @param int $index + * @return int + */ + private function findNextIndex( $index ) { + $groupIndices = $this->getFlatArrayGroupIndices(); - $this->moveObjectInPropertyGroup( $object, $edgeIndex ); - $this->movePropertyGroup( $object->getPropertyId(), $toIndex ); + foreach ( $groupIndices as $groupIndex ) { + if ( $groupIndex >= $index ) { + return $groupIndex; + } } - $this->exchangeArray( $this->toFlatArray() ); + return count( $this->flatArray ); } /** - * Adds an object at a specific index. If no index is specified, the object will be append to - * the end of its "property group" or - if no objects featuring the same property exist - to the - * absolute end of the array. - * Specifying an index outside a "property group" will place the new object at the specified - * index with the existing "property group" objects being shifted towards the new new object. - * @since 0.5 - * - * @param object $object - * @param int $index Absolute index where to place the new object. + * Finds all indeces where a new PropertyId group starts. * - * @throws RuntimeException + * @return int[] */ - public function addObjectAtIndex( $object, $index = null ) { - $this->assertIndexIsBuild(); - - $propertyId = $object->getPropertyId(); - $validIndices = $this->getFlatArrayIndices( $propertyId ); - - if( count( $this ) === 0 ) { - // Array is empty, just append object. - $this->append( $object ); - - } elseif( count( $validIndices ) === 0 ) { - // No objects featuring that property exist. The object may be inserted at a place - // between existing "property groups". - $this->append( $object ); - if( !is_null( $index ) ) { - $this->buildIndex(); - $this->moveObjectToIndex( $object, $index ); - } + private function getFlatArrayGroupIndices() { + $indices = array(); + $index = 0; - } else { - // Objects featuring the same property as the object which is about to be added already - // exist in the array. - $this->addObjectToPropertyGroup( $object, $index ); + foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { + $indices[$propertyId->getSerialization()] = $index; + $index += count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); } - $this->buildIndex(); + return $indices; } - /* - * Adds an object to an existing property group at the specified absolute index. - * @since 0.5 + /** + * Asserts that the given paramter is a valid index. * - * @param object $object * @param int $index + * @param bool $checkForEquality * + * @throws InvalidArgumentException * @throws OutOfBoundsException */ - private function addObjectToPropertyGroup( $object, $index = null ) { - /** @var PropertyId $propertyId */ - $propertyId = $object->getPropertyId(); - $validIndices = $this->getFlatArrayIndices( $propertyId ); - - if( count( $validIndices ) === 0 ) { - throw new OutOfBoundsException( 'No objects featuring the object\'s property exist' ); + private function assertValidIndex( $index, $checkForEquality = true ) { + if ( !is_int( $index ) ) { + throw new InvalidArgumentException( 'Only integer indices are supported.' ); } - // Add index to allow placing object after the last object of the "property group": - $validIndices[] = $validIndices[count( $validIndices ) - 1] + 1; - - if( is_null( $index ) ) { - // If index is null, append object to "property group". - $index = $validIndices[count( $validIndices ) - 1]; + if ( $index < 0 || $index > count( $this->flatArray ) ) { + throw new OutOfBoundsException( 'The index exceeds the array dimensions.' ); } - if( in_array( $index, $validIndices ) ) { - // Add object at index within "property group". - $this->byId[$propertyId->getSerialization()][] = $object; - $this->exchangeArray( $this->toFlatArray() ); - $this->moveObjectToIndex( $object, $index ); - - } else { - // Index is out of the "property group"; The whole group needs to be moved. - $this->movePropertyGroup( $propertyId, $index ); - - // Move new object to the edge of the "property group" to receive its designated - // index: - if( $index < $validIndices[0] ) { - array_unshift( $this->byId[$propertyId->getSerialization()], $object ); - } else { - $this->byId[$propertyId->getSerialization()][] = $object; - } + if ( $index === count( $this->flatArray ) && $checkForEquality ) { + throw new OutOfBoundsException( 'The index exceeds the array dimensions.' ); } - - $this->exchangeArray( $this->toFlatArray() ); } } diff --git a/tests/unit/ByPropertyIdArrayTest.php b/tests/unit/ByPropertyIdArrayTest.php index 15dfa64f..f31653f9 100644 --- a/tests/unit/ByPropertyIdArrayTest.php +++ b/tests/unit/ByPropertyIdArrayTest.php @@ -28,23 +28,6 @@ */ class ByPropertyIdArrayTest extends \PHPUnit_Framework_TestCase { - public function testArrayObjectNotConstructedFromObject() { - $claim1 = new Claim( new PropertyNoValueSnak( 1 ) ); - $claim1->setGuid( '1' ); - $claim2 = new Claim( new PropertyNoValueSnak( 2 ) ); - $claim2->setGuid( '2' ); - - $claims = new Claims(); - $claims->append( $claim1 ); - - $byPropertyIdArray = new ByPropertyIdArray( $claims ); - // According to the documentation append() "cannot be called when the ArrayObject was - // constructed from an object." This test makes sure it was not constructed from an object. - $byPropertyIdArray->append( $claim2 ); - - $this->assertCount( 2, $byPropertyIdArray ); - } - /** * Returns an accessible ReflectionMethod of ByPropertyIdArray. * @@ -206,20 +189,6 @@ public function testGetByNotSetIdThrowsException() { $indexedArray->getByPropertyId( PropertyId::newFromNumber( 9000 ) ); } - public function testNotBuildExceptionIsThrownForByPropertyId() { - $indexedArray = new ByPropertyIdArray(); - - $this->setExpectedException( 'RuntimeException' ); - $indexedArray->getByPropertyId( PropertyId::newFromNumber( 9000 ) ); - } - - public function testNotBuildExceptionIsThrownForGetPropertyIds() { - $indexedArray = new ByPropertyIdArray(); - - $this->setExpectedException( 'RuntimeException' ); - $indexedArray->getPropertyIds(); - } - /** * @dataProvider listProvider * @param array $objects @@ -257,43 +226,43 @@ public function moveProvider() { $argLists[] = array( $c, $c[0], 0, $c ); $argLists[] = array( $c, $c[0], 1, array( $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ) ); - $argLists[] = array( $c, $c[0], 2, array( $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ) ); + $argLists[] = array( $c, $c[0], 2, array( $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ) ); $argLists[] = array( $c, $c[0], 3, array( $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ) ); $argLists[] = array( $c, $c[0], 4, array( $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ) ); - $argLists[] = array( $c, $c[0], 5, array( $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ) ); - $argLists[] = array( $c, $c[0], 6, array( $c[2], $c[3], $c[4], $c[5], $c[1], $c[0] ) ); + $argLists[] = array( $c, $c[0], 5, array( $c[2], $c[3], $c[4], $c[5], $c[1], $c[0] ) ); + #$argLists[] = array( $c, $c[0], 6, array( $c[2], $c[3], $c[4], $c[5], $c[1], $c[0] ) ); $argLists[] = array( $c, $c[1], 0, array( $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ) ); $argLists[] = array( $c, $c[1], 1, $c ); - $argLists[] = array( $c, $c[1], 2, $c ); + $argLists[] = array( $c, $c[1], 2, array( $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ) ); $argLists[] = array( $c, $c[1], 3, array( $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ) ); // $argLists[] = array( $c, $c[1], 4, array( $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ) ); - $argLists[] = array( $c, $c[1], 5, array( $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ) ); - $argLists[] = array( $c, $c[1], 6, array( $c[2], $c[3], $c[4], $c[5], $c[0], $c[1] ) ); + $argLists[] = array( $c, $c[1], 5, array( $c[2], $c[3], $c[4], $c[5], $c[0], $c[1] ) ); + #$argLists[] = array( $c, $c[1], 6, array( $c[2], $c[3], $c[4], $c[5], $c[0], $c[1] ) ); $argLists[] = array( $c, $c[2], 0, array( $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ) ); $argLists[] = array( $c, $c[2], 1, $c ); $argLists[] = array( $c, $c[2], 2, $c ); $argLists[] = array( $c, $c[2], 3, array( $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ) ); $argLists[] = array( $c, $c[2], 4, array( $c[0], $c[1], $c[3], $c[4], $c[2], $c[5] ) ); - $argLists[] = array( $c, $c[2], 5, array( $c[0], $c[1], $c[3], $c[4], $c[2], $c[5] ) ); - $argLists[] = array( $c, $c[2], 6, array( $c[0], $c[1], $c[5], $c[3], $c[4], $c[2] ) ); + $argLists[] = array( $c, $c[2], 5, array( $c[0], $c[1], $c[5], $c[3], $c[4], $c[2] ) ); + #$argLists[] = array( $c, $c[2], 6, array( $c[0], $c[1], $c[5], $c[3], $c[4], $c[2] ) ); $argLists[] = array( $c, $c[3], 0, array( $c[3], $c[2], $c[4], $c[0], $c[1], $c[5] ) ); $argLists[] = array( $c, $c[3], 1, array( $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ) ); $argLists[] = array( $c, $c[3], 2, array( $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ) ); $argLists[] = array( $c, $c[3], 3, $c ); $argLists[] = array( $c, $c[3], 4, array( $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ) ); - $argLists[] = array( $c, $c[3], 5, array( $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ) ); - $argLists[] = array( $c, $c[3], 6, array( $c[0], $c[1], $c[5], $c[2], $c[4], $c[3] ) ); + $argLists[] = array( $c, $c[3], 5, array( $c[0], $c[1], $c[5], $c[2], $c[4], $c[3] ) ); + #$argLists[] = array( $c, $c[3], 6, array( $c[0], $c[1], $c[5], $c[2], $c[4], $c[3] ) ); $argLists[] = array( $c, $c[4], 0, array( $c[4], $c[2], $c[3], $c[0], $c[1], $c[5] ) ); $argLists[] = array( $c, $c[4], 1, array( $c[0], $c[1], $c[4], $c[2], $c[3], $c[5] ) ); $argLists[] = array( $c, $c[4], 2, array( $c[0], $c[1], $c[4], $c[2], $c[3], $c[5] ) ); $argLists[] = array( $c, $c[4], 3, array( $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ) ); $argLists[] = array( $c, $c[4], 4, $c ); - $argLists[] = array( $c, $c[4], 5, $c ); - $argLists[] = array( $c, $c[4], 6, array( $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ) ); + $argLists[] = array( $c, $c[4], 5, array( $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ) ); + #$argLists[] = array( $c, $c[4], 6, array( $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ) ); $argLists[] = array( $c, $c[5], 0, array( $c[5], $c[0], $c[1], $c[2], $c[3], $c[4] ) ); $argLists[] = array( $c, $c[5], 1, array( $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ) ); @@ -301,7 +270,7 @@ public function moveProvider() { $argLists[] = array( $c, $c[5], 3, $c ); $argLists[] = array( $c, $c[5], 4, $c ); $argLists[] = array( $c, $c[5], 5, $c ); - $argLists[] = array( $c, $c[5], 6, $c ); + #$argLists[] = array( $c, $c[5], 6, $c ); return $argLists; } @@ -324,12 +293,7 @@ public function testMoveObjectToIndex( $indexedArray->moveObjectToIndex( $object, $toIndex ); - // Not using $indexedArray->toFlatArray() here to test whether native array has been - // exchanged: - $reindexedArray = array(); - foreach( $indexedArray as $o ) { - $reindexedArray[] = $o; - } + $reindexedArray = $indexedArray->toFlatArray(); $this->assertEquals( $objectsDestination, $reindexedArray ); } @@ -359,8 +323,7 @@ public function addProvider() { $argLists = array(); - $argLists[] = array( array(), $c[0], null, array( $c[0] ) ); - $argLists[] = array( array(), $c[0], 1, array( $c[0] ) ); + $argLists[] = array( array(), $c[0], 0, array( $c[0] ) ); $argLists[] = array( array( $c[0] ), $c[2], 0, array( $c[2], $c[0] ) ); $argLists[] = array( array( $c[2], $c[1] ), $c[0], 0, array( $c[0], $c[1], $c[2] ) ); $argLists[] = array( @@ -378,8 +341,8 @@ public function addProvider() { $argLists[] = array( array( $c[0], $c[1], $c[2], $c[3], $c[5] ), $c[4], - null, - array( $c[0], $c[1], $c[2], $c[3], $c[4], $c[5] ) + 0, + array( $c[4], $c[2], $c[3], $c[0], $c[1], $c[5] ) ); return $argLists; From 1fb0e96cfadeb5a1fe7daa9ece75d7f04725cca5 Mon Sep 17 00:00:00 2001 From: Bene Date: Thu, 9 Oct 2014 20:22:21 +0200 Subject: [PATCH 14/14] Remove new classes --- src/ByPropertyIdArrayNew.php | 323 ------------------------ tests/unit/ByPropertyIdArrayNewTest.php | 113 --------- 2 files changed, 436 deletions(-) delete mode 100644 src/ByPropertyIdArrayNew.php delete mode 100644 tests/unit/ByPropertyIdArrayNewTest.php diff --git a/src/ByPropertyIdArrayNew.php b/src/ByPropertyIdArrayNew.php deleted file mode 100644 index 81194490..00000000 --- a/src/ByPropertyIdArrayNew.php +++ /dev/null @@ -1,323 +0,0 @@ - - */ -class ByPropertyIdArrayNew { - - /** - * @var ByPropertyIdGrouper - */ - private $byPropertyIdGrouper; - - /** - * @var PropertyIdProvider[] - */ - private $flatArray; - - /** - * @param PropertyIdProvider[] $propertyIdProviders - * - * @throws InvalidArgumentException - */ - public function __construct( array $propertyIdProviders ) { - $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $propertyIdProviders ); - $this->flatArray = array(); - - foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { - $propertyIdProviders = $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); - $this->flatArray = array_merge( $this->flatArray, $propertyIdProviders ); - } - } - - /** - * @since 0.2 - * @deprecated since 1.2 - */ - public function buildIndex() {} - - /** - * @since 0.2 - * @deprecated since 1.2 - * - * @param PropertyId $propertyId - * @return PropertyIdProvider[] - * - * @throws OutOfBoundsException - */ - public function getByPropertyId( PropertyId $propertyId ) { - return $this->byPropertyIdGrouper->getByPropertyId( $propertyId ); - } - - /** - * Returns the absolute index of an object or false if the object could not be found. - * - * @since 0.5 - * @deprecated since 1.2 - * - * @param object $object - * @return bool|int - * - * @throws RuntimeException - */ - public function getFlatArrayIndexOfObject( $object ) { - return array_search( $object, $this->flatArray, true ); - } - - /** - * @since 0.2 - * @deprecated since 1.2 - * - * @return PropertyId[] - */ - public function getPropertyIds() { - return $this->byPropertyIdGrouper->getPropertyIds(); - } - - /** - * Returns a list of all PropertyIdProvider instances grouped by their PropertyId. - * - * @since 0.2 - * - * @return PropertyIdProvider[] - */ - public function toFlatArray() { - return $this->flatArray; - } - - /** - * Returns the index of the given PropertyIdPovider in the flat array. - * - * @since 1.2 - * - * @param PropertyIdProvider $propertyIdProvider - * @return int - * - * @throws OutOfBoundsException - */ - public function getIndex( PropertyIdProvider $propertyIdProvider ) { - $index = array_search( $propertyIdProvider, $this->flatArray, true ); - - if ( $index === false ) { - throw new OutOfBoundsException( 'The given PropertyIdProvider was not found.' ); - } - - return $index; - } - - /** - * Adds the given PropertyIdProvider to the array at the given index. - * - * @since 0.2 - * - * @param PropertyIdProvider $propertyIdProvider - * @param int $index - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - public function addObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index ) { - $this->assertValidIndex( $index ); - - $groupIndices = $this->getFlatArrayGroupIndices(); - $propertyId = $propertyIdProvider->getPropertyId(); - $idSerialization = $propertyId->getSerialization(); - - if ( isset( $groupIndices[$idSerialization] ) ) { - $groupIndex = $groupIndices[$idSerialization]; - $count = count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); - } else { - $groupIndex = 0; - $count = 0; - } - - // if not inside of group also move property group - if ( $index < $groupIndex || $groupIndex + $count <= $index ) { - // find real index to insert - $index = $index === 0 ? 0 : $this->findNextIndex( $index ); - $this->moveGroupInFlatArray( $groupIndex, $count, $index ); - } - - $this->addtoFlatArray( $propertyIdProvider, $index ); - $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); - } - - /** - * Removes the PropertyIdProvider at the given index and returns it. - * - * @since 1.2 - * - * @param int $index - * @return PropertyIdProvider - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - public function removeAtIndex( $index ) { - $this->assertValidIndex( $index ); - - $object = $this->removeFromFlatArray( $index ); - $this->byPropertyIdGrouper = new ByPropertyIdGrouper( $this->flatArray ); - - return $object; - } - - /** - * Removes the given PropertyIdProvider and returns it. - * - * @since 1.2 - * - * @param PropertyIdProvider $propertyIdProvider - * @return PropertyIdProvider - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - public function removeObject( PropertyIdProvider $propertyIdProvider ) { - return $this->removeAtIndex( $this->getIndex( $propertyIdProvider ) ); - } - - /** - * Moves a PropertyIdProvider from the old to the new index and returns it. - * - * @since 1.2 - * - * @param int $oldIndex - * @param int $newIndex - * @return PropertyIdProvider - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - public function moveToIndex( $oldIndex, $newIndex ) { - $this->assertValidIndex( $oldIndex ); - $this->assertValidIndex( $newIndex ); - - $object = $this->removeAtIndex( $oldIndex ); - $this->addObjectAtIndex( $object, $newIndex ); - - return $object; - } - - /** - * Moves the given PropertyIdProvider to the new index and returns it. - * - * @since 0.2 - * - * @param PropertyIdProvider $propertyIdProvider - * @param int $index - * @return PropertyIdProvider - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - public function moveObjectToIndex( PropertyIdProvider $propertyIdProvider, $index ) { - return $this->moveToIndex( $this->getIndex( $propertyIdProvider ), $index ); - } - - /** - * Adds the object at the given index. - * @see array_splice - * - * @param PropertyIdProvider $propertyIdProvider - * @param int $index - */ - private function addtoFlatArray( PropertyIdProvider $propertyIdProvider, $index ) { - array_splice( $this->flatArray, $index, 0, array( $propertyIdProvider ) ); - } - - /** - * Removes the object at the given index and returns it. - * @see array_splice - * - * @param int $index - * @return PropertyIdProvider - */ - private function removeFromFlatArray( $index ) { - $objects = array_splice( $this->flatArray, $index, 1 ); - return $objects[0]; - } - - /** - * Moves a list of objects with the given length from the start to the target index. - * @see array_splice - * - * @param int $start - * @param int $length - * @param int $target - */ - private function moveGroupInFlatArray( $start, $length, $target ) { - // make sure we do not exceed the limits - if ( $start < $target ) { - $target = $target - $length; - } - - $objects = array_splice( $this->flatArray, $start, $length ); - array_splice( $this->flatArray, $target, 0, $objects ); - } - - /** - * Finds the next index in the flat array which starts a new PropertyId group. - * - * @param int $index - * @return int - */ - private function findNextIndex( $index ) { - $groupIndices = $this->getFlatArrayGroupIndices(); - - foreach ( $groupIndices as $groupIndex ) { - if ( $groupIndex >= $index ) { - return $groupIndex; - } - } - - return count( $this->flatArray ); - } - - /** - * Finds all indeces where a new PropertyId group starts. - * - * @return int[] - */ - private function getFlatArrayGroupIndices() { - $indices = array(); - $index = 0; - - foreach ( $this->byPropertyIdGrouper->getPropertyIds() as $propertyId ) { - $indices[$propertyId->getSerialization()] = $index; - $index += count( $this->byPropertyIdGrouper->getByPropertyId( $propertyId ) ); - } - - return $indices; - } - - /** - * Asserts that the given paramter is a valid index. - * - * @param int $index - * - * @throws InvalidArgumentException - * @throws OutOfBoundsException - */ - private function assertValidIndex( $index ) { - if ( !is_int( $index ) ) { - throw new InvalidArgumentException( 'Only integer indices are supported.' ); - } - - if ( $index < 0 || $index > count( $this->flatArray ) ) { - throw new OutOfBoundsException( 'The index exceeds the array dimensions.' ); - } - } - -} diff --git a/tests/unit/ByPropertyIdArrayNewTest.php b/tests/unit/ByPropertyIdArrayNewTest.php deleted file mode 100644 index 9916cf67..00000000 --- a/tests/unit/ByPropertyIdArrayNewTest.php +++ /dev/null @@ -1,113 +0,0 @@ -getByPropertyIdArray(); - $expectedTypes = array( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ); - $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->toFlatArray() ) ); - } - - public function testGetIndex() { - $byPropertyIdArray = $this->getByPropertyIdArray(); - $propertyIdProvider = $this->getSnakMock( 'P42', 'foo bar' ); - $byPropertyIdArray->addObjectAtIndex( $propertyIdProvider, 2 ); - $this->assertEquals( 2, $byPropertyIdArray->getIndex( $propertyIdProvider ) ); - } - - public function provideAddObjectAtIndex() { - $cases = array(); - - $cases[] = array( - $this->getSnakMock( 'P1', 'x' ), - 1, - array( 'a', 'x', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ) - ); - - $cases[] = array( - $this->getSnakMock( 'P1', 'x' ), - 5, - array( 'c', 'd', 'e', 'a', 'b', 'x', 'f', 'g', 'h' ) - ); - - $cases[] = array( - $this->getSnakMock( 'P2', 'x' ), - 0, - array( 'x', 'c', 'd', 'e', 'a', 'b', 'f', 'g', 'h' ) - ); - - $cases[] = array( - $this->getSnakMock( 'P2', 'x' ), - 8, - array( 'a', 'b', 'f', 'g', 'h', 'c', 'd', 'e', 'x' ) - ); - - $cases[] = array( - $this->getSnakMock( 'P2', 'x' ), - 7, - array( 'a', 'b', 'f', 'g', 'h', 'c', 'd', 'e', 'x' ) - ); - - return $cases; - } - - /** - * @dataProvider provideAddObjectAtIndex - */ - public function testAddObjectAtIndex( PropertyIdProvider $propertyIdProvider, $index, $expectedTypes ) { - $byPropertyIdArray = $this->getByPropertyIdArray(); - $byPropertyIdArray->addObjectAtIndex( $propertyIdProvider, $index ); - $this->assertEquals( $expectedTypes, $this->getTypes( $byPropertyIdArray->toFlatArray() ) ); - } - - private function getByPropertyIdArray() { - return new ByPropertyIdArrayNew( array( - $this->getSnakMock( 'P1', 'a' ), - $this->getSnakMock( 'P1', 'b' ), - $this->getSnakMock( 'P2', 'c' ), - $this->getSnakMock( 'P2', 'd' ), - $this->getSnakMock( 'P2', 'e' ), - $this->getSnakMock( 'P3', 'f' ), - $this->getSnakMock( 'P4', 'g' ), - $this->getSnakMock( 'P4', 'h' ) - ) ); - } - - private function getTypes( array $snaks ) { - return array_map( function( Snak $snak ) { - return $snak->getType(); - }, $snaks ); - } - - /** - * @param string $propertyId - * @param string $type - * @return Snak - */ - private function getSnakMock( $propertyId, $type ) { - $snak = $this->getMock( 'Wikibase\DataModel\Snak\Snak' ); - - $snak->expects( $this->any() ) - ->method( 'getPropertyId' ) - ->will( $this->returnValue( new PropertyId( $propertyId ) ) ); - - $snak->expects( $this->any() ) - ->method( 'getType' ) - ->will( $this->returnValue( $type ) ); - - return $snak; - } - -}