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 <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits