Skip to content

Commit

Permalink
Add StatementListChanger
Browse files Browse the repository at this point in the history
  • Loading branch information
thiemowmde committed Nov 8, 2016
1 parent 7b0d6d5 commit 6f85c91
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 0 deletions.
69 changes: 69 additions & 0 deletions src/Statement/StatementListChanger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Wikibase\DataModel\Services\Statement;

use Wikibase\DataModel\ByPropertyIdArray;
use Wikibase\DataModel\Statement\Statement;
use Wikibase\DataModel\Statement\StatementList;

/**
* A collection of functions to manipulate StatementList objects.
*
* @license GPL-2.0+
* @author Thiemo Mättig
*/
class StatementListChanger {

public function clear( StatementList $statementList ) {
foreach ( $statementList->toArray() as $statement ) {
$statementList->removeStatementsWithGuid( $statement->getGuid() );
}
}

/**
* @param StatementList $statementList
* @param Statement[] $statements
*/
private function replaceStatements( StatementList $statementList, array $statements ) {
$this->clear( $statementList );

foreach ( $statements as $statement ) {
$statementList->addStatement( $statement );
}
}

public function groupByProperty( StatementList $statementList ) {
$byId = [];

foreach ( $statementList->toArray() as $statement ) {
$id = $statement->getPropertyId()->getSerialization();
$byId[$id][] = $statement;
}

$this->clear( $statementList );

foreach ( $byId as $statements ) {
foreach ( $statements as $statement ) {
$statementList->addStatement( $statement );
}
}
}

/**
* @param StatementList $statementList
* @param Statement $statement
* @param int $index
*/
public function addToGroup( StatementList $statementList, Statement $statement, $index ) {
if ( $statementList->isEmpty() ) {
$statementList->addStatement( $statement );
return;
}

$byPropertyIdArray = new ByPropertyIdArray( $statementList->toArray() );
$byPropertyIdArray->buildIndex();
$byPropertyIdArray->addObjectAtIndex( $statement, $index );
$this->replaceStatements( $statementList, $byPropertyIdArray->toFlatArray() );
}

}
168 changes: 168 additions & 0 deletions tests/unit/Statement/StatementListChangerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php

namespace Wikibase\DataModel\Services\Tests\Statement;

use PHPUnit_Framework_TestCase;
use Wikibase\DataModel\Entity\PropertyId;
use Wikibase\DataModel\Services\Statement\StatementListChanger;
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
use Wikibase\DataModel\Statement\Statement;
use Wikibase\DataModel\Statement\StatementList;

/**
* @covers Wikibase\DataModel\Services\Statement\StatementListChanger
*
* @license GPL-2.0+
* @author Thiemo Mättig
*/
class StatementListChangerTest extends PHPUnit_Framework_TestCase {

public function testConstructor() {
$instance = new StatementListChanger();

$this->assertInstanceOf( StatementListChanger::class, $instance );
}

public function testClear() {
$statementList = $this->newStatementList( [ 'P1$A' ] );

$instance = new StatementListChanger();
$instance->clear( $statementList );

$this->assertTrue( $statementList->isEmpty() );
}

/**
* @dataProvider groupByPropertyIdProvider
*/
public function testGroupByPropertyId( array $guids, array $expectedGuids ) {
$statementList = $this->newStatementList( $guids );

$instance = new StatementListChanger();
$instance->groupByProperty( $statementList );

$this->assertGuids( $expectedGuids, $statementList );
}

public function groupByPropertyIdProvider() {
return [
[
[],
[]
],
[
[ 'P1$A' ],
[ 'P1$A' ]
],
[
[ 'P1$A', 'P2$B', 'P1$C', 'P2$D' ],
[ 'P1$A', 'P1$C', 'P2$B', 'P2$D' ]
],
[
[ 'P1$A', 'P1$B', 'P2$C', 'P3$D', 'P1$E', 'P2$F' ],
[ 'P1$A', 'P1$B', 'P1$E', 'P2$C', 'P2$F', 'P3$D' ]
],
];
}

/**
* @dataProvider addToGroupProvider
*/
public function testAddToGroup( array $guids, $newGuid, $index, array $expectedGuids ) {
$statementList = $this->newStatementList( $guids );
$statement = $this->newStatement( $newGuid );

$instance = new StatementListChanger();
$instance->addToGroup( $statementList, $statement, $index );

$this->assertGuids( $expectedGuids, $statementList );
}

public function addToGroupProvider() {
return [
'add to empty list' => [
[],
'P1$A',
0,
[ 'P1$A' ]
],
'negative index' => [
[],
'P1$A',
-100,
[ 'P1$A' ]
],
'extreme index' => [
[],
'P1$A',
100,
[ 'P1$A' ]
],
'append one statement' => [
[ 'P1$A' ],
'P1$B',
1,
[ 'P1$A', 'P1$B' ]
],
'prepend one statement' => [
[ 'P1$A' ],
'P1$B',
0,
[ 'P1$B', 'P1$A' ]
],
'insert one statement' => [
[ 'P1$A', 'P2$B' ],
'P1$C',
1,
[ 'P1$A', 'P1$C', 'P2$B' ]
],
'move group to the end' => [
[ 'P1$A', 'P2$B' ],
'P1$C',
100,
[ 'P2$B', 'P1$A', 'P1$C' ]
],
];
}

/**
* @param string[] $guids
*
* @return StatementList
*/
private function newStatementList( array $guids ) {
$statementList = new StatementList();

foreach ( $guids as $guid ) {
$statementList->addStatement( $this->newStatement( $guid ) );
}

return $statementList;
}

private function newStatement( $guid ) {
list( $propertyId, ) = explode( '$', $guid, 2 );

return new Statement(
new PropertyNoValueSnak( new PropertyId( $propertyId ) ),
null,
null,
$guid
);
}

/**
* @param string[] $expectedGuids
* @param StatementList $statementList
*/
private function assertGuids( array $expectedGuids, StatementList $statementList ) {
$guids = [];

foreach ( $statementList->toArray() as $statement ) {
$guids[] = $statement->getGuid();
}

$this->assertSame( $expectedGuids, $guids );
}

}

0 comments on commit 6f85c91

Please sign in to comment.