-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #135 from wmde/statementsPatcher
Introduce StatementListPatcher::patchStatementList
- Loading branch information
Showing
2 changed files
with
129 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
|
@@ -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(); | ||
|
||
|
@@ -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() { | ||
|