Jeroen De Dauw has uploaded a new change for review. https://gerrit.wikimedia.org/r/77247
Change subject: Implrmented StrategicArrayComparer ...................................................................... Implrmented StrategicArrayComparer Change-Id: Ib1f3f4c2a1e3f28fa142429cb64d115c4706fabd --- M src/ArrayComparer/StrategicArrayComparer.php M src/differ/CallbackListDiffer.php M tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php 3 files changed, 202 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Diff refs/changes/47/77247/1 diff --git a/src/ArrayComparer/StrategicArrayComparer.php b/src/ArrayComparer/StrategicArrayComparer.php index 39c6d32..d4a3656 100644 --- a/src/ArrayComparer/StrategicArrayComparer.php +++ b/src/ArrayComparer/StrategicArrayComparer.php @@ -3,12 +3,15 @@ namespace Diff\ArrayComparer; use Diff\Comparer\ValueComparer; +use Exception; /** * Computes the difference between two arrays by comparing elements with * a ValueComparer. * - * @since 0.7 + * Quantity matters: [42, 42] and [42] are different + * + * @since 0.8 * * @file * @ingroup Diff @@ -27,7 +30,7 @@ /** * @see ArrayComparer::diffArrays * - * @since 0.7 + * @since 0.8 * * @param array $arrayOne * @param array $arrayTwo @@ -35,7 +38,41 @@ * @return array */ public function diffArrays( array $arrayOne, array $arrayTwo ) { - return array(); // TODO: implement + $notInTwo = array(); + + foreach ( $arrayOne as $element ) { + $valueOffset = $this->arraySearch( $element, $arrayTwo ); + + if ( $valueOffset === false ) { + $notInTwo[] = $element; + continue; + } + + unset( $arrayTwo[$valueOffset] ); + } + + return $notInTwo; + } + + /** + * @since 0.8 + * + * @param string|int $needle + * @param array $haystack + * + * @return bool|int|string + * @throws Exception + */ + protected function arraySearch( $needle, array $haystack ) { + foreach ( $haystack as $valueOffset => $thing ) { + $areEqual = $this->valueComparer->valuesAreEqual( $needle, $thing ); + + if ( $areEqual ) { + return $valueOffset; + } + } + + return false; } } diff --git a/src/differ/CallbackListDiffer.php b/src/differ/CallbackListDiffer.php index 9f5dc28..e8f9e11 100644 --- a/src/differ/CallbackListDiffer.php +++ b/src/differ/CallbackListDiffer.php @@ -101,6 +101,7 @@ $areEqual = call_user_func_array( $this->comparisonCallback, array( $needle, $thing ) ); if ( !is_bool( $areEqual ) ) { + // TODO: throw a more specific exception type throw new Exception( 'Comparison callback returned a non-boolean value' ); } diff --git a/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php b/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php index 9d3b400..b457c0f 100644 --- a/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php +++ b/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php @@ -2,6 +2,7 @@ namespace Diff\Tests\ArrayComparer; +use Diff\ArrayComparer\ArrayComparer; use Diff\ArrayComparer\StrategicArrayComparer; use Diff\Tests\DiffTestCase; @@ -9,7 +10,7 @@ * @covers Diff\ArrayComparer\StrategicArrayComparer * * @file - * @since 0.7 + * @since 0.8 * * @ingroup DiffTest * @@ -25,26 +26,179 @@ $this->assertTrue( true ); } - public function testDiffArrays() { + public function testDiffArraysWithComparerThatAlwaysReturnsTrue() { + $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer' ); + + $valueComparer->expects( $this->any() ) + ->method( 'valuesAreEqual' ) + ->will( $this->returnValue( true ) ); + + $arrayComparer = new StrategicArrayComparer( $valueComparer ); + + $this->assertNoDifference( + $arrayComparer, + array( 0, 2, 4 ), + array( 1, 2, 9 ) + ); + + $this->assertNoDifference( + $arrayComparer, + array( 1, 2, 3 ), + array( 1, 2, 3 ) + ); + + $this->assertNoDifference( + $arrayComparer, + array( 'bah' ), + array( 'foo', 'bar', 'baz' ) + ); + + $this->assertNoDifference( + $arrayComparer, + array(), + array( 'foo', 'bar', 'baz' ) + ); + + $this->assertNoDifference( + $arrayComparer, + array(), + array() + ); + } + + protected function assertNoDifference( ArrayComparer $arrayComparer, array $arrayOne, array $arrayTwo ) { + $this->assertEquals( + array(), + $arrayComparer->diffArrays( + $arrayOne, + $arrayTwo + ) + ); + } + + public function testDiffArraysWithComparerThatAlwaysReturnsFalse() { + $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer' ); + + $valueComparer->expects( $this->any() ) + ->method( 'valuesAreEqual' ) + ->will( $this->returnValue( false ) ); + + $arrayComparer = new StrategicArrayComparer( $valueComparer ); + + $this->assertAllDifferent( + $arrayComparer, + array(), + array() + ); + + $this->assertAllDifferent( + $arrayComparer, + array( 1, 2, 3 ), + array() + ); + + $this->assertAllDifferent( + $arrayComparer, + array( 1, 2, 3 ), + array( 1, 2, 3 ) + ); + + $this->assertAllDifferent( + $arrayComparer, + array(), + array( 1, 2, 3 ) + ); + } + + protected function assertAllDifferent( ArrayComparer $arrayComparer, array $arrayOne, array $arrayTwo ) { + $this->assertEquals( + $arrayOne, + $arrayComparer->diffArrays( + $arrayOne, + $arrayTwo + ) + ); + } + + public function testQuantityMattersWithReturnTrue() { + $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer' ); + + $valueComparer->expects( $this->any() ) + ->method( 'valuesAreEqual' ) + ->will( $this->returnValue( true ) ); + + $arrayComparer = new StrategicArrayComparer( $valueComparer ); + + $this->assertEquals( + array( 1, 1, 1 ), + $arrayComparer->diffArrays( + array( 1, 1, 1, 1 ), + array( 1 ) + ) + ); + + $this->assertEquals( + array( 1 ), + $arrayComparer->diffArrays( + array( 1, 1, 1, 1 ), + array( 1, 1, 1 ) + ) + ); + } + + public function testQuantityMattersWithSimpleComparison() { $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer' ); $valueComparer->expects( $this->any() ) ->method( 'valuesAreEqual' ) ->will( $this->returnCallback( function( $firstValue, $secondValue ) { - return true; + return $firstValue == $secondValue; } ) ); $arrayComparer = new StrategicArrayComparer( $valueComparer ); $this->assertEquals( - array(), + array( 1, 2, 5 ), $arrayComparer->diffArrays( - array( 0, 2, 4 ), - array( 1, 2, 9 ) + array( 1, 1, 2, 3, 2, 5 ), + array( 1, 2, 3, 4 ) ) ); - // TODO: implement + $this->assertEquals( + array( 1 ), + $arrayComparer->diffArrays( + array( 1, 1, 1, 2, 2, 3 ), + array( 1, 1, 2, 2, 3, 3, 3 ) + ) + ); + + $this->assertEquals( + array( 1 ), + $arrayComparer->diffArrays( + array( 3, 1, 2, 1, 1, 2 ), + array( 1, 3, 3, 2, 2, 3, 1 ) + ) + ); + } + + public function testValueComparerGetsCalledWithCorrectValues() { + $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer' ); + + $valueComparer->expects( $this->once() ) + ->method( 'valuesAreEqual' ) + ->with( + $this->equalTo( 1 ), + $this->equalTo( 2 ) + ) + ->will( $this->returnValue( true ) ); + + $arrayComparer = new StrategicArrayComparer( $valueComparer ); + + $arrayComparer->diffArrays( + array( 1 ), + array( 2 ) + ); } } -- To view, visit https://gerrit.wikimedia.org/r/77247 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib1f3f4c2a1e3f28fa142429cb64d115c4706fabd Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Diff Gerrit-Branch: master Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits