Completed
Push — master ( 660d1f...929911 )
by Bene
33s
created

testSerializeUnserializeRoundtrip()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 11
rs 9.4285
cc 1
eloc 7
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 testConstructorDoesNotIgnoreCopies() {
54
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
55
		$list = new ReferenceList( array( $reference, clone $reference ) );
56
		$this->assertCount( 2, $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 testAddReferenceDoesNotIgnoreCopies() {
212
		$list = new ReferenceList();
213
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
214
		$list->addReference( $reference );
215
		$list->addReference( clone $reference );
216
		$this->assertCount( 2, $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 testRemoveReferenceHashDoesNotRemoveCopies() {
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->assertFalse( $references->isEmpty() );
383
		$this->assertTrue( $references->hasReference( $reference ) );
384
		$this->assertNotSame( $reference, $references->getReference( $reference->getHash() ) );
385
	}
386
387
	public function testRemoveReferenceHashUpdatesIndexes() {
388
		$reference1 = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
389
		$reference2 = new Reference( array( new PropertyNoValueSnak( 2 ) ) );
390
		$references = new ReferenceList( array( $reference1, $reference2 ) );
391
392
		$references->removeReferenceHash( $reference1->getHash() );
393
394
		$this->assertSame( 0, $references->indexOf( $reference2 ) );
395
	}
396
397
	public function testGivenOneSnak_addNewReferenceAddsSnak() {
398
		$references = new ReferenceList();
399
		$snak = new PropertyNoValueSnak( 1 );
400
401
		$references->addNewReference( $snak );
402
		$this->assertTrue( $references->hasReference( new Reference( array( $snak ) ) ) );
403
	}
404
405
	public function testGivenMultipleSnaks_addNewReferenceAddsThem() {
406
		$references = new ReferenceList();
407
		$snak1 = new PropertyNoValueSnak( 1 );
408
		$snak2 = new PropertyNoValueSnak( 3 );
409
		$snak3 = new PropertyNoValueSnak( 2 );
410
411
		$references->addNewReference( $snak1, $snak2, $snak3 );
412
413
		$expectedSnaks = array( $snak1, $snak2, $snak3 );
414
		$this->assertTrue( $references->hasReference( new Reference( $expectedSnaks ) ) );
415
	}
416
417
	public function testGivenAnArrayOfSnaks_addNewReferenceAddsThem() {
418
		$references = new ReferenceList();
419
		$snaks = array(
420
			new PropertyNoValueSnak( 1 ),
421
			new PropertyNoValueSnak( 3 ),
422
			new PropertyNoValueSnak( 2 )
423
		);
424
425
		$references->addNewReference( $snaks );
426
		$this->assertTrue( $references->hasReference( new Reference( $snaks ) ) );
427
	}
428
429
	public function testAddNewReferenceDoesNotIgnoreIdenticalObjects() {
430
		$list = new ReferenceList();
431
		$snak = new PropertyNoValueSnak( 1 );
432
		$list->addNewReference( $snak );
433
		$list->addNewReference( $snak );
434
		$this->assertCount( 2, $list );
435
	}
436
437
	public function testAddNewReferenceDoesNotIgnoreCopies() {
438
		$list = new ReferenceList();
439
		$snak = new PropertyNoValueSnak( 1 );
440
		$list->addNewReference( $snak );
441
		$list->addNewReference( clone $snak );
442
		$this->assertCount( 2, $list );
443
	}
444
445
	public function testGivenNoneSnak_addNewReferenceThrowsException() {
446
		$references = new ReferenceList();
447
448
		$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...
449
		$references->addNewReference( new PropertyNoValueSnak( 1 ), null );
450
	}
451
452
	public function testEmptySerializationStability() {
453
		$list = new ReferenceList();
454
		$this->assertSame( 'a:0:{}', $list->serialize() );
455
	}
456
457
	public function testSerializationStability() {
458
		$list = new ReferenceList();
459
		$list->addNewReference( new PropertyNoValueSnak( 1 ) );
460
		$this->assertSame(
461
			"a:1:{i:0;O:28:\"Wikibase\\DataModel\\Reference\":1:{s:35:\"\x00Wikibase\\DataModel\\"
462
			. "Reference\x00snaks\";C:32:\"Wikibase\\DataModel\\Snak\\SnakList\":102:{a:2:{s:4:\""
463
			. 'data";a:1:{i:0;C:43:"Wikibase\\DataModel\\Snak\\PropertyNoValueSnak":4:{i:1;}}s:5'
464
			. ':"index";i:0;}}}}',
465
			$list->serialize()
466
		);
467
	}
468
469
	public function testSerializeUnserializeRoundtrip() {
470
		$original = new ReferenceList();
471
		$original->addNewReference( new PropertyNoValueSnak( 1 ) );
472
473
		/** @var ReferenceList $clone */
474
		$clone = unserialize( serialize( $original ) );
475
476
		$this->assertTrue( $original->equals( $clone ) );
477
		$this->assertSame( $original->getValueHash(), $clone->getValueHash() );
478
		$this->assertSame( $original->serialize(), $clone->serialize() );
479
	}
480
481
	public function testUnserializeCreatesNonIdenticalClones() {
482
		$original = new ReferenceList();
483
		$reference = new Reference( array( new PropertyNoValueSnak( 1 ) ) );
484
		$original->addReference( $reference );
485
486
		/** @var ReferenceList $clone */
487
		$clone = unserialize( serialize( $original ) );
488
		$clone->addReference( $reference );
489
490
		$this->assertCount( 2, $clone );
491
	}
492
493
	public function testGivenEmptyList_isEmpty() {
494
		$references = new ReferenceList();
495
		$this->assertTrue( $references->isEmpty() );
496
	}
497
498
	public function testGivenNonEmptyList_isNotEmpty() {
499
		$references = new ReferenceList();
500
		$references->addNewReference( new PropertyNoValueSnak( 1 ) );
501
502
		$this->assertFalse( $references->isEmpty() );
503
	}
504
505
}
506