Completed
Pull Request — master (#638)
by no
12:19 queued 08:59
created

ReferenceListTest::testConstructorIgnoresCopies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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