Daniel Werner has submitted this change and it was merged.

Change subject: Implemented StrategicArrayComparer
......................................................................


Implemented StrategicArrayComparer

Change-Id: Ib1f3f4c2a1e3f28fa142429cb64d115c4706fabd
---
M RELEASE-NOTES.md
M src/ArrayComparer/ArrayComparer.php
M src/ArrayComparer/NativeArrayComparer.php
M src/ArrayComparer/StrategicArrayComparer.php
M src/ArrayComparer/StrictArrayComparer.php
M src/differ/CallbackListDiffer.php
M tests/phpunit/ArrayComparer/NativeArrayComparerTest.php
M tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
M tests/phpunit/ArrayComparer/StrictArrayComparerTest.php
9 files changed, 225 insertions(+), 26 deletions(-)

Approvals:
  Daniel Werner: Looks good to me, approved



diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index f1c82cc..01e3a08 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -4,6 +4,13 @@
 
 ## Version 0.8 (dev)
 
+#### Additions
+
+* Added Diff\ArrayComparer\ArrayComparer interface
+* Added NativeArrayComparer, ArrayComparer adapter for array_diff
+* Added StrictArrayComparer, containing the "strict mode" logic from ListDiffer
+* Added StrategicArrayComparer, implementation of ArrayComparer that takes a 
ValueComparer as strategy
+
 #### Improvements
 
 * MapPatcher will now report conflicts for remove operations that specify a 
value to be removed
diff --git a/src/ArrayComparer/ArrayComparer.php 
b/src/ArrayComparer/ArrayComparer.php
index 8fbab4c..99c6ab9 100644
--- a/src/ArrayComparer/ArrayComparer.php
+++ b/src/ArrayComparer/ArrayComparer.php
@@ -6,7 +6,7 @@
  * Interface for objects that can compute the difference between two arrays
  * in similar fashion to PHPs native array_diff.
  *
- * @since 0.7
+ * @since 0.8
  *
  * @file
  * @ingroup Diff
@@ -19,7 +19,9 @@
        /**
         * Returns an array containing all the entries from arrayOne that are 
not present in arrayTwo.
         *
-        * @since 0.7
+        * Implementations are allowed to hold quantity into account or to 
disregard it.
+        *
+        * @since 0.8
         *
         * @param array $firstArray
         * @param array $secondArray
diff --git a/src/ArrayComparer/NativeArrayComparer.php 
b/src/ArrayComparer/NativeArrayComparer.php
index 798e873..c5ef04f 100644
--- a/src/ArrayComparer/NativeArrayComparer.php
+++ b/src/ArrayComparer/NativeArrayComparer.php
@@ -5,7 +5,7 @@
 /**
  * Adapter for PHPs native array_diff method.
  *
- * @since 0.7
+ * @since 0.8
  *
  * @file
  * @ingroup Diff
@@ -20,7 +20,7 @@
         *
         * Uses @see array_diff.
         *
-        * @since 0.7
+        * @since 0.8
         *
         * @param array $arrayOne
         * @param array $arrayTwo
diff --git a/src/ArrayComparer/StrategicArrayComparer.php 
b/src/ArrayComparer/StrategicArrayComparer.php
index 39c6d32..fbf0977 100644
--- a/src/ArrayComparer/StrategicArrayComparer.php
+++ b/src/ArrayComparer/StrategicArrayComparer.php
@@ -8,7 +8,9 @@
  * 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 +29,7 @@
        /**
         * @see ArrayComparer::diffArrays
         *
-        * @since 0.7
+        * @since 0.8
         *
         * @param array $arrayOne
         * @param array $arrayTwo
@@ -35,7 +37,40 @@
         * @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
+        */
+       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/ArrayComparer/StrictArrayComparer.php 
b/src/ArrayComparer/StrictArrayComparer.php
index 785bce8..6d3e2c3 100644
--- a/src/ArrayComparer/StrictArrayComparer.php
+++ b/src/ArrayComparer/StrictArrayComparer.php
@@ -5,7 +5,15 @@
 /**
  * Strict variant of PHPs array_diff method.
  *
- * @since 0.7
+ * Similar to @see array_diff with the following differences:
+ *
+ * - Strict comparison for arrays: ['42'] and [42] are different
+ * - Quantity matters: [42, 42] and [42] are different
+ * - Arrays and objects are compared properly: [[1]] and [[2]] are different
+ * - Naive support for objects by using non-strict comparison
+ * - Only works with two arrays (array_diff can take more)
+ *
+ * @since 0.8
  *
  * @file
  * @ingroup Diff
@@ -18,15 +26,7 @@
        /**
         * @see ArrayComparer::diffArrays
         *
-        * Similar to @see array_diff with the following differences:
-        *
-        * - Strict comparison for arrays: ['42'] and [42] are different
-        * - Quantity matters: [42, 42] and [42] are different
-        * - Arrays and objects are compared properly: [[1]] and [[2]] are 
different
-        * - Naive support for objects by using non-strict comparison
-        * - Only works with two arrays (array_diff can take more)
-        *
-        * @since 0.7
+        * @since 0.8
         *
         * @param array $arrayOne
         * @param array $arrayTwo
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/NativeArrayComparerTest.php 
b/tests/phpunit/ArrayComparer/NativeArrayComparerTest.php
index 5b5de97..cdbd68e 100644
--- a/tests/phpunit/ArrayComparer/NativeArrayComparerTest.php
+++ b/tests/phpunit/ArrayComparer/NativeArrayComparerTest.php
@@ -9,7 +9,7 @@
  * @covers Diff\ArrayComparer\NativeArrayComparer
  *
  * @file
- * @since 0.7
+ * @since 0.8
  *
  * @ingroup DiffTest
  *
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 )
+               );
        }
 
 }
diff --git a/tests/phpunit/ArrayComparer/StrictArrayComparerTest.php 
b/tests/phpunit/ArrayComparer/StrictArrayComparerTest.php
index c1f065b..35cd54b 100644
--- a/tests/phpunit/ArrayComparer/StrictArrayComparerTest.php
+++ b/tests/phpunit/ArrayComparer/StrictArrayComparerTest.php
@@ -9,7 +9,7 @@
  * @covers Diff\ArrayComparer\StrictArrayComparer
  *
  * @file
- * @since 0.7
+ * @since 0.8
  *
  * @ingroup DiffTest
  *

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib1f3f4c2a1e3f28fa142429cb64d115c4706fabd
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/Diff
Gerrit-Branch: master
Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com>
Gerrit-Reviewer: Daniel Werner <daniel.wer...@wikimedia.de>
Gerrit-Reviewer: Jeroen De Dauw <jeroended...@gmail.com>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to