Skip to content

Commit

Permalink
Merge pull request #135 from wmde/statementsPatcher
Browse files Browse the repository at this point in the history
Introduce StatementListPatcher::patchStatementList
  • Loading branch information
JonasKress committed Apr 27, 2016
2 parents f3f2996 + ebd3459 commit 16dfc52
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 26 deletions.
68 changes: 42 additions & 26 deletions src/Diff/Internal/StatementListPatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace Wikibase\DataModel\Services\Diff\Internal;

use Diff\Comparer\CallbackComparer;
use Diff\DiffOp\Diff\Diff;
use Diff\Patcher\MapPatcher;
use Diff\DiffOp\DiffOp;
use Diff\DiffOp\DiffOpAdd;
use Diff\DiffOp\DiffOpChange;
use Diff\DiffOp\DiffOpRemove;
use Diff\Patcher\PatcherException;
use InvalidArgumentException;
use Wikibase\DataModel\Statement\Statement;
use Wikibase\DataModel\Statement\StatementList;
Expand All @@ -19,48 +22,61 @@
*
* @license GPL-2.0+
* @author Jeroen De Dauw < [email protected] >
* @author Thiemo Mättig
*/
class StatementListPatcher {

/**
* @var MapPatcher
* @since 3.6
*
* @param StatementList $statements
* @param Diff $patch
*
* @throws PatcherException
*/
private $patcher;
public function patchStatementList( StatementList $statements, Diff $patch ) {
/** @var DiffOp $diffOp */
foreach ( $patch as $diffOp ) {
switch ( true ) {
case $diffOp instanceof DiffOpAdd:
/** @var DiffOpAdd $diffOp */
$statements->addStatement( $diffOp->getNewValue() );
break;

public function __construct() {
$this->patcher = new MapPatcher();
case $diffOp instanceof DiffOpChange:
/** @var DiffOpChange $diffOp */
/** @var Statement $statement */
$statement = $diffOp->getOldValue();
$statements->removeStatementsWithGuid( $statement->getGuid() );
$statements->addStatement( $diffOp->getNewValue() );
break;

$this->patcher->setValueComparer( new CallbackComparer(
function( Statement $firstStatement, Statement $secondStatement ) {
return $firstStatement->equals( $secondStatement );
case $diffOp instanceof DiffOpRemove:
/** @var DiffOpRemove $diffOp */
/** @var Statement $statement */
$statement = $diffOp->getOldValue();
$statements->removeStatementsWithGuid( $statement->getGuid() );
break;

default:
throw new PatcherException( 'Invalid statement list diff' );
}
) );
}
}

/**
* @deprecated since 3.6, use patchStatementList instead
*
* @param StatementList $statements
* @param Diff $patch
*
* @throws InvalidArgumentException
* @return StatementList
*/
public function getPatchedStatementList( StatementList $statements, Diff $patch ) {
$statementsByGuid = array();

/**
* @var Statement $statement
*/
foreach ( $statements as $statement ) {
$statementsByGuid[$statement->getGuid()] = $statement;
}

$patchedList = new StatementList();

foreach ( $this->patcher->patch( $statementsByGuid, $patch ) as $statement ) {
$patchedList->addStatement( $statement );
}

return $patchedList;
$patched = clone $statements;
$this->patchStatementList( $patched, $patch );
return $patched;
}

}
87 changes: 87 additions & 0 deletions tests/unit/Diff/Internal/StatementListPatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use DataValues\StringValue;
use Diff\DiffOp\Diff\Diff;
use Diff\DiffOp\DiffOpAdd;
use Diff\DiffOp\DiffOpChange;
use Diff\DiffOp\DiffOpRemove;
use Wikibase\DataModel\Services\Diff\Internal\StatementListPatcher;
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
Expand All @@ -18,9 +19,93 @@
*
* @license GPL-2.0+
* @author Jeroen De Dauw < [email protected] >
* @author Thiemo Mättig
*/
class StatementListPatcherTest extends \PHPUnit_Framework_TestCase {

public function patchStatementListProvider() {
$statement1 = new Statement( new PropertyNoValueSnak( 1 ) );
$statement2 = new Statement( new PropertyNoValueSnak( 2 ) );

return array(
// Empty diffs
array(
new StatementList(),
new Diff(),
new StatementList()
),
array(
new StatementList( $statement1 ),
new Diff(),
new StatementList( $statement1 )
),

// Add operations
array(
new StatementList(),
new Diff( array( new DiffOpAdd( $statement1 ) ), true ),
new StatementList( $statement1 )
),
array(
new StatementList(),
new Diff( array( new DiffOpAdd( $statement1 ) ), false ),
new StatementList( $statement1 )
),
array(
new StatementList(),
new Diff( array( new DiffOpAdd( $statement1 ) ) ),
new StatementList( $statement1 )
),

// Remove operations
array(
new StatementList( $statement1 ),
new Diff( array( new DiffOpRemove( $statement1 ) ), true ),
new StatementList()
),
array(
new StatementList( $statement1 ),
new Diff( array( new DiffOpRemove( $statement1 ) ), false ),
new StatementList()
),
array(
new StatementList( $statement1 ),
new Diff( array( new DiffOpRemove( $statement1 ) ) ),
new StatementList()
),

// Mixed operations
array(
new StatementList( $statement1 ),
new Diff( array(
new DiffOpRemove( $statement1 ),
new DiffOpAdd( $statement2 ),
) ),
new StatementList( $statement2 )
),
array(
new StatementList( $statement1 ),
new Diff( array(
new DiffOpChange( $statement1, $statement2 ),
) ),
new StatementList( $statement2 )
),
);
}

/**
* @dataProvider patchStatementListProvider
*/
public function testPatchStatementList(
StatementList $statements,
Diff $patch,
StatementList $expected
) {
$patcher = new StatementListPatcher();
$patcher->patchStatementList( $statements, $patch );
$this->assertEquals( $expected, $statements );
}

public function testGivenEmptyDiff_listIsReturnedAsIs() {
$statements = new StatementList();

Expand All @@ -29,7 +114,9 @@ public function testGivenEmptyDiff_listIsReturnedAsIs() {

private function assertListResultsFromPatch( StatementList $expected, StatementList $original, Diff $patch ) {
$patcher = new StatementListPatcher();
$clone = clone $original;
$this->assertEquals( $expected, $patcher->getPatchedStatementList( $original, $patch ) );
$this->assertEquals( $clone, $original, 'original must not change' );
}

public function testFoo() {
Expand Down

0 comments on commit 16dfc52

Please sign in to comment.