Completed
Push — moreRefTests ( b1b4d5 )
by no
03:25
created

ReferenceListTest::testEquals()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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