Passed
Push — release500 ( 6f22d3...711bfb )
by no
02:56
created

testIndexOf_falseForMissingReferences()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
rs 9.6666
cc 1
eloc 6
nc 1
nop 0
1
<?php
2
3
namespace Wikibase\DataModel\Tests;
4
5
use Hashable;
6
use InvalidArgumentException;
7
use Wikibase\DataModel\Entity\PropertyId;
8
use Wikibase\DataModel\Reference;
9
use Wikibase\DataModel\ReferenceList;
10
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
11
use Wikibase\DataModel\Snak\SnakList;
12
13
/**
14
 * @covers Wikibase\DataModel\ReferenceList
15
 *
16
 * @group Wikibase
17
 * @group WikibaseDataModel
18
 * @group WikibaseReference
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Jeroen De Dauw < [email protected] >
22
 * @author Thiemo Mättig
23
 */
24
class ReferenceListTest extends \PHPUnit_Framework_TestCase {
25
26
	public function instanceProvider() {
27
		$instances = array();
28
29
		foreach ( $this->getConstructorArg() as $arg ) {
30
			$instances[] = array( new ReferenceList( $arg ) );
31
		}
32
33
		return $instances;
34
	}
35
36
	public function getElementInstances() {
37
		return array(
38
			new Reference(),
39
			new Reference( array( new PropertyNoValueSnak( 2 ) ) ),
40
			new Reference( array( new PropertyNoValueSnak( 3 ) ) ),
41
		);
42
	}
43
44
	public function getConstructorArg() {
45
		return array(
46
			array(),
47
			$this->getElementInstances(),
48
		);
49
	}
50
51
	public function testCanConstructWithReferenceListObject() {
52
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
53
		$original = new ReferenceList( array( $reference ) );
54
		$copy = new ReferenceList( $original );
55
56
		$this->assertSame( 1, $copy->count() );
57
		$this->assertNotNull( $copy->getReference( $reference->getHash() ) );
58
	}
59
60
	/**
61
	 * @dataProvider invalidConstructorArgumentsProvider
62
	 * @expectedException InvalidArgumentException
63
	 */
64
	public function testGivenInvalidConstructorArguments_constructorThrowsException( $input ) {
65
		new ReferenceList( $input );
66
	}
67
68
	public function invalidConstructorArgumentsProvider() {
69
		$id1 = new PropertyId( 'P1' );
70
71
		return array(
72
			array( null ),
73
			array( false ),
74
			array( 1 ),
75
			array( 0.1 ),
76
			array( 'string' ),
77
			array( $id1 ),
78
			array( new PropertyNoValueSnak( $id1 ) ),
79
			array( new Reference() ),
80
			array( new SnakList( array( new PropertyNoValueSnak( $id1 ) ) ) ),
81
			array( array( new PropertyNoValueSnak( $id1 ) ) ),
82
			array( array( new ReferenceList() ) ),
83
			array( array( new SnakList() ) ),
84
		);
85
	}
86
87
	/**
88
	 * @dataProvider instanceProvider
89
	 * @param ReferenceList $array
90
	 */
91
	public function testHasReferenceBeforeRemoveButNotAfter( ReferenceList $array ) {
92
		if ( $array->count() === 0 ) {
93
			$this->assertTrue( true );
94
			return;
95
		}
96
97
		/**
98
		 * @var Reference $hashable
99
		 */
100
		foreach ( iterator_to_array( $array ) as $hashable ) {
101
			$this->assertTrue( $array->hasReference( $hashable ) );
102
			$array->removeReference( $hashable );
103
			$this->assertFalse( $array->hasReference( $hashable ) );
104
		}
105
	}
106
107
	public function testGivenCloneOfReferenceInList_hasReferenceReturnsTrue() {
108
		$list = new ReferenceList();
109
110
		$reference = new Reference( array( new PropertyNoValueSnak( 42 ) ) );
111
		$sameReference = unserialize( serialize( $reference ) );
112
113
		$list->addReference( $reference );
114
115
		$this->assertTrue(
116
			$list->hasReference( $sameReference ),
117
			'hasReference should return true when a reference with the same value is present, even when its another instance'
118
		);
119
	}
120
121
	/**
122
	 * @dataProvider instanceProvider
123
	 * @param ReferenceList $array
124
	 */
125
	public function testRemoveReference( ReferenceList $array ) {
126
		$elementCount = count( $array );
127
128
		/**
129
		 * @var Reference $element
130
		 */
131
		foreach ( iterator_to_array( $array ) as $element ) {
132
			$this->assertTrue( $array->hasReference( $element ) );
133
134
			$array->removeReference( $element );
135
136
			$this->assertFalse( $array->hasReference( $element ) );
137
			$this->assertEquals( --$elementCount, count( $array ) );
138
		}
139
140
		$elements = $this->getElementInstances();
141
		$element = array_shift( $elements );
142
143
		$array->removeReference( $element );
0 ignored issues
show
Bug introduced by
It seems like $element defined by array_shift($elements) on line 141 can be null; however, Wikibase\DataModel\Refer...List::removeReference() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
144
		$array->removeReference( $element );
0 ignored issues
show
Bug introduced by
It seems like $element defined by array_shift($elements) on line 141 can be null; however, Wikibase\DataModel\Refer...List::removeReference() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
145
146
		$this->assertTrue( true );
147
	}
148
149
	public function testAddReferenceOnEmptyList() {
150
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
151
152
		$references = new ReferenceList();
153
		$references->addReference( $reference );
154
155
		$this->assertCount( 1, $references );
156
157
		$expectedList = new ReferenceList( array( $reference ) );
158
		$this->assertSameReferenceOrder( $expectedList, $references );
159
	}
160
161
	private function assertSameReferenceOrder( ReferenceList $expectedList, ReferenceList $references ) {
162
		$this->assertEquals(
163
			iterator_to_array( $expectedList ),
164
			iterator_to_array( $references )
165
		);
166
	}
167
168
	public function testAddReferenceOnNonEmptyList() {
169
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
170
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
171
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
172
173
		$references = new ReferenceList( array( $reference1, $reference2 ) );
174
		$references->addReference( $reference3 );
175
176
		$this->assertCount( 3, $references );
177
178
		$expectedList = new ReferenceList( array( $reference1, $reference2, $reference3 ) );
179
		$this->assertSameReferenceOrder( $expectedList, $references );
180
	}
181
182
	public function testAddReferenceAtIndexZero() {
183
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
184
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
185
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
186
187
		$references = new ReferenceList( array( $reference1, $reference2 ) );
188
		$references->addReference( $reference3, 0 );
189
190
		$expectedList = new ReferenceList( array( $reference3, $reference1, $reference2 ) );
191
		$this->assertSameReferenceOrder( $expectedList, $references );
192
	}
193
194
	public function testAddReferenceAtNegativeIndex() {
195
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
196
		$referenceList = new ReferenceList();
197
198
		$this->setExpectedException( 'InvalidArgumentException' );
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
199
		$referenceList->addReference( $reference, -1 );
200
	}
201
202
	public function testGivenEmptyReference_addReferenceDoesNotAdd() {
203
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
204
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
205
		$emptyReference = new Reference( array() );
206
207
		$references = new ReferenceList( array( $reference1, $reference2 ) );
208
		$references->addReference( $emptyReference );
209
210
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
211
		$this->assertSameReferenceOrder( $expectedList, $references );
212
	}
213
214
	public function testGivenEmptyReferenceAndIndex_addReferenceDoesNotAdd() {
215
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
216
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
217
		$emptyReference = new Reference( array() );
218
219
		$references = new ReferenceList( array( $reference1, $reference2 ) );
220
		$references->addReference( $emptyReference, 0 );
221
222
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
223
		$this->assertSameReferenceOrder( $expectedList, $references );
224
	}
225
226
	/**
227
	 * @dataProvider instanceProvider
228
	 * @param ReferenceList $array
229
	 */
230
	public function testIndexOf( ReferenceList $array ) {
231
		$this->assertFalse( $array->indexOf( new Reference() ) );
232
233
		$i = 0;
234
		foreach ( $array as $reference ) {
235
			$this->assertEquals( $i++, $array->indexOf( $reference ) );
236
		}
237
	}
238
239
	public function testIndexOf_falseForMissingReferences() {
240
		$referenceList = new ReferenceList();
241
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
242
243
		$referenceList->addNewReference( new PropertyNoValueSnak( 1 ) );
244
245
		$this->assertFalse( $referenceList->indexOf( new Reference() ) );
246
		$this->assertFalse( $referenceList->indexOf( $reference ) );
247
	}
248
249
	/**
250
	 * @dataProvider instanceProvider
251
	 * @param ReferenceList $array
252
	 */
253
	public function testEquals( ReferenceList $array ) {
254
		$this->assertTrue( $array->equals( $array ) );
255
		$this->assertFalse( $array->equals( 42 ) );
256
	}
257
258
	/**
259
	 * @dataProvider instanceProvider
260
	 * @param ReferenceList $array
261
	 */
262
	public function testGetHashReturnsString( ReferenceList $array ) {
263
		$this->assertInternalType( 'string', $array->getValueHash() );
264
	}
265
266
	/**
267
	 * @dataProvider instanceProvider
268
	 * @param ReferenceList $array
269
	 */
270
	public function testGetHashValueIsTheSameForClone( ReferenceList $array ) {
271
		$copy = unserialize( serialize( $array ) );
272
		$this->assertEquals( $array->getValueHash(), $copy->getValueHash() );
273
	}
274
275
	/**
276
	 * @dataProvider instanceProvider
277
	 * @param ReferenceList $references
278
	 */
279
	public function testHasReferenceHash( ReferenceList $references ) {
280
		$this->assertFalse( $references->hasReferenceHash( '~=[,,_,,]:3' ) );
281
282
		/**
283
		 * @var Hashable $reference
284
		 */
285
		foreach ( $references as $reference ) {
286
			$this->assertTrue( $references->hasReferenceHash( $reference->getHash() ) );
287
		}
288
	}
289
290
	/**
291
	 * @dataProvider instanceProvider
292
	 * @param ReferenceList $references
293
	 */
294
	public function testGetReference( ReferenceList $references ) {
295
		$this->assertNull( $references->getReference( '~=[,,_,,]:3' ) );
296
297
		/**
298
		 * @var Reference $reference
299
		 */
300
		foreach ( $references as $reference ) {
301
			$this->assertTrue( $reference->equals( $references->getReference( $reference->getHash() ) ) );
302
		}
303
	}
304
305
	/**
306
	 * @dataProvider instanceProvider
307
	 * @param ReferenceList $references
308
	 */
309
	public function testRemoveReferenceHash( ReferenceList $references ) {
310
		$references->removeReferenceHash( '~=[,,_,,]:3' );
311
312
		$hashes = array();
313
314
		/**
315
		 * @var Reference $reference
316
		 */
317
		foreach ( $references as $reference ) {
318
			$hashes[] = $reference->getHash();
319
		}
320
321
		foreach ( $hashes as $hash ) {
322
			$references->removeReferenceHash( $hash );
323
		}
324
325
		$this->assertEquals( 0, count( $references ) );
326
	}
327
328
	public function testGivenOneSnak_addNewReferenceAddsSnak() {
329
		$references = new ReferenceList();
330
		$snak = new PropertyNoValueSnak( 1 );
331
332
		$references->addNewReference( $snak );
333
		$this->assertTrue( $references->hasReference( new Reference( array( $snak ) ) ) );
334
	}
335
336
	public function testGivenMultipleSnaks_addNewReferenceAddsThem() {
337
		$references = new ReferenceList();
338
		$snak1 = new PropertyNoValueSnak( 1 );
339
		$snak2 = new PropertyNoValueSnak( 3 );
340
		$snak3 = new PropertyNoValueSnak( 2 );
341
342
		$references->addNewReference( $snak1, $snak2, $snak3 );
343
344
		$expectedSnaks = array( $snak1, $snak2, $snak3 );
345
		$this->assertTrue( $references->hasReference( new Reference( $expectedSnaks ) ) );
346
	}
347
348
	public function testGivenAnArrayOfSnaks_addNewReferenceAddsThem() {
349
		$references = new ReferenceList();
350
		$snaks = array(
351
			new PropertyNoValueSnak( 1 ),
352
			new PropertyNoValueSnak( 3 ),
353
			new PropertyNoValueSnak( 2 )
354
		);
355
356
		$references->addNewReference( $snaks );
357
		$this->assertTrue( $references->hasReference( new Reference( $snaks ) ) );
358
	}
359
360
	public function testGivenNoneSnak_addNewReferenceThrowsException() {
361
		$references = new ReferenceList();
362
363
		$this->setExpectedException( 'InvalidArgumentException' );
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit_Framework_TestCase::setExpectedException() has been deprecated with message: Method deprecated since Release 5.2.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
364
		$references->addNewReference( new PropertyNoValueSnak( 1 ), null );
365
	}
366
367
	public function testSerializeRoundtrip() {
368
		$references = new ReferenceList();
369
370
		$references->addReference( new Reference() );
371
372
		$references->addReference( new Reference( array(
373
			new PropertyNoValueSnak( 2 ),
374
			new PropertyNoValueSnak( 3 ),
375
		) ) );
376
377
		$serialized = serialize( $references );
378
		$this->assertTrue( $references->equals( unserialize( $serialized ) ) );
379
	}
380
381
	public function testGivenEmptyList_isEmpty() {
382
		$references = new ReferenceList();
383
		$this->assertTrue( $references->isEmpty() );
384
	}
385
386
	public function testGivenNonEmptyList_isNotEmpty() {
387
		$references = new ReferenceList();
388
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
389
390
		$this->assertFalse( $references->isEmpty() );
391
	}
392
393
}
394