Completed
Pull Request — master (#638)
by no
06:14 queued 03:12
created

testAddNewReferenceIgnoresCopies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
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 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 testAddReferenceAtIndexIgnoresIdenticalObjects() {
220
		$list = new ReferenceList();
221
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
222
		$list->addReference( $reference, 0 );
223
		$list->addReference( $reference, 0 );
224
		$this->assertCount( 1, $list );
225
	}
226
227
	public function testAddReferenceAtIndexZero() {
228
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
229
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
230
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
231
232
		$references = new ReferenceList( array( $reference1, $reference2 ) );
233
		$references->addReference( $reference3, 0 );
234
235
		$expectedList = new ReferenceList( array( $reference3, $reference1, $reference2 ) );
236
		$this->assertSameReferenceOrder( $expectedList, $references );
237
	}
238
239
	public function testAddReferenceAtNegativeIndex() {
240
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
241
		$referenceList = new ReferenceList();
242
243
		$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...
244
		$referenceList->addReference( $reference, -1 );
245
	}
246
247
	public function testGivenEmptyReference_addReferenceDoesNotAdd() {
248
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
249
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
250
		$emptyReference = new Reference( array() );
251
252
		$references = new ReferenceList( array( $reference1, $reference2 ) );
253
		$references->addReference( $emptyReference );
254
255
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
256
		$this->assertSameReferenceOrder( $expectedList, $references );
257
	}
258
259
	public function testGivenEmptyReferenceAndIndex_addReferenceDoesNotAdd() {
260
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
261
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
262
		$emptyReference = new Reference( array() );
263
264
		$references = new ReferenceList( array( $reference1, $reference2 ) );
265
		$references->addReference( $emptyReference, 0 );
266
267
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
268
		$this->assertSameReferenceOrder( $expectedList, $references );
269
	}
270
271
	/**
272
	 * @dataProvider instanceProvider
273
	 */
274
	public function testIndexOf( ReferenceList $array ) {
275
		$this->assertFalse( $array->indexOf( new Reference() ) );
276
277
		$i = 0;
278
		foreach ( $array as $reference ) {
279
			$this->assertEquals( $i++, $array->indexOf( $reference ) );
280
		}
281
	}
282
283
	public function testIndexOf_checksForIdentity() {
284
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
285
		$reference2 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
286
		$referenceList = new ReferenceList( array( $reference1 ) );
287
288
		$this->assertNotSame( $reference1, $reference2, 'post condition' );
289
		$this->assertTrue( $reference1->equals( $reference2 ), 'post condition' );
290
		$this->assertSame( 0, $referenceList->indexOf( $reference1 ), 'identity' );
291
		$this->assertFalse( $referenceList->indexOf( $reference2 ), 'not equality' );
292
	}
293
294
	/**
295
	 * @dataProvider instanceProvider
296
	 */
297
	public function testEquals( ReferenceList $array ) {
298
		$this->assertTrue( $array->equals( $array ) );
299
		$this->assertFalse( $array->equals( 42 ) );
300
	}
301
302
	/**
303
	 * @dataProvider instanceProvider
304
	 */
305
	public function testGetValueHashReturnsString( ReferenceList $array ) {
306
		$this->assertInternalType( 'string', $array->getValueHash() );
307
	}
308
309
	/**
310
	 * @dataProvider instanceProvider
311
	 */
312
	public function testGetValueHashIsTheSameForClone( ReferenceList $array ) {
313
		$copy = unserialize( serialize( $array ) );
314
		$this->assertEquals( $array->getValueHash(), $copy->getValueHash() );
315
	}
316
317
	/**
318
	 * @dataProvider instanceProvider
319
	 */
320
	public function testHasReferenceHash( ReferenceList $references ) {
321
		$this->assertFalse( $references->hasReferenceHash( '~=[,,_,,]:3' ) );
322
323
		/**
324
		 * @var Hashable $reference
325
		 */
326
		foreach ( $references as $reference ) {
327
			$this->assertTrue( $references->hasReferenceHash( $reference->getHash() ) );
328
		}
329
	}
330
331
	/**
332
	 * @dataProvider instanceProvider
333
	 */
334
	public function testGetReference( ReferenceList $references ) {
335
		$this->assertNull( $references->getReference( '~=[,,_,,]:3' ) );
336
337
		/**
338
		 * @var Reference $reference
339
		 */
340
		foreach ( $references as $reference ) {
341
			$this->assertTrue( $reference->equals( $references->getReference( $reference->getHash() ) ) );
342
		}
343
	}
344
345
	/**
346
	 * @dataProvider instanceProvider
347
	 */
348
	public function testRemoveReferenceHash( ReferenceList $references ) {
349
		$references->removeReferenceHash( '~=[,,_,,]:3' );
350
351
		$hashes = array();
352
353
		/**
354
		 * @var Reference $reference
355
		 */
356
		foreach ( $references as $reference ) {
357
			$hashes[] = $reference->getHash();
358
		}
359
360
		foreach ( $hashes as $hash ) {
361
			$references->removeReferenceHash( $hash );
362
		}
363
364
		$this->assertEquals( 0, count( $references ) );
365
	}
366
367
	public function testRemoveReferenceHashRemovesIdenticalObjects() {
368
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
369
		$references = new ReferenceList( array( $reference, $reference ) );
370
371
		$references->removeReferenceHash( $reference->getHash() );
372
373
		$this->assertTrue( $references->isEmpty() );
374
	}
375
376
	public function testRemoveReferenceHashRemovesCopies() {
377
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
378
		$references = new ReferenceList( array( $reference, clone $reference ) );
379
380
		$references->removeReferenceHash( $reference->getHash() );
381
382
		$this->assertTrue( $references->isEmpty() );
383
	}
384
385
	public function testRemoveReferenceHashUpdatesIndexes() {
386
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
387
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
388
		$references = new ReferenceList( array( $reference1, $reference2 ) );
389
390
		$references->removeReferenceHash( $reference1->getHash() );
391
392
		$this->assertSame( 0, $references->indexOf( $reference2 ) );
393
	}
394
395
	public function testGivenOneSnak_addNewReferenceAddsSnak() {
396
		$references = new ReferenceList();
397
		$snak = new PropertyNoValueSnak( 1 );
398
399
		$references->addNewReference( $snak );
400
		$this->assertTrue( $references->hasReference( new Reference( array( $snak ) ) ) );
401
	}
402
403
	public function testGivenMultipleSnaks_addNewReferenceAddsThem() {
404
		$references = new ReferenceList();
405
		$snak1 = new PropertyNoValueSnak( 1 );
406
		$snak2 = new PropertyNoValueSnak( 3 );
407
		$snak3 = new PropertyNoValueSnak( 2 );
408
409
		$references->addNewReference( $snak1, $snak2, $snak3 );
410
411
		$expectedSnaks = array( $snak1, $snak2, $snak3 );
412
		$this->assertTrue( $references->hasReference( new Reference( $expectedSnaks ) ) );
413
	}
414
415
	public function testGivenAnArrayOfSnaks_addNewReferenceAddsThem() {
416
		$references = new ReferenceList();
417
		$snaks = array(
418
			new PropertyNoValueSnak( 1 ),
419
			new PropertyNoValueSnak( 3 ),
420
			new PropertyNoValueSnak( 2 )
421
		);
422
423
		$references->addNewReference( $snaks );
424
		$this->assertTrue( $references->hasReference( new Reference( $snaks ) ) );
425
	}
426
427
	public function testAddNewReferenceIgnoresIdenticalObjects() {
428
		$list = new ReferenceList();
429
		$snak = new PropertyNoValueSnak( 1 );
430
		$list->addNewReference( $snak );
431
		$list->addNewReference( $snak );
432
		$this->assertCount( 1, $list );
433
	}
434
435
	public function testAddNewReferenceIgnoresCopies() {
436
		$list = new ReferenceList();
437
		$snak = new PropertyNoValueSnak( 1 );
438
		$list->addNewReference( $snak );
439
		$list->addNewReference( clone $snak );
440
		$this->assertCount( 1, $list );
441
	}
442
443
	public function testGivenNoneSnak_addNewReferenceThrowsException() {
444
		$references = new ReferenceList();
445
446
		$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...
447
		$references->addNewReference( new PropertyNoValueSnak( 1 ), null );
448
	}
449
450
	public function testEmptySerializationStability() {
451
		$list = new ReferenceList();
452
		$this->assertSame( 'a:0:{}', $list->serialize() );
453
	}
454
455
	public function testSerializationStability() {
456
		$list = new ReferenceList();
457
		$list->addNewReference( new PropertyNoValueSnak( 1 ) );
458
		$this->assertSame(
459
			"a:1:{i:0;O:28:\"Wikibase\\DataModel\\Reference\":1:{s:35:\"\x00Wikibase\\DataModel\\"
460
			. "Reference\x00snaks\";C:32:\"Wikibase\\DataModel\\Snak\\SnakList\":102:{a:2:{s:4:\""
461
			. 'data";a:1:{i:0;C:43:"Wikibase\\DataModel\\Snak\\PropertyNoValueSnak":4:{i:1;}}s:5'
462
			. ':"index";i:0;}}}}',
463
			$list->serialize()
464
		);
465
	}
466
467
	public function testSerializeUnserializeRoundtrip() {
468
		$original = new ReferenceList();
469
		$original->addNewReference( new PropertyNoValueSnak( 1 ) );
470
471
		/** @var ReferenceList $clone */
472
		$clone = unserialize( serialize( $original ) );
473
474
		$this->assertTrue( $original->equals( $clone ) );
475
		$this->assertSame( $original->getValueHash(), $clone->getValueHash() );
476
		$this->assertSame( $original->serialize(), $clone->serialize() );
477
	}
478
479
	public function testUnserializeCreatesNonIdenticalClones() {
480
		$original = new ReferenceList();
481
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
482
		$original->addReference( $reference );
483
484
		/** @var ReferenceList $clone */
485
		$clone = unserialize( serialize( $original ) );
486
		$clone->addReference( $reference );
487
488
		$this->assertCount( 2, $clone );
489
	}
490
491
	public function testGivenEmptyList_isEmpty() {
492
		$references = new ReferenceList();
493
		$this->assertTrue( $references->isEmpty() );
494
	}
495
496
	public function testGivenNonEmptyList_isNotEmpty() {
497
		$references = new ReferenceList();
498
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
499
500
		$this->assertFalse( $references->isEmpty() );
501
	}
502
503
}
504