Jeroen De Dauw has uploaded a new change for review.
https://gerrit.wikimedia.org/r/60870
Change subject: Introduced ValueComparer interface
......................................................................
Introduced ValueComparer interface
Change-Id: I671a8dc821e2f02f451723d36fa0674528723f70
---
M Diff.classes.php
M Diff.mw.php
M RELEASE-NOTES
A includes/Comparer/CallbackComparer.php
A includes/Comparer/StrictComparer.php
A includes/Comparer/ValueComparer.php
M includes/patcher/MapPatcher.php
A tests/phpunit/Comparer/CallbackComparerTest.php
A tests/phpunit/Comparer/StrictComparerTest.php
M tests/phpunit/patcher/MapPatcherTest.php
10 files changed, 393 insertions(+), 2 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Diff
refs/changes/70/60870/1
diff --git a/Diff.classes.php b/Diff.classes.php
index fb1ff9e..fb806a0 100644
--- a/Diff.classes.php
+++ b/Diff.classes.php
@@ -15,6 +15,10 @@
'Diff\Appendable' => 'includes/Appendable.php',
'Diff\DiffOpFactory' => 'includes/DiffOpFactory.php',
+ 'Diff\Comparer\CallbackComparer' =>
'includes/Comparer/CallbackComparer.php',
+ 'Diff\Comparer\StrictComparer' =>
'includes/Comparer/StrictComparer.php',
+ 'Diff\Comparer\ValueComparer' => 'includes/Comparer/ValueComparer.php',
+
'Diff\CallbackListDiffer' => 'includes/differ/CallbackListDiffer.php',
'Diff\Differ' => 'includes/differ/Differ.php',
'Diff\ListDiffer' => 'includes/differ/ListDiffer.php',
diff --git a/Diff.mw.php b/Diff.mw.php
index daae74c..dfadc9e 100644
--- a/Diff.mw.php
+++ b/Diff.mw.php
@@ -58,6 +58,9 @@
$wgHooks['UnitTestsList'][] = function( array &$files ) {
// @codeCoverageIgnoreStart
$testFiles = array(
+ 'Comparer/CallbackComparer',
+ 'Comparer/StrictComparer',
+
'differ/CallbackListDiffer',
'differ/ListDiffer',
'differ/MapDiffer',
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 0f0a207..3d412e2 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -15,6 +15,8 @@
; Additions
* Added phpunit.php runner in the tests directory
+* Added Diff\Comparer\ValueComparer interface with CallbackComparer and
StrictComparer implementations
+* Added MapPatcher::setValueComparer to facilitate patching maps containing
objects
; Removals
diff --git a/includes/Comparer/CallbackComparer.php
b/includes/Comparer/CallbackComparer.php
new file mode 100644
index 0000000..749719c
--- /dev/null
+++ b/includes/Comparer/CallbackComparer.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Diff\Comparer;
+
+/**
+ * Adapter around a comparision callback that implements the ValueComparer
+ * interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.6
+ *
+ * @file
+ * @ingroup Diff
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class CallbackComparer implements ValueComparer {
+
+ private $callback;
+
+ /**
+ * @since 0.6
+ *
+ * @param callable $callback
+ */
+ public function __construct( $callback ) {
+ $this->callback = $callback;
+ }
+
+ public function valuesAreEqual( $firstValue, $secondValue ) {
+ return call_user_func_array( $this->callback, array(
$firstValue, $secondValue ) );
+ }
+
+}
diff --git a/includes/Comparer/StrictComparer.php
b/includes/Comparer/StrictComparer.php
new file mode 100644
index 0000000..4734858
--- /dev/null
+++ b/includes/Comparer/StrictComparer.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Diff\Comparer;
+
+/**
+ * Value comparer that uses PHPs native strict equality check (ie ===).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.6
+ *
+ * @file
+ * @ingroup Diff
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class StrictComparer implements ValueComparer {
+
+ public function valuesAreEqual( $firstValue, $secondValue ) {
+ return $firstValue === $secondValue;
+ }
+
+}
diff --git a/includes/Comparer/ValueComparer.php
b/includes/Comparer/ValueComparer.php
new file mode 100644
index 0000000..97dfb42
--- /dev/null
+++ b/includes/Comparer/ValueComparer.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Diff\Comparer;
+
+/**
+ * Interface for objects that can determine if two values are equal.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.6
+ *
+ * @file
+ * @ingroup Diff
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+interface ValueComparer {
+
+ /**
+ * @since 0.6
+ *
+ * @param mixed $firstValue
+ * @param mixed $secondValue
+ *
+ * @return boolean
+ */
+ public function valuesAreEqual( $firstValue, $secondValue );
+
+}
diff --git a/includes/patcher/MapPatcher.php b/includes/patcher/MapPatcher.php
index 5c3f920..2ebd70f 100644
--- a/includes/patcher/MapPatcher.php
+++ b/includes/patcher/MapPatcher.php
@@ -2,6 +2,8 @@
namespace Diff;
+use Diff\Comparer\StrictComparer;
+use Diff\Comparer\ValueComparer;
use RuntimeException;
/**
@@ -40,10 +42,17 @@
protected $listPatcher;
/**
+ * @since 0.6
+ *
+ * @var ValueComparer|null
+ */
+ protected $comparer = null;
+
+ /**
* @since 0.4
*
* @param bool $throwErrors
- * @param Patcher|null $listPatcher
+ * @param Patcher|null $listPatcher The patcher that will be used for
lists in the value
*/
public function __construct( $throwErrors = false, Patcher $listPatcher
= null ) {
parent::__construct( $throwErrors );
@@ -53,6 +62,17 @@
}
$this->listPatcher = $listPatcher;
+ }
+
+ /**
+ * Sets the value comparer that should be used to determine if values
are equal.
+ *
+ * @since 0.6
+ *
+ * @param ValueComparer $comparer
+ */
+ public function setValueComparer( ValueComparer $comparer ) {
+ $this->comparer = $comparer;
}
/**
@@ -132,7 +152,7 @@
continue;
}
- if ( $base[$key] !== $diffOp->getOldValue() ) {
+ if ( !$this->valuesAreEqual( $base[$key],
$diffOp->getOldValue() ) ) {
$this->handleError( 'Tried changing a
map value from an invalid source value' );
continue;
}
@@ -147,4 +167,12 @@
return $base;
}
+ protected function valuesAreEqual( $firstValue, $secondValue ) {
+ if ( $this->comparer === null ) {
+ $this->comparer = new StrictComparer();
+ }
+
+ return $this->comparer->valuesAreEqual( $firstValue,
$secondValue );
+ }
+
}
diff --git a/tests/phpunit/Comparer/CallbackComparerTest.php
b/tests/phpunit/Comparer/CallbackComparerTest.php
new file mode 100644
index 0000000..ef70534
--- /dev/null
+++ b/tests/phpunit/Comparer/CallbackComparerTest.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Diff\Tests\Comparer;
+
+use Diff\Comparer\CallbackComparer;
+use Diff\Tests\DiffTestCase;
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 0.6
+ *
+ * @ingroup DiffTest
+ *
+ * @group Diff
+ * @group Comparer
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class CallbackComparerTest extends DiffTestCase {
+
+ protected function newComparerInstance() {
+ return new CallbackComparer( function( $firstValue,
$secondValue ) {
+ return $firstValue === 1 || $firstValue ===
$secondValue;
+ } );
+ }
+
+ /**
+ * @dataProvider equalProvider
+ */
+ public function testEqualValuesAreEqual( $firstValue, $secondValue ) {
+ $comparer = $this->newComparerInstance();
+
+ $this->assertTrue( $comparer->valuesAreEqual( $firstValue,
$secondValue ) );
+ }
+
+ public function equalProvider() {
+ return array(
+ array( 1, 0 ),
+ array( 1, 1 ),
+ array( 1, 2 ),
+ array( 2, 2 ),
+ );
+ }
+
+ /**
+ * @dataProvider unequalProvider
+ */
+ public function testDifferentValuesAreNotEqual( $firstValue,
$secondValue ) {
+ $comparer = $this->newComparerInstance();
+
+ $this->assertFalse( $comparer->valuesAreEqual( $firstValue,
$secondValue ) );
+ }
+
+ public function unequalProvider() {
+ return array(
+ array( 0, 1 ),
+ array( 0, 2 ),
+ array( 0, '0' ),
+ );
+ }
+
+}
diff --git a/tests/phpunit/Comparer/StrictComparerTest.php
b/tests/phpunit/Comparer/StrictComparerTest.php
new file mode 100644
index 0000000..a6d8472
--- /dev/null
+++ b/tests/phpunit/Comparer/StrictComparerTest.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Diff\Tests\Comparer;
+
+use Diff\Comparer\StrictComparer;
+use Diff\Tests\DiffTestCase;
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 0.6
+ *
+ * @ingroup DiffTest
+ *
+ * @group Diff
+ * @group Comparer
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class StrictComparerTest extends DiffTestCase {
+
+ /**
+ * @dataProvider equalProvider
+ */
+ public function testEqualValuesAreEqual( $firstValue, $secondValue ) {
+ $comparer = new StrictComparer();
+
+ $this->assertTrue( $comparer->valuesAreEqual( $firstValue,
$secondValue ) );
+ }
+
+ public function equalProvider() {
+ return array(
+ array( 1, 1 ),
+ array( '', '' ),
+ array( '1', '1' ),
+ array( 'foo bar ', 'foo bar ' ),
+ array( 4.2, 4.2 ),
+ array( null, null ),
+ array( false, false ),
+ array( true, true ),
+ array( array(), array() ),
+ array( array( 1 ), array( 1 ) ),
+ array( array( 1, 2, 'a' ), array( 1, 2, 'a' ) ),
+ array( array( 'a' => 1, 'b' => 2, null ), array( 'a' =>
1, 'b' => 2, null ) ),
+ );
+ }
+
+ /**
+ * @dataProvider unequalProvider
+ */
+ public function testDifferentValuesAreNotEqual( $firstValue,
$secondValue ) {
+ $comparer = new StrictComparer();
+
+ $this->assertFalse( $comparer->valuesAreEqual( $firstValue,
$secondValue ) );
+ }
+
+ public function unequalProvider() {
+ return array(
+ array( 1, 2 ),
+ array( '', '0' ),
+ array( '', ' ' ),
+ array( '', 0 ),
+ array( '', false ),
+ array( null, false ),
+ array( null, 0 ),
+ array( '1', '01' ),
+ array( 'foo bar', 'foo bar ' ),
+ array( 4, 4.0 ),
+ array( 4.2, 4.3 ),
+ array( false, true ),
+ array( true, '1' ),
+ array( array(), array( 1 ) ),
+ array( array( 1 ), array( 2 ) ),
+ array( array( 1, 2, 'b' ), array( 1, 2, 'c' ) ),
+ array( array( 'a' => 1, 'b' => 2 ), array( 'a' => 1,
'b' => 2, null ) ),
+ array( new \stdClass(), new \stdClass() ),
+ array( (object)array( 'a' => 1, 'b' => 2, null ),
(object)array( 'a' => 1, 'b' => 3, null ) ),
+ );
+ }
+
+}
diff --git a/tests/phpunit/patcher/MapPatcherTest.php
b/tests/phpunit/patcher/MapPatcherTest.php
index a4f90bb..8b582c0 100644
--- a/tests/phpunit/patcher/MapPatcherTest.php
+++ b/tests/phpunit/patcher/MapPatcherTest.php
@@ -2,6 +2,8 @@
namespace Diff\Tests;
+use Diff\Comparer\CallbackComparer;
+use Diff\Comparer\StrictComparer;
use Diff\Diff;
use Diff\DiffOpAdd;
use Diff\DiffOpChange;
@@ -215,4 +217,53 @@
$this->assertEquals( $expected->getOperations(),
$actual->getOperations(), $message );
}
+ public function testSetValueComparerToAlwaysFalse() {
+ $patcher = new MapPatcher();
+
+ $patcher->setValueComparer( new CallbackComparer( function(
$firstValue, $secondValue ) {
+ return false;
+ } ) );
+
+ $baseMap = array(
+ 'foo' => 42,
+ 'bar' => 9001,
+ );
+
+ $patch = new Diff( array(
+ 'foo' => new DiffOpChange( 42, 1337 ),
+ 'bar' => new DiffOpChange( 9001, 1337 ),
+ ) );
+
+ $patchedMap = $patcher->patch( $baseMap, $patch );
+
+ $this->assertEquals( $baseMap, $patchedMap );
+ }
+
+ public function testSetValueComparerToAlwaysTrue() {
+ $patcher = new MapPatcher();
+
+ $patcher->setValueComparer( new CallbackComparer( function(
$firstValue, $secondValue ) {
+ return true;
+ } ) );
+
+ $baseMap = array(
+ 'foo' => 42,
+ 'bar' => 9001,
+ );
+
+ $patch = new Diff( array(
+ 'foo' => new DiffOpChange( 3, 1337 ),
+ 'bar' => new DiffOpChange( 3, 1337 ),
+ ) );
+
+ $expectedMap = array(
+ 'foo' => 1337,
+ 'bar' => 1337,
+ );
+
+ $patchedMap = $patcher->patch( $baseMap, $patch );
+
+ $this->assertEquals( $expectedMap, $patchedMap );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/60870
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I671a8dc821e2f02f451723d36fa0674528723f70
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