Passed
Push — rankClass ( 1b9cf4...7f76c7 )
by no
04:15 queued 16s
created

testGetFlatArrayIndexOfObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Wikibase\DataModel\Tests;
4
5
use ArrayObject;
6
use DataValues\StringValue;
7
use InvalidArgumentException;
8
use OutOfBoundsException;
9
use PHPUnit_Framework_TestCase;
10
use ReflectionClass;
11
use ReflectionMethod;
12
use RuntimeException;
13
use stdClass;
14
use Wikibase\DataModel\ByPropertyIdArray;
15
use Wikibase\DataModel\Entity\PropertyId;
16
use Wikibase\DataModel\PropertyIdProvider;
17
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
18
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
19
use Wikibase\DataModel\Snak\PropertyValueSnak;
20
use Wikibase\DataModel\Snak\Snak;
21
use Wikibase\DataModel\Statement\Statement;
22
23
/**
24
 * @covers \Wikibase\DataModel\ByPropertyIdArray
25
 *
26
 * @group Wikibase
27
 * @group WikibaseDataModel
28
 *
29
 * @license GPL-2.0+
30
 * @author Jeroen De Dauw < [email protected] >
31
 * @author H. Snater < [email protected] >
32
 */
33
class ByPropertyIdArrayTest extends PHPUnit_Framework_TestCase {
34
35
	public function testGivenNull_constructorAssumesEmptyArray() {
36
		$indexedArray = new ByPropertyIdArray( null );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
37
38
		$this->assertSame( 0, $indexedArray->count() );
39
	}
40
41
	public function testGivenNonTraversableObject_constructorDoesNotCastObjectToArray() {
42
		$object = new stdClass();
43
		$object->property = true;
44
45
		$this->expectException( InvalidArgumentException::class );
46
		new ByPropertyIdArray( $object );
0 ignored issues
show
Documentation introduced by
$object is of type object<stdClass>, but the function expects a array<integer,object<Wik...bject<Traversable>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
47
	}
48
49
	public function testArrayObjectNotConstructedFromObject() {
50
		$statement1 = new Statement( new PropertyNoValueSnak( 1 ) );
51
		$statement1->setGuid( '1' );
52
		$statement2 = new Statement( new PropertyNoValueSnak( 2 ) );
53
		$statement2->setGuid( '2' );
54
55
		$object = new ArrayObject();
56
		$object->append( $statement1 );
57
58
		$byPropertyIdArray = new ByPropertyIdArray( $object );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
59
		// According to the documentation append() "cannot be called when the ArrayObject was
60
		// constructed from an object." This test makes sure it was not constructed from an object.
61
		$byPropertyIdArray->append( $statement2 );
62
63
		$this->assertCount( 2, $byPropertyIdArray );
64
	}
65
66
	/**
67
	 * Returns an accessible ReflectionMethod of ByPropertyIdArray.
68
	 *
69
	 * @param string $methodName
70
	 * @return ReflectionMethod
71
	 */
72
	protected static function getMethod( $methodName ) {
73
		$class = new ReflectionClass( ByPropertyIdArray::class );
74
		$method = $class->getMethod( $methodName );
75
		$method->setAccessible( true );
76
		return $method;
77
	}
78
79
	public function listProvider() {
80
		$lists = [];
81
82
		$snaks = [
83
			new PropertyNoValueSnak( new PropertyId( 'P42' ) ),
84
			new PropertySomeValueSnak( new PropertyId( 'P42' ) ),
85
			new PropertySomeValueSnak( new PropertyId( 'P10' ) ),
86
			new PropertyValueSnak( new PropertyId( 'P10' ), new StringValue( 'ohi' ) ),
87
			new PropertySomeValueSnak( new PropertyId( 'P1' ) ),
88
		];
89
90
		$lists[] = $snaks;
91
92
		$lists[] = array_map(
93
			function( Snak $snak ) {
94
				return new Statement( $snak );
95
			},
96
			$snaks
97
		);
98
99
		$argLists = [];
100
101
		foreach ( $lists as $list ) {
102
			$argLists[] = [ $list ];
103
		}
104
105
		return $argLists;
106
	}
107
108
	/**
109
	 * @return Statement[]
110
	 */
111
	protected function statementsProvider() {
112
		$snaks = [
113
			new PropertyNoValueSnak( new PropertyId( 'P1' ) ),
114
			new PropertySomeValueSnak( new PropertyId( 'P1' ) ),
115
			new PropertyValueSnak( new PropertyId( 'P2' ), new StringValue( 'a' ) ),
116
			new PropertyValueSnak( new PropertyId( 'P2' ), new StringValue( 'b' ) ),
117
			new PropertyValueSnak( new PropertyId( 'P2' ), new StringValue( 'c' ) ),
118
			new PropertySomeValueSnak( new PropertyId( 'P3' ) ),
119
		];
120
121
		return array_map(
122
			function( Snak $snak ) {
123
				return new Statement( $snak );
124
			},
125
			$snaks
126
		);
127
	}
128
129
	/**
130
	 * @dataProvider listProvider
131
	 * @param PropertyIdProvider[] $objects
132
	 */
133
	public function testGetIds( array $objects ) {
134
		$indexedArray = new ByPropertyIdArray( $objects );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
135
136
		$expected = [];
137
138
		foreach ( $objects as $object ) {
139
			$expected[] = $object->getPropertyId();
140
		}
141
142
		$expected = array_unique( $expected );
143
144
		$indexedArray->buildIndex();
145
146
		$this->assertEquals(
147
			array_values( $expected ),
148
			array_values( $indexedArray->getPropertyIds() )
149
		);
150
	}
151
152
	/**
153
	 * @dataProvider listProvider
154
	 * @param PropertyIdProvider[] $objects
155
	 */
156
	public function testGetById( array $objects ) {
157
		$indexedArray = new ByPropertyIdArray( $objects );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
158
159
		$ids = [];
160
161
		foreach ( $objects as $object ) {
162
			$ids[] = $object->getPropertyId();
163
		}
164
165
		$ids = array_unique( $ids );
166
167
		$indexedArray->buildIndex();
168
169
		$allObtainedObjects = [];
170
171
		foreach ( $ids as $id ) {
172
			foreach ( $indexedArray->getByPropertyId( $id ) as $obtainedObject ) {
173
				$allObtainedObjects[] = $obtainedObject;
174
				$this->assertEquals( $id, $obtainedObject->getPropertyId() );
175
			}
176
		}
177
178
		$this->assertEquals(
179
			array_values( $objects ),
180
			array_values( $allObtainedObjects )
181
		);
182
	}
183
184
	/**
185
	 * @dataProvider listProvider
186
	 * @param PropertyIdProvider[] $objects
187
	 */
188
	public function testRemoveObject( array $objects ) {
189
		$lastIndex = count( $objects ) - 1;
190
		$indexedArray = new ByPropertyIdArray( $objects );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
191
		$indexedArray->buildIndex();
192
193
		$removeObject = self::getMethod( 'removeObject' );
194
195
		$removeObject->invokeArgs( $indexedArray, [ $objects[0] ] );
196
		$removeObject->invokeArgs( $indexedArray, [ $objects[$lastIndex] ] );
197
198
		$this->assertFalse(
199
			in_array( $objects[0], $indexedArray->getByPropertyId( $objects[0]->getPropertyId() ) )
200
		);
201
202
		$this->assertFalse( in_array(
203
			$objects[$lastIndex],
204
			$indexedArray->getByPropertyId( $objects[1]->getPropertyId() )
205
		) );
206
207
		$this->assertFalse( in_array( $objects[0], $indexedArray->toFlatArray() ) );
208
		$this->assertFalse( in_array( $objects[$lastIndex], $indexedArray->toFlatArray() ) );
209
	}
210
211
	public function testGetByNotSetIdThrowsException() {
212
		$indexedArray = new ByPropertyIdArray();
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
213
		$indexedArray->buildIndex();
214
215
		$this->expectException( OutOfBoundsException::class );
216
217
		$indexedArray->getByPropertyId( new PropertyId( 'P9000' ) );
218
	}
219
220
	public function testNotBuildExceptionIsThrownForByPropertyId() {
221
		$indexedArray = new ByPropertyIdArray();
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
222
223
		$this->expectException( RuntimeException::class );
224
		$indexedArray->getByPropertyId( new PropertyId( 'P9000' ) );
225
	}
226
227
	public function testNotBuildExceptionIsThrownForGetPropertyIds() {
228
		$indexedArray = new ByPropertyIdArray();
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
229
230
		$this->expectException( RuntimeException::class );
231
		$indexedArray->getPropertyIds();
232
	}
233
234
	/**
235
	 * @dataProvider listProvider
236
	 */
237
	public function testGetFlatArrayIndexOfObject( array $objects ) {
238
		$indexedArray = new ByPropertyIdArray( $objects );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
239
		$indexedArray->buildIndex();
240
241
		$indicesSource = [];
242
		$indicesDestination = [];
243
244
		$i = 0;
245
		foreach ( $objects as $object ) {
246
			$indicesSource[$i++] = $object;
247
			$indicesDestination[$indexedArray->getFlatArrayIndexOfObject( $object )] = $object;
248
		}
249
250
		$this->assertEquals( $indicesSource, $indicesDestination );
251
	}
252
253
	/**
254
	 * @dataProvider listProvider
255
	 */
256
	public function testToFlatArray( array $objects ) {
257
		$indexedArray = new ByPropertyIdArray( $objects );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
258
		$indexedArray->buildIndex();
259
260
		$this->assertEquals( $objects, $indexedArray->toFlatArray() );
261
	}
262
263
	public function moveProvider() {
264
		$c = $this->statementsProvider();
265
		$argLists = [];
266
267
		$argLists[] = [ $c, $c[0], 0, $c ];
268
		$argLists[] = [ $c, $c[0], 1, [ $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ] ];
269
		$argLists[] = [ $c, $c[0], 2, [ $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ] ];
270
		$argLists[] = [ $c, $c[0], 3, [ $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ] ];
271
		$argLists[] = [ $c, $c[0], 4, [ $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ] ];
272
		$argLists[] = [ $c, $c[0], 5, [ $c[2], $c[3], $c[4], $c[1], $c[0], $c[5] ] ];
273
		$argLists[] = [ $c, $c[0], 6, [ $c[2], $c[3], $c[4], $c[5], $c[1], $c[0] ] ];
274
275
		$argLists[] = [ $c, $c[1], 0, [ $c[1], $c[0], $c[2], $c[3], $c[4], $c[5] ] ];
276
		$argLists[] = [ $c, $c[1], 1, $c ];
277
		$argLists[] = [ $c, $c[1], 2, $c ];
278
		$argLists[] = [ $c, $c[1], 3, [ $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ] ];
279
		$argLists[] = [ $c, $c[1], 4, [ $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ] ];
280
		$argLists[] = [ $c, $c[1], 5, [ $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ] ];
281
		$argLists[] = [ $c, $c[1], 6, [ $c[2], $c[3], $c[4], $c[5], $c[0], $c[1] ] ];
282
283
		$argLists[] = [ $c, $c[2], 0, [ $c[2], $c[3], $c[4], $c[0], $c[1], $c[5] ] ];
284
		$argLists[] = [ $c, $c[2], 1, $c ];
285
		$argLists[] = [ $c, $c[2], 2, $c ];
286
		$argLists[] = [ $c, $c[2], 3, [ $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ] ];
287
		$argLists[] = [ $c, $c[2], 4, [ $c[0], $c[1], $c[3], $c[4], $c[2], $c[5] ] ];
288
		$argLists[] = [ $c, $c[2], 5, [ $c[0], $c[1], $c[3], $c[4], $c[2], $c[5] ] ];
289
		$argLists[] = [ $c, $c[2], 6, [ $c[0], $c[1], $c[5], $c[3], $c[4], $c[2] ] ];
290
291
		$argLists[] = [ $c, $c[3], 0, [ $c[3], $c[2], $c[4], $c[0], $c[1], $c[5] ] ];
292
		$argLists[] = [ $c, $c[3], 1, [ $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ] ];
293
		$argLists[] = [ $c, $c[3], 2, [ $c[0], $c[1], $c[3], $c[2], $c[4], $c[5] ] ];
294
		$argLists[] = [ $c, $c[3], 3, $c ];
295
		$argLists[] = [ $c, $c[3], 4, [ $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ] ];
296
		$argLists[] = [ $c, $c[3], 5, [ $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ] ];
297
		$argLists[] = [ $c, $c[3], 6, [ $c[0], $c[1], $c[5], $c[2], $c[4], $c[3] ] ];
298
299
		$argLists[] = [ $c, $c[4], 0, [ $c[4], $c[2], $c[3], $c[0], $c[1], $c[5] ] ];
300
		$argLists[] = [ $c, $c[4], 1, [ $c[0], $c[1], $c[4], $c[2], $c[3], $c[5] ] ];
301
		$argLists[] = [ $c, $c[4], 2, [ $c[0], $c[1], $c[4], $c[2], $c[3], $c[5] ] ];
302
		$argLists[] = [ $c, $c[4], 3, [ $c[0], $c[1], $c[2], $c[4], $c[3], $c[5] ] ];
303
		$argLists[] = [ $c, $c[4], 4, $c ];
304
		$argLists[] = [ $c, $c[4], 5, $c ];
305
		$argLists[] = [ $c, $c[4], 6, [ $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ] ];
306
307
		$argLists[] = [ $c, $c[5], 0, [ $c[5], $c[0], $c[1], $c[2], $c[3], $c[4] ] ];
308
		$argLists[] = [ $c, $c[5], 1, [ $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ] ];
309
		$argLists[] = [ $c, $c[5], 2, [ $c[0], $c[1], $c[5], $c[2], $c[3], $c[4] ] ];
310
		$argLists[] = [ $c, $c[5], 3, $c ];
311
		$argLists[] = [ $c, $c[5], 4, $c ];
312
		$argLists[] = [ $c, $c[5], 5, $c ];
313
		$argLists[] = [ $c, $c[5], 6, $c ];
314
315
		return $argLists;
316
	}
317
318
	/**
319
	 * @dataProvider moveProvider
320
	 */
321
	public function testMoveObjectToIndex(
322
		array $objectsSource,
323
		PropertyIdProvider $object,
324
		$toIndex,
325
		array $objectsDestination
326
	) {
327
		$indexedArray = new ByPropertyIdArray( $objectsSource );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
328
		$indexedArray->buildIndex();
329
330
		$indexedArray->moveObjectToIndex( $object, $toIndex );
331
332
		// Not using $indexedArray->toFlatArray() here to test whether native array has been
333
		// exchanged:
334
		$reindexedArray = [];
335
		foreach ( $indexedArray as $o ) {
336
			$reindexedArray[] = $o;
337
		}
338
339
		$this->assertEquals( $objectsDestination, $reindexedArray );
340
	}
341
342
	public function testMoveThrowingOutOfBoundsExceptionIfObjectNotPresent() {
343
		$statements = $this->statementsProvider();
344
		$indexedArray = new ByPropertyIdArray( $statements );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
345
		$indexedArray->buildIndex();
346
347
		$this->expectException( OutOfBoundsException::class );
348
349
		$indexedArray->moveObjectToIndex( new Statement( new PropertyNoValueSnak( new PropertyId( 'P9999' ) ) ), 0 );
350
	}
351
352
	public function testMoveThrowingOutOfBoundsExceptionOnInvalidIndex() {
353
		$statements = $this->statementsProvider();
354
		$indexedArray = new ByPropertyIdArray( $statements );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
355
		$indexedArray->buildIndex();
356
357
		$this->expectException( OutOfBoundsException::class );
358
359
		$indexedArray->moveObjectToIndex( $statements[0], 9999 );
360
	}
361
362
	public function addProvider() {
363
		$c = $this->statementsProvider();
364
365
		$argLists = [];
366
367
		$argLists[] = [ [], $c[0], null, [ $c[0] ] ];
368
		$argLists[] = [ [], $c[0], 1, [ $c[0] ] ];
369
		$argLists[] = [ [ $c[0] ], $c[2], 0, [ $c[2], $c[0] ] ];
370
		$argLists[] = [ [ $c[2], $c[1] ], $c[0], 0, [ $c[0], $c[1], $c[2] ] ];
371
		$argLists[] = [
372
			[ $c[0], $c[1], $c[3] ],
373
			$c[5],
374
			1,
375
			[ $c[0], $c[1], $c[5], $c[3] ]
376
		];
377
		$argLists[] = [
378
			[ $c[0], $c[1], $c[5], $c[3] ],
379
			$c[2],
380
			2,
381
			[ $c[0], $c[1], $c[2], $c[3], $c[5] ]
382
		];
383
		$argLists[] = [
384
			[ $c[0], $c[1], $c[2], $c[3], $c[5] ],
385
			$c[4],
386
			null,
387
			[ $c[0], $c[1], $c[2], $c[3], $c[4], $c[5] ]
388
		];
389
390
		return $argLists;
391
	}
392
393
	/**
394
	 * @dataProvider addProvider
395
	 */
396
	public function testAddObjectAtIndex(
397
		array $objectsSource,
398
		PropertyIdProvider $object,
399
		$index,
400
		array $objectsDestination
401
	) {
402
		$indexedArray = new ByPropertyIdArray( $objectsSource );
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\ByPropertyIdArray has been deprecated with message: since 5.0, use a DataModel Service instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
403
		$indexedArray->buildIndex();
404
405
		$indexedArray->addObjectAtIndex( $object, $index );
406
407
		$this->assertEquals( $objectsDestination, $indexedArray->toFlatArray() );
408
	}
409
410
}
411