Completed
Pull Request — master (#638)
by no
10:40 queued 07:32
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
		$original = new ReferenceList( array( $reference, $reference ) );
50
		$this->assertCount( 1, $original );
51
	}
52
53
	public function testConstructorIgnoresCopies() {
54
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
55
		$original = new ReferenceList( array( $reference, clone $reference ) );
56
		$this->assertCount( 1, $original );
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 testAddReferenceAtIndexZero() {
204
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
205
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
206
		$reference3 = new Reference( array( new PropertyNoValueSnak( 3 ) ) );
207
208
		$references = new ReferenceList( array( $reference1, $reference2 ) );
209
		$references->addReference( $reference3, 0 );
210
211
		$expectedList = new ReferenceList( array( $reference3, $reference1, $reference2 ) );
212
		$this->assertSameReferenceOrder( $expectedList, $references );
213
	}
214
215
	public function testAddReferenceAtNegativeIndex() {
216
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
217
		$referenceList = new ReferenceList();
218
219
		$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...
220
		$referenceList->addReference( $reference, -1 );
221
	}
222
223
	public function testGivenEmptyReference_addReferenceDoesNotAdd() {
224
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
225
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
226
		$emptyReference = new Reference( array() );
227
228
		$references = new ReferenceList( array( $reference1, $reference2 ) );
229
		$references->addReference( $emptyReference );
230
231
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
232
		$this->assertSameReferenceOrder( $expectedList, $references );
233
	}
234
235
	public function testGivenEmptyReferenceAndIndex_addReferenceDoesNotAdd() {
236
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
237
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
238
		$emptyReference = new Reference( array() );
239
240
		$references = new ReferenceList( array( $reference1, $reference2 ) );
241
		$references->addReference( $emptyReference, 0 );
242
243
		$expectedList = new ReferenceList( array( $reference1, $reference2 ) );
244
		$this->assertSameReferenceOrder( $expectedList, $references );
245
	}
246
247
	/**
248
	 * @dataProvider instanceProvider
249
	 */
250
	public function testIndexOf( ReferenceList $array ) {
251
		$this->assertFalse( $array->indexOf( new Reference() ) );
252
253
		$i = 0;
254
		foreach ( $array as $reference ) {
255
			$this->assertEquals( $i++, $array->indexOf( $reference ) );
256
		}
257
	}
258
259
	public function testIndexOf_checksForIdentity() {
260
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
261
		$reference2 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
262
		$referenceList = new ReferenceList( array( $reference1 ) );
263
264
		$this->assertNotSame( $reference1, $reference2, 'post condition' );
265
		$this->assertTrue( $reference1->equals( $reference2 ), 'post condition' );
266
		$this->assertSame( 0, $referenceList->indexOf( $reference1 ), 'identity' );
267
		$this->assertFalse( $referenceList->indexOf( $reference2 ), 'not equality' );
268
	}
269
270
	/**
271
	 * @dataProvider instanceProvider
272
	 */
273
	public function testEquals( ReferenceList $array ) {
274
		$this->assertTrue( $array->equals( $array ) );
275
		$this->assertFalse( $array->equals( 42 ) );
276
	}
277
278
	/**
279
	 * @dataProvider instanceProvider
280
	 */
281
	public function testGetValueHashReturnsString( ReferenceList $array ) {
282
		$this->assertInternalType( 'string', $array->getValueHash() );
283
	}
284
285
	/**
286
	 * @dataProvider instanceProvider
287
	 */
288
	public function testGetValueHashIsTheSameForClone( ReferenceList $array ) {
289
		$copy = unserialize( serialize( $array ) );
290
		$this->assertEquals( $array->getValueHash(), $copy->getValueHash() );
291
	}
292
293
	/**
294
	 * @dataProvider instanceProvider
295
	 */
296
	public function testHasReferenceHash( ReferenceList $references ) {
297
		$this->assertFalse( $references->hasReferenceHash( '~=[,,_,,]:3' ) );
298
299
		/**
300
		 * @var Hashable $reference
301
		 */
302
		foreach ( $references as $reference ) {
303
			$this->assertTrue( $references->hasReferenceHash( $reference->getHash() ) );
304
		}
305
	}
306
307
	/**
308
	 * @dataProvider instanceProvider
309
	 */
310
	public function testGetReference( ReferenceList $references ) {
311
		$this->assertNull( $references->getReference( '~=[,,_,,]:3' ) );
312
313
		/**
314
		 * @var Reference $reference
315
		 */
316
		foreach ( $references as $reference ) {
317
			$this->assertTrue( $reference->equals( $references->getReference( $reference->getHash() ) ) );
318
		}
319
	}
320
321
	/**
322
	 * @dataProvider instanceProvider
323
	 */
324
	public function testRemoveReferenceHash( ReferenceList $references ) {
325
		$references->removeReferenceHash( '~=[,,_,,]:3' );
326
327
		$hashes = array();
328
329
		/**
330
		 * @var Reference $reference
331
		 */
332
		foreach ( $references as $reference ) {
333
			$hashes[] = $reference->getHash();
334
		}
335
336
		foreach ( $hashes as $hash ) {
337
			$references->removeReferenceHash( $hash );
338
		}
339
340
		$this->assertEquals( 0, count( $references ) );
341
	}
342
343
	public function testRemoveReferenceHashRemovesIdenticalObjects() {
344
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
345
		$references = new ReferenceList( array( $reference, $reference ) );
346
347
		$references->removeReferenceHash( $reference->getHash() );
348
349
		$this->assertTrue( $references->isEmpty() );
350
	}
351
352
	public function testRemoveReferenceHashDoesNotRemoveCopies() {
353
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
354
		$references = new ReferenceList( array( $reference, clone $reference ) );
355
356
		$references->removeReferenceHash( $reference->getHash() );
357
358
		$this->assertFalse( $references->isEmpty() );
359
		$this->assertTrue( $references->hasReference( $reference ) );
360
		$this->assertNotSame( $reference, $references->getReference( $reference->getHash() ) );
361
	}
362
363
	public function testRemoveReferenceHashUpdatesIndexes() {
364
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
365
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
366
		$references = new ReferenceList( array( $reference1, $reference2 ) );
367
368
		$references->removeReferenceHash( $reference1->getHash() );
369
370
		$this->assertSame( 0, $references->indexOf( $reference2 ) );
371
	}
372
373
	public function testGivenOneSnak_addNewReferenceAddsSnak() {
374
		$references = new ReferenceList();
375
		$snak = new PropertyNoValueSnak( 1 );
376
377
		$references->addNewReference( $snak );
378
		$this->assertTrue( $references->hasReference( new Reference( array( $snak ) ) ) );
379
	}
380
381
	public function testGivenMultipleSnaks_addNewReferenceAddsThem() {
382
		$references = new ReferenceList();
383
		$snak1 = new PropertyNoValueSnak( 1 );
384
		$snak2 = new PropertyNoValueSnak( 3 );
385
		$snak3 = new PropertyNoValueSnak( 2 );
386
387
		$references->addNewReference( $snak1, $snak2, $snak3 );
388
389
		$expectedSnaks = array( $snak1, $snak2, $snak3 );
390
		$this->assertTrue( $references->hasReference( new Reference( $expectedSnaks ) ) );
391
	}
392
393
	public function testGivenAnArrayOfSnaks_addNewReferenceAddsThem() {
394
		$references = new ReferenceList();
395
		$snaks = array(
396
			new PropertyNoValueSnak( 1 ),
397
			new PropertyNoValueSnak( 3 ),
398
			new PropertyNoValueSnak( 2 )
399
		);
400
401
		$references->addNewReference( $snaks );
402
		$this->assertTrue( $references->hasReference( new Reference( $snaks ) ) );
403
	}
404
405
	public function testGivenNoneSnak_addNewReferenceThrowsException() {
406
		$references = new ReferenceList();
407
408
		$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...
409
		$references->addNewReference( new PropertyNoValueSnak( 1 ), null );
410
	}
411
412
	public function testSerializationStability() {
413
		$references = new ReferenceList();
414
		$this->assertSame( 'a:0:{}', $references->serialize() );
415
	}
416
417
	public function testSerializeRoundtrip() {
418
		$references = new ReferenceList();
419
420
		$references->addReference( new Reference() );
421
422
		$references->addReference( new Reference( array(
423
			new PropertyNoValueSnak( 2 ),
424
			new PropertyNoValueSnak( 3 ),
425
		) ) );
426
427
		$serialized = serialize( $references );
428
		$this->assertTrue( $references->equals( unserialize( $serialized ) ) );
429
	}
430
431
	public function testGivenEmptyList_isEmpty() {
432
		$references = new ReferenceList();
433
		$this->assertTrue( $references->isEmpty() );
434
	}
435
436
	public function testGivenNonEmptyList_isNotEmpty() {
437
		$references = new ReferenceList();
438
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
439
440
		$this->assertFalse( $references->isEmpty() );
441
	}
442
443
}
444