Jeroen De Dauw has uploaded a new change for review.
https://gerrit.wikimedia.org/r/77255
Change subject: Update ListDiffer and CallbackListDiffer to make use of new
ArrayComparer classes
......................................................................
Update ListDiffer and CallbackListDiffer to make use of new ArrayComparer
classes
Change-Id: I4437d21a5557d30a1031332f2653d3659c91b8ba
---
M src/ArrayComparer/StrategicArrayComparer.php
M src/differ/CallbackListDiffer.php
M src/differ/ListDiffer.php
M tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
M tests/phpunit/differ/CallbackListDifferTest.php
5 files changed, 67 insertions(+), 107 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Diff
refs/changes/55/77255/1
diff --git a/src/ArrayComparer/StrategicArrayComparer.php
b/src/ArrayComparer/StrategicArrayComparer.php
index fbf0977..555925a 100644
--- a/src/ArrayComparer/StrategicArrayComparer.php
+++ b/src/ArrayComparer/StrategicArrayComparer.php
@@ -3,6 +3,7 @@
namespace Diff\ArrayComparer;
use Diff\Comparer\ValueComparer;
+use RuntimeException;
/**
* Computes the difference between two arrays by comparing elements with
@@ -60,11 +61,16 @@
* @param array $haystack
*
* @return bool|int|string
+ * @throws RuntimeException
*/
protected function arraySearch( $needle, array $haystack ) {
foreach ( $haystack as $valueOffset => $thing ) {
$areEqual = $this->valueComparer->valuesAreEqual(
$needle, $thing );
+ if ( !is_bool( $areEqual ) ) {
+ throw new RuntimeException( 'ValueComparer
returned a non-boolean value' );
+ }
+
if ( $areEqual ) {
return $valueOffset;
}
diff --git a/src/differ/CallbackListDiffer.php
b/src/differ/CallbackListDiffer.php
index e8f9e11..ce8c21f 100644
--- a/src/differ/CallbackListDiffer.php
+++ b/src/differ/CallbackListDiffer.php
@@ -2,7 +2,8 @@
namespace Diff;
-use Exception;
+use Diff\ArrayComparer\StrategicArrayComparer;
+use Diff\Comparer\CallbackComparer;
/**
* Differ that only looks at the values of the arrays (and thus ignores key
differences).
@@ -21,11 +22,11 @@
class CallbackListDiffer implements Differ {
/**
- * @since 0.5
+ * @since 0.8
*
- * @var callable|null
+ * @var ListDiffer
*/
- protected $comparisonCallback = null;
+ protected $differ = null;
/**
* Constructor.
@@ -35,7 +36,7 @@
* @param callable $comparisonCallback
*/
public function __construct( $comparisonCallback ) {
- $this->comparisonCallback = $comparisonCallback;
+ $this->differ = new ListDiffer( new StrategicArrayComparer( new
CallbackComparer( $comparisonCallback ) ) );
}
/**
@@ -49,68 +50,7 @@
* @return DiffOp[]
*/
public function doDiff( array $oldValues, array $newValues ) {
- $operations = array();
-
- foreach ( $this->diffArrays( $newValues, $oldValues ) as
$addition ) {
- $operations[] = new DiffOpAdd( $addition );
- }
-
- foreach ( $this->diffArrays( $oldValues, $newValues ) as
$removal ) {
- $operations[] = new DiffOpRemove( $removal );
- }
-
- return $operations;
- }
-
- /**
- * @since 0.5
- *
- * @param array $arrayOne
- * @param array $arrayTwo
- *
- * @return array
- */
- protected function diffArrays( array $arrayOne, array $arrayTwo ) {
- $notInTwo = array();
-
- foreach ( $arrayOne as $element ) {
- $valueOffset = $this->arraySearch( $element, $arrayTwo
);
-
- if ( $valueOffset === false ) {
- $notInTwo[] = $element;
- continue;
- }
-
- unset( $arrayTwo[$valueOffset] );
- }
-
- return $notInTwo;
- }
-
- /**
- * @since 0.5
- *
- * @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 = 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' );
- }
-
- if ( $areEqual ) {
- return $valueOffset;
- }
- }
-
- return false;
+ return $this->differ->doDiff( $oldValues, $newValues );
}
}
diff --git a/src/differ/ListDiffer.php b/src/differ/ListDiffer.php
index 757d130..108795c 100644
--- a/src/differ/ListDiffer.php
+++ b/src/differ/ListDiffer.php
@@ -2,13 +2,16 @@
namespace Diff;
+use Diff\ArrayComparer\ArrayComparer;
+use Diff\ArrayComparer\NativeArrayComparer;
use Diff\ArrayComparer\StrictArrayComparer;
+use InvalidArgumentException;
/**
* Differ that only looks at the values of the arrays (and thus ignores key
differences).
*
- * Values are compared using the strictDiff method in strict mode (default)
- * or using array_diff_assoc in native mode.
+ * By default values are compared using a StrictArrayComparer.
+ * You can alter the ArrayComparer used by providing one in the constructor.
*
* @since 0.4
*
@@ -25,6 +28,7 @@
* This makes use of @see array_diff
*
* @since 0.4
+ * @deprecated since 0.8
*/
const MODE_NATIVE = 0;
@@ -33,31 +37,48 @@
* This makes use of @see ListDiffer::strictDiff
*
* @since 0.4
+ * @deprecated since 0.8
*/
const MODE_STRICT = 1;
/**
- * @since 0.4
+ * @since 0.8
*
- * @var int
+ * @var ArrayComparer
*/
- protected $diffMode;
+ protected $arrayComparer;
/**
- * Constructor.
+ * @param ArrayComparer $arrayComparer
*
- * Takes an argument that determines the diff mode.
- * By default this is ListDiffer::MODE_STRICT, which causes
- * computation in @see doDiff to be done via @see arrayDiff.
- * If the native behavior is preferred, ListDiffer::MODE_NATIVE
- * can be specified.
- *
- * @since 0.4
- *
- * @param int $diffMode
+ * The first argument is an ArrayComparer since version 0.8.
+ * Before this it was an element of the ListDiffer::MODE_ enum.
+ * The later is still supported though deprecated.
*/
- public function __construct( $diffMode = self::MODE_STRICT ) {
- $this->diffMode = $diffMode;
+ public function __construct( $arrayComparer = null ) {
+ $this->arrayComparer = $this->getRealArrayComparer(
$arrayComparer );
+ }
+
+ /**
+ * @param $arrayComparer
+ *
+ * @return ArrayComparer
+ * @throws InvalidArgumentException
+ */
+ protected function getRealArrayComparer( $arrayComparer ) {
+ if ( $arrayComparer === null || $arrayComparer ===
self::MODE_STRICT ) {
+ return new StrictArrayComparer();
+ }
+
+ if ( $arrayComparer === self::MODE_NATIVE ) {
+ return new NativeArrayComparer();
+ }
+
+ if ( is_object( $arrayComparer ) && $arrayComparer instanceof
ArrayComparer ) {
+ return $arrayComparer;
+ }
+
+ throw new InvalidArgumentException( 'Got an invalid
$arrayComparer' );
}
/**
@@ -94,28 +115,7 @@
* @return array
*/
protected function diffArrays( array $arrayOne, array $arrayTwo ) {
- if ( $this->diffMode === self::MODE_STRICT ) {
- return $this->strictDiff( $arrayOne, $arrayTwo );
- }
- else {
- return array_diff( $arrayOne, $arrayTwo );
- }
- }
-
- /**
- * Returns an array containing all the entries from arrayOne that are
not present in arrayTwo.
- *
- * @since 0.4
- *
- * @param array $arrayOne
- * @param array $arrayTwo
- *
- * @return array
- */
- protected function strictDiff( array $arrayOne, array $arrayTwo ) {
- $differ = new StrictArrayComparer();
-
- return $differ->diffArrays( $arrayOne, $arrayTwo );
+ return $this->arrayComparer->diffArrays( $arrayOne, $arrayTwo );
}
}
diff --git a/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
b/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
index b457c0f..80e5cd4 100644
--- a/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
+++ b/tests/phpunit/ArrayComparer/StrategicArrayComparerTest.php
@@ -201,4 +201,18 @@
);
}
+ public function testCallbackComparisonReturningNyanCat() {
+ $valueComparer = $this->getMock( 'Diff\Comparer\ValueComparer'
);
+
+ $valueComparer->expects( $this->once() )
+ ->method( 'valuesAreEqual' )
+ ->will( $this->returnValue( '~=[,,_,,]:3' ) );
+
+ $arrayComparer = new StrategicArrayComparer( $valueComparer );
+
+ $this->setExpectedException( 'RuntimeException' );
+
+ $arrayComparer->diffArrays( array( 1, '2', 'baz' ), array( 1,
'foo', '2' ) );
+ }
+
}
diff --git a/tests/phpunit/differ/CallbackListDifferTest.php
b/tests/phpunit/differ/CallbackListDifferTest.php
index ad0e5e9..d8f8bdc 100644
--- a/tests/phpunit/differ/CallbackListDifferTest.php
+++ b/tests/phpunit/differ/CallbackListDifferTest.php
@@ -221,7 +221,7 @@
return '~=[,,_,,]:3';
} );
- $this->setExpectedException( 'Exception' );
+ $this->setExpectedException( 'RuntimeException' );
$differ->doDiff( array( 1, '2', 'baz' ), array( 1, 'foo', '2' )
);
}
--
To view, visit https://gerrit.wikimedia.org/r/77255
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4437d21a5557d30a1031332f2653d3659c91b8ba
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Diff
Gerrit-Branch: master
Gerrit-Owner: Jeroen De Dauw <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits