Test Failed
Push — atIndexRegression ( 3be0fe...6ffbbc )
by no
03:32 queued 10s
created

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