Skip to content

Commit 6f85c91

Browse files
committed
Add StatementListChanger
1 parent 7b0d6d5 commit 6f85c91

2 files changed

Lines changed: 237 additions & 0 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Services\Statement;
4+
5+
use Wikibase\DataModel\ByPropertyIdArray;
6+
use Wikibase\DataModel\Statement\Statement;
7+
use Wikibase\DataModel\Statement\StatementList;
8+
9+
/**
10+
* A collection of functions to manipulate StatementList objects.
11+
*
12+
* @license GPL-2.0+
13+
* @author Thiemo Mättig
14+
*/
15+
class StatementListChanger {
16+
17+
public function clear( StatementList $statementList ) {
18+
foreach ( $statementList->toArray() as $statement ) {
19+
$statementList->removeStatementsWithGuid( $statement->getGuid() );
20+
}
21+
}
22+
23+
/**
24+
* @param StatementList $statementList
25+
* @param Statement[] $statements
26+
*/
27+
private function replaceStatements( StatementList $statementList, array $statements ) {
28+
$this->clear( $statementList );
29+
30+
foreach ( $statements as $statement ) {
31+
$statementList->addStatement( $statement );
32+
}
33+
}
34+
35+
public function groupByProperty( StatementList $statementList ) {
36+
$byId = [];
37+
38+
foreach ( $statementList->toArray() as $statement ) {
39+
$id = $statement->getPropertyId()->getSerialization();
40+
$byId[$id][] = $statement;
41+
}
42+
43+
$this->clear( $statementList );
44+
45+
foreach ( $byId as $statements ) {
46+
foreach ( $statements as $statement ) {
47+
$statementList->addStatement( $statement );
48+
}
49+
}
50+
}
51+
52+
/**
53+
* @param StatementList $statementList
54+
* @param Statement $statement
55+
* @param int $index
56+
*/
57+
public function addToGroup( StatementList $statementList, Statement $statement, $index ) {
58+
if ( $statementList->isEmpty() ) {
59+
$statementList->addStatement( $statement );
60+
return;
61+
}
62+
63+
$byPropertyIdArray = new ByPropertyIdArray( $statementList->toArray() );
64+
$byPropertyIdArray->buildIndex();
65+
$byPropertyIdArray->addObjectAtIndex( $statement, $index );
66+
$this->replaceStatements( $statementList, $byPropertyIdArray->toFlatArray() );
67+
}
68+
69+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
namespace Wikibase\DataModel\Services\Tests\Statement;
4+
5+
use PHPUnit_Framework_TestCase;
6+
use Wikibase\DataModel\Entity\PropertyId;
7+
use Wikibase\DataModel\Services\Statement\StatementListChanger;
8+
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
9+
use Wikibase\DataModel\Statement\Statement;
10+
use Wikibase\DataModel\Statement\StatementList;
11+
12+
/**
13+
* @covers Wikibase\DataModel\Services\Statement\StatementListChanger
14+
*
15+
* @license GPL-2.0+
16+
* @author Thiemo Mättig
17+
*/
18+
class StatementListChangerTest extends PHPUnit_Framework_TestCase {
19+
20+
public function testConstructor() {
21+
$instance = new StatementListChanger();
22+
23+
$this->assertInstanceOf( StatementListChanger::class, $instance );
24+
}
25+
26+
public function testClear() {
27+
$statementList = $this->newStatementList( [ 'P1$A' ] );
28+
29+
$instance = new StatementListChanger();
30+
$instance->clear( $statementList );
31+
32+
$this->assertTrue( $statementList->isEmpty() );
33+
}
34+
35+
/**
36+
* @dataProvider groupByPropertyIdProvider
37+
*/
38+
public function testGroupByPropertyId( array $guids, array $expectedGuids ) {
39+
$statementList = $this->newStatementList( $guids );
40+
41+
$instance = new StatementListChanger();
42+
$instance->groupByProperty( $statementList );
43+
44+
$this->assertGuids( $expectedGuids, $statementList );
45+
}
46+
47+
public function groupByPropertyIdProvider() {
48+
return [
49+
[
50+
[],
51+
[]
52+
],
53+
[
54+
[ 'P1$A' ],
55+
[ 'P1$A' ]
56+
],
57+
[
58+
[ 'P1$A', 'P2$B', 'P1$C', 'P2$D' ],
59+
[ 'P1$A', 'P1$C', 'P2$B', 'P2$D' ]
60+
],
61+
[
62+
[ 'P1$A', 'P1$B', 'P2$C', 'P3$D', 'P1$E', 'P2$F' ],
63+
[ 'P1$A', 'P1$B', 'P1$E', 'P2$C', 'P2$F', 'P3$D' ]
64+
],
65+
];
66+
}
67+
68+
/**
69+
* @dataProvider addToGroupProvider
70+
*/
71+
public function testAddToGroup( array $guids, $newGuid, $index, array $expectedGuids ) {
72+
$statementList = $this->newStatementList( $guids );
73+
$statement = $this->newStatement( $newGuid );
74+
75+
$instance = new StatementListChanger();
76+
$instance->addToGroup( $statementList, $statement, $index );
77+
78+
$this->assertGuids( $expectedGuids, $statementList );
79+
}
80+
81+
public function addToGroupProvider() {
82+
return [
83+
'add to empty list' => [
84+
[],
85+
'P1$A',
86+
0,
87+
[ 'P1$A' ]
88+
],
89+
'negative index' => [
90+
[],
91+
'P1$A',
92+
-100,
93+
[ 'P1$A' ]
94+
],
95+
'extreme index' => [
96+
[],
97+
'P1$A',
98+
100,
99+
[ 'P1$A' ]
100+
],
101+
'append one statement' => [
102+
[ 'P1$A' ],
103+
'P1$B',
104+
1,
105+
[ 'P1$A', 'P1$B' ]
106+
],
107+
'prepend one statement' => [
108+
[ 'P1$A' ],
109+
'P1$B',
110+
0,
111+
[ 'P1$B', 'P1$A' ]
112+
],
113+
'insert one statement' => [
114+
[ 'P1$A', 'P2$B' ],
115+
'P1$C',
116+
1,
117+
[ 'P1$A', 'P1$C', 'P2$B' ]
118+
],
119+
'move group to the end' => [
120+
[ 'P1$A', 'P2$B' ],
121+
'P1$C',
122+
100,
123+
[ 'P2$B', 'P1$A', 'P1$C' ]
124+
],
125+
];
126+
}
127+
128+
/**
129+
* @param string[] $guids
130+
*
131+
* @return StatementList
132+
*/
133+
private function newStatementList( array $guids ) {
134+
$statementList = new StatementList();
135+
136+
foreach ( $guids as $guid ) {
137+
$statementList->addStatement( $this->newStatement( $guid ) );
138+
}
139+
140+
return $statementList;
141+
}
142+
143+
private function newStatement( $guid ) {
144+
list( $propertyId, ) = explode( '$', $guid, 2 );
145+
146+
return new Statement(
147+
new PropertyNoValueSnak( new PropertyId( $propertyId ) ),
148+
null,
149+
null,
150+
$guid
151+
);
152+
}
153+
154+
/**
155+
* @param string[] $expectedGuids
156+
* @param StatementList $statementList
157+
*/
158+
private function assertGuids( array $expectedGuids, StatementList $statementList ) {
159+
$guids = [];
160+
161+
foreach ( $statementList->toArray() as $statement ) {
162+
$guids[] = $statement->getGuid();
163+
}
164+
165+
$this->assertSame( $expectedGuids, $guids );
166+
}
167+
168+
}

0 commit comments

Comments
 (0)