Completed
Pull Request — master (#641)
by no
04:23
created

testGivenAnArrayOfSnaks_addNewReferenceAddsThem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 11
rs 9.4285
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
namespace Wikibase\DataModel\Tests;
4
5
use Hashable;
6
use InvalidArgumentException;
7
use PHPUnit_Framework_TestCase;
8
use Wikibase\DataModel\Entity\PropertyId;
9
use Wikibase\DataModel\Reference;
10
use Wikibase\DataModel\ReferenceList;
11
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
12
use Wikibase\DataModel\Snak\SnakList;
13
14
/**
15
 * @covers Wikibase\DataModel\ReferenceList
16
 *
17
 * @group Wikibase
18
 * @group WikibaseDataModel
19
 * @group WikibaseReference
20
 *
21
 * @licence GNU GPL v2+
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author Thiemo Mättig
24
 */
25
class ReferenceListTest extends PHPUnit_Framework_TestCase {
26
27
	public function instanceProvider() {
28
		return array(
29
			array( new ReferenceList( array() ) ),
30
			array( new ReferenceList( array(
31
				new Reference(),
32
				new Reference( array( new PropertyNoValueSnak( 2 ) ) ),
33
				new Reference( array( new PropertyNoValueSnak( 3 ) ) ),
34
			) ) ),
35
		);
36
	}
37
38
	public function testCanConstructWithReferenceListObject() {
39
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
40
		$original = new ReferenceList( array( $reference ) );
41
		$copy = new ReferenceList( $original );
42
43
		$this->assertSame( 1, $copy->count() );
44
		$this->assertNotNull( $copy->getReference( $reference->getHash() ) );
45
	}
46
47
	/**
48
	 * @dataProvider invalidConstructorArgumentsProvider
49
	 * @expectedException InvalidArgumentException
50
	 */
51
	public function testGivenInvalidConstructorArguments_constructorThrowsException( $input ) {
52
		new ReferenceList( $input );
53
	}
54
55
	public function invalidConstructorArgumentsProvider() {
56
		$id1 = new PropertyId( 'P1' );
57
58
		return array(
59
			array( null ),
60
			array( false ),
61
			array( 1 ),
62
			array( 0.1 ),
63
			array( 'string' ),
64
			array( $id1 ),
65
			array( new PropertyNoValueSnak( $id1 ) ),
66
			array( new Reference() ),
67
			array( new SnakList( array( new PropertyNoValueSnak( $id1 ) ) ) ),
68
			array( array( new PropertyNoValueSnak( $id1 ) ) ),
69
			array( array( new ReferenceList() ) ),
70
			array( array( new SnakList() ) ),
71
		);
72
	}
73
74
	public function testGetIterator_isTraversable() {
75
		$references = new ReferenceList();
76
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
77
		$iterator = $references->getIterator();
78
79
		$this->assertInstanceOf( 'Traversable', $iterator );
80
		$this->assertCount( 1, $iterator );
81
		foreach ( $references as $reference ) {
82
			$this->assertInstanceOf( 'Wikibase\DataModel\Reference', $reference );
83
		}
84
	}
85
86
	/**
87
	 * @dataProvider instanceProvider
88
	 */
89
	public function testHasReferenceBeforeRemoveButNotAfter( ReferenceList $array ) {
90
		if ( $array->count() === 0 ) {
91
			$this->assertTrue( true );
92
			return;
93
		}
94
95
		/**
96
		 * @var Reference $hashable
97
		 */
98
		foreach ( iterator_to_array( $array ) as $hashable ) {
99
			$this->assertTrue( $array->hasReference( $hashable ) );
100
			$array->removeReference( $hashable );
101
			$this->assertFalse( $array->hasReference( $hashable ) );
102
		}
103
	}
104
105
	public function testGivenCloneOfReferenceInList_hasReferenceReturnsTrue() {
106
		$list = new ReferenceList();
107
108
		$reference = new Reference( array( new PropertyNoValueSnak( 42 ) ) );
109
		$sameReference = unserialize( serialize( $reference ) );
110
111
		$list->addReference( $reference );
112
113
		$this->assertTrue(
114
			$list->hasReference( $sameReference ),
115
			'hasReference should return true when a reference with the same value is present, even when its another instance'
116
		);
117
	}
118
119
	/**
120
	 * @dataProvider instanceProvider
121
	 */
122
	public function testRemoveReference( ReferenceList $array ) {
123
		$elementCount = count( $array );
124
125
		/**
126
		 * @var Reference $element
127
		 */
128
		foreach ( iterator_to_array( $array ) as $element ) {
129
			$this->assertTrue( $array->hasReference( $element ) );
130
131
			$array->removeReference( $element );
132
133
			$this->assertFalse( $array->hasReference( $element ) );
134
			$this->assertEquals( --$elementCount, count( $array ) );
135
		}
136
	}
137
138
	public function testRemoveReferenceRemovesIdenticalObjects() {
139
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
140
		$references = new ReferenceList( array( $reference, $reference ) );
141
142
		$references->removeReference( $reference );
143
144
		$this->assertTrue( $references->isEmpty() );
145
	}
146
147
	public function testRemoveReferenceDoesNotRemoveCopies() {
148
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
149
		$references = new ReferenceList( array( $reference, clone $reference ) );
150
151
		$references->removeReference( $reference );
152
153
		$this->assertFalse( $references->isEmpty() );
154
		$this->assertTrue( $references->hasReference( $reference ) );
155
		$this->assertNotSame( $reference, $references->getReference( $reference->getHash() ) );
156
	}
157
158
	public function testAddReferenceOnEmptyList() {
159
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
160
161
		$references = new ReferenceList();
162
		$references->addReference( $reference );
163
164
		$this->assertCount( 1, $references );
165
166
		$expectedList = new ReferenceList( array( $reference ) );
167
		$this->assertSameReferenceOrder( $expectedList, $references );
168
	}
169
170
	private function assertSameReferenceOrder( ReferenceList $expectedList, ReferenceList $references ) {
171
		$this->assertEquals(
172
			iterator_to_array( $expectedList ),
173
			iterator_to_array( $references )
174
		);
175
	}
176
177
	public function testAddReferenceOnNonEmptyList() {
178
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
179
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
180
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
181
182
		$references = new ReferenceList( array( $reference1, $reference2 ) );
183
		$references->addReference( $reference3 );
184
185
		$this->assertCount( 3, $references );
186
187
		$expectedList = new ReferenceList( array( $reference1, $reference2, $reference3 ) );
188
		$this->assertSameReferenceOrder( $expectedList, $references );
189
	}
190
191
	public function testAddReferenceAtIndexMovesIdenticalObjects() {
192
		$list = new ReferenceList();
193
		$list->addNewReference( new PropertyNoValueSnak( 1 ) );
194
		$reference = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
195
		$list->addReference( $reference );
196
		$this->assertSame( 1, $list->indexOf( $reference ), 'pre condition' );
197
198
		$list->addReference( $reference, 0 );
199
200
		$this->assertCount( 2, $list, 'not added' );
201
		$this->assertSame( 0, $list->indexOf( $reference ), 'can move up' );
202
203
		$list->addReference( $reference, 2 );
204
205
		$this->assertCount( 2, $list, 'not added' );
206
		$this->assertSame( 0, $list->indexOf( $reference ), 'can not move down' );
207
	}
208
209
	public function testAddReferenceAtIndexZero() {
210
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
211
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
212
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
213
214
		$references = new ReferenceList( array( $reference1, $reference2 ) );
215
		$references->addReference( $reference3, 0 );
216
217
		$expectedList = new ReferenceList( array( $reference3, $reference1, $reference2 ) );
218
		$this->assertSameReferenceOrder( $expectedList, $references );
219
	}
220
221
	public function testAddReferenceAtNegativeIndex() {
222
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
223
		$referenceList = new ReferenceList();
224
225
		$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...
226
		$referenceList->addReference( $reference, -1 );
227
	}
228
229
	public function testGivenEmptyReference_addReferenceDoesNotAdd() {
230
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
231
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
232
		$emptyReference = new Reference( array() );
233
234
		$references = new ReferenceList( array( $reference1, $reference2 ) );
235
		$references->addReference( $emptyReference );
236
237
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
238
		$this->assertSameReferenceOrder( $expectedList, $references );
239
	}
240
241
	public function testGivenEmptyReferenceAndIndex_addReferenceDoesNotAdd() {
242
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
243
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
244
		$emptyReference = new Reference( array() );
245
246
		$references = new ReferenceList( array( $reference1, $reference2 ) );
247
		$references->addReference( $emptyReference, 0 );
248
249
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
250
		$this->assertSameReferenceOrder( $expectedList, $references );
251
	}
252
253
	/**
254
	 * @dataProvider instanceProvider
255
	 */
256
	public function testIndexOf( ReferenceList $array ) {
257
		$this->assertFalse( $array->indexOf( new Reference() ) );
258
259
		$i = 0;
260
		foreach ( $array as $reference ) {
261
			$this->assertEquals( $i++, $array->indexOf( $reference ) );
262
		}
263
	}
264
265
	public function testIndexOf_checksForIdentity() {
266
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
267
		$reference2 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
268
		$referenceList = new ReferenceList( array( $reference1 ) );
269
270
		$this->assertNotSame( $reference1, $reference2, 'post condition' );
271
		$this->assertTrue( $reference1->equals( $reference2 ), 'post condition' );
272
		$this->assertSame( 0, $referenceList->indexOf( $reference1 ), 'identity' );
273
		$this->assertFalse( $referenceList->indexOf( $reference2 ), 'not equality' );
274
	}
275
276
	/**
277
	 * @dataProvider instanceProvider
278
	 */
279
	public function testEquals( ReferenceList $array ) {
280
		$this->assertTrue( $array->equals( $array ) );
281
		$this->assertFalse( $array->equals( 42 ) );
282
	}
283
284
	/**
285
	 * @dataProvider instanceProvider
286
	 */
287
	public function testGetValueHashReturnsString( ReferenceList $array ) {
288
		$this->assertInternalType( 'string', $array->getValueHash() );
289
	}
290
291
	/**
292
	 * @dataProvider instanceProvider
293
	 */
294
	public function testGetValueHashIsTheSameForClone( ReferenceList $array ) {
295
		$copy = unserialize( serialize( $array ) );
296
		$this->assertEquals( $array->getValueHash(), $copy->getValueHash() );
297
	}
298
299
	/**
300
	 * @dataProvider instanceProvider
301
	 */
302
	public function testHasReferenceHash( ReferenceList $references ) {
303
		$this->assertFalse( $references->hasReferenceHash( '~=[,,_,,]:3' ) );
304
305
		/**
306
		 * @var Hashable $reference
307
		 */
308
		foreach ( $references as $reference ) {
309
			$this->assertTrue( $references->hasReferenceHash( $reference->getHash() ) );
310
		}
311
	}
312
313
	/**
314
	 * @dataProvider instanceProvider
315
	 */
316
	public function testGetReference( ReferenceList $references ) {
317
		$this->assertNull( $references->getReference( '~=[,,_,,]:3' ) );
318
319
		/**
320
		 * @var Reference $reference
321
		 */
322
		foreach ( $references as $reference ) {
323
			$this->assertTrue( $reference->equals( $references->getReference( $reference->getHash() ) ) );
324
		}
325
	}
326
327
	/**
328
	 * @dataProvider instanceProvider
329
	 */
330
	public function testRemoveReferenceHash( ReferenceList $references ) {
331
		$references->removeReferenceHash( '~=[,,_,,]:3' );
332
333
		$hashes = array();
334
335
		/**
336
		 * @var Reference $reference
337
		 */
338
		foreach ( $references as $reference ) {
339
			$hashes[] = $reference->getHash();
340
		}
341
342
		foreach ( $hashes as $hash ) {
343
			$references->removeReferenceHash( $hash );
344
		}
345
346
		$this->assertEquals( 0, count( $references ) );
347
	}
348
349
	public function testRemoveReferenceHashRemovesIdenticalObjects() {
350
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
351
		$references = new ReferenceList( array( $reference, $reference ) );
352
353
		$references->removeReferenceHash( $reference->getHash() );
354
355
		$this->assertTrue( $references->isEmpty() );
356
	}
357
358
	public function testRemoveReferenceHashDoesNotRemoveCopies() {
359
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
360
		$references = new ReferenceList( array( $reference, clone $reference ) );
361
362
		$references->removeReferenceHash( $reference->getHash() );
363
364
		$this->assertFalse( $references->isEmpty() );
365
		$this->assertTrue( $references->hasReference( $reference ) );
366
		$this->assertNotSame( $reference, $references->getReference( $reference->getHash() ) );
367
	}
368
369
	public function testRemoveReferenceHashUpdatesIndexes() {
370
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
371
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
372
		$references = new ReferenceList( array( $reference1, $reference2 ) );
373
374
		$references->removeReferenceHash( $reference1->getHash() );
375
376
		$this->assertSame( 0, $references->indexOf( $reference2 ) );
377
	}
378
379
	public function testGivenOneSnak_addNewReferenceAddsSnak() {
380
		$references = new ReferenceList();
381
		$snak = new PropertyNoValueSnak( 1 );
382
383
		$references->addNewReference( $snak );
384
		$this->assertTrue( $references->hasReference( new Reference( array( $snak ) ) ) );
385
	}
386
387
	public function testGivenMultipleSnaks_addNewReferenceAddsThem() {
388
		$references = new ReferenceList();
389
		$snak1 = new PropertyNoValueSnak( 1 );
390
		$snak2 = new PropertyNoValueSnak( 3 );
391
		$snak3 = new PropertyNoValueSnak( 2 );
392
393
		$references->addNewReference( $snak1, $snak2, $snak3 );
394
395
		$expectedSnaks = array( $snak1, $snak2, $snak3 );
396
		$this->assertTrue( $references->hasReference( new Reference( $expectedSnaks ) ) );
397
	}
398
399
	public function testGivenAnArrayOfSnaks_addNewReferenceAddsThem() {
400
		$references = new ReferenceList();
401
		$snaks = array(
402
			new PropertyNoValueSnak( 1 ),
403
			new PropertyNoValueSnak( 3 ),
404
			new PropertyNoValueSnak( 2 )
405
		);
406
407
		$references->addNewReference( $snaks );
408
		$this->assertTrue( $references->hasReference( new Reference( $snaks ) ) );
409
	}
410
411
	public function testGivenNoneSnak_addNewReferenceThrowsException() {
412
		$references = new ReferenceList();
413
414
		$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...
415
		$references->addNewReference( new PropertyNoValueSnak( 1 ), null );
416
	}
417
418
	public function testSerializationStability() {
419
		$references = new ReferenceList();
420
		$this->assertSame( 'a:0:{}', $references->serialize() );
421
	}
422
423
	public function testSerializeRoundtrip() {
424
		$references = new ReferenceList();
425
426
		$references->addReference( new Reference() );
427
428
		$references->addReference( new Reference( array(
429
			new PropertyNoValueSnak( 2 ),
430
			new PropertyNoValueSnak( 3 ),
431
		) ) );
432
433
		$serialized = serialize( $references );
434
		$this->assertTrue( $references->equals( unserialize( $serialized ) ) );
435
	}
436
437
	public function testGivenEmptyList_isEmpty() {
438
		$references = new ReferenceList();
439
		$this->assertTrue( $references->isEmpty() );
440
	}
441
442
	public function testGivenNonEmptyList_isNotEmpty() {
443
		$references = new ReferenceList();
444
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
445
446
		$this->assertFalse( $references->isEmpty() );
447
	}
448
449
}
450