Completed
Push — 7.x ( 8fe89e...2279c4 )
by adam
09:26 queued 05:00
created

ItemTest::clearableProvider()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 18
nc 1
nop 0
1
<?php
2
3
namespace Wikibase\DataModel\Tests\Entity;
4
5
use OutOfBoundsException;
6
use PHPUnit_Framework_TestCase;
7
use Wikibase\DataModel\Entity\Item;
8
use Wikibase\DataModel\Entity\ItemId;
9
use Wikibase\DataModel\SiteLink;
10
use Wikibase\DataModel\SiteLinkList;
11
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
12
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
13
use Wikibase\DataModel\Statement\Statement;
14
use Wikibase\DataModel\Statement\StatementList;
15
use Wikibase\DataModel\Term\AliasGroup;
16
use Wikibase\DataModel\Term\AliasGroupList;
17
use Wikibase\DataModel\Term\Fingerprint;
18
use Wikibase\DataModel\Term\Term;
19
use Wikibase\DataModel\Term\TermList;
20
21
/**
22
 * @covers Wikibase\DataModel\Entity\Item
23
 *
24
 * @group Wikibase
25
 * @group WikibaseDataModel
26
 *
27
 * @license GPL-2.0+
28
 * @author Jeroen De Dauw < [email protected] >
29
 * @author John Erling Blad < [email protected] >
30
 * @author Michał Łazowik
31
 */
32
class ItemTest extends PHPUnit_Framework_TestCase {
33
34
	private function getNewEmpty() {
35
		return new Item();
36
	}
37
38
	public function testGetId() {
39
		$item = new Item();
40
		$this->assertNull( $item->getId() );
41
42
		$item->setId( new ItemId( 'Q1' ) );
43
		$this->assertEquals( new ItemId( 'Q1' ), $item->getId() );
44
45
		$item->setId( null );
46
		$this->assertNull( $item->getId() );
47
48
		$item = new Item( new ItemId( 'Q2' ) );
49
		$this->assertEquals( new ItemId( 'Q2' ), $item->getId() );
50
	}
51
52
	public function testSetIdUsingNumber() {
53
		$item = new Item();
54
		$item->setId( 42 );
55
		$this->assertEquals( new ItemId( 'Q42' ), $item->getId() );
56
	}
57
58
	public function testGetSiteLinkWithNonSetSiteId() {
59
		$item = new Item();
60
61
		$this->setExpectedException( OutOfBoundsException::class );
62
		$item->getSiteLinkList()->getBySiteId( 'enwiki' );
63
	}
64
65
	/**
66
	 * @dataProvider simpleSiteLinkProvider
67
	 */
68
	public function testAddSiteLink( SiteLink $siteLink ) {
69
		$item = new Item();
70
71
		$item->getSiteLinkList()->addSiteLink( $siteLink );
72
73
		$this->assertEquals(
74
			$siteLink,
75
			$item->getSiteLinkList()->getBySiteId( $siteLink->getSiteId() )
76
		);
77
	}
78
79
	public function simpleSiteLinkProvider() {
80
		$argLists = [];
81
82
		$argLists[] = [
83
			new SiteLink(
84
				'enwiki',
85
				'Wikidata',
86
				[
87
					new ItemId( 'Q42' )
88
				]
89
			)
90
		];
91
		$argLists[] = [
92
			new SiteLink(
93
				'nlwiki',
94
				'Wikidata'
95
			)
96
		];
97
		$argLists[] = [
98
			new SiteLink(
99
				'enwiki',
100
				'Nyan!',
101
				[
102
					new ItemId( 'Q42' ),
103
					new ItemId( 'Q149' )
104
				]
105
			)
106
		];
107
		$argLists[] = [
108
			new SiteLink(
109
				'foo bar',
110
				'baz bah',
111
				[
112
					new ItemId( 'Q3' ),
113
					new ItemId( 'Q7' )
114
				]
115
			)
116
		];
117
118
		return $argLists;
119
	}
120
121
	/**
122
	 * @dataProvider simpleSiteLinksProvider
123
	 */
124
	public function testGetSiteLinks() {
125
		$siteLinks = func_get_args();
126
		$item = new Item();
127
128
		foreach ( $siteLinks as $siteLink ) {
129
			$item->getSiteLinkList()->addSiteLink( $siteLink );
130
		}
131
132
		$this->assertInternalType( 'array', $item->getSiteLinks() );
0 ignored issues
show
Deprecated Code introduced by
The method Wikibase\DataModel\Entity\Item::getSiteLinks() has been deprecated with message: since 0.8, use getSiteLinkList() instead,

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...
133
		$this->assertEquals( $siteLinks, $item->getSiteLinks() );
0 ignored issues
show
Deprecated Code introduced by
The method Wikibase\DataModel\Entity\Item::getSiteLinks() has been deprecated with message: since 0.8, use getSiteLinkList() instead,

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...
134
	}
135
136
	public function simpleSiteLinksProvider() {
137
		$argLists = [];
138
139
		$argLists[] = [];
140
141
		$argLists[] = [ new SiteLink( 'enwiki', 'Wikidata', [ new ItemId( 'Q42' ) ] ) ];
142
143
		$argLists[] = [
144
			new SiteLink( 'enwiki', 'Wikidata' ),
145
			new SiteLink( 'nlwiki', 'Wikidata', [ new ItemId( 'Q3' ) ] )
146
		];
147
148
		$argLists[] = [
149
			new SiteLink( 'enwiki', 'Wikidata' ),
150
			new SiteLink( 'nlwiki', 'Wikidata' ),
151
			new SiteLink( 'foo bar', 'baz bah', [ new ItemId( 'Q2' ) ] )
152
		];
153
154
		return $argLists;
155
	}
156
157
	public function testHasLinkToSiteForFalse() {
158
		$item = new Item();
159
		$item->getSiteLinkList()->addNewSiteLink( 'ENWIKI', 'Wikidata', [ new ItemId( 'Q42' ) ] );
160
161
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'enwiki' ) );
162
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'dewiki' ) );
163
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'foo bar' ) );
164
	}
165
166
	public function testHasLinkToSiteForTrue() {
167
		$item = new Item();
168
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Wikidata', [ new ItemId( 'Q42' ) ] );
169
		$item->getSiteLinkList()->addNewSiteLink( 'dewiki', 'Wikidata' );
170
		$item->getSiteLinkList()->addNewSiteLink( 'foo bar', 'Wikidata' );
171
172
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'enwiki' ) );
173
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'dewiki' ) );
174
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'foo bar' ) );
175
	}
176
177
	public function testEmptyItemReturnsEmptySiteLinkList() {
178
		$item = new Item();
179
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
180
	}
181
182
	public function testAddSiteLinkOverridesOldLinks() {
183
		$item = new Item();
184
185
		$item->getSiteLinkList()->addNewSiteLink( 'kittens', 'foo' );
186
187
		$newLink = new SiteLink( 'kittens', 'bar' );
188
		$item->addSiteLink( $newLink );
0 ignored issues
show
Deprecated Code introduced by
The method Wikibase\DataModel\Entity\Item::addSiteLink() has been deprecated with message: since 0.8, use getSiteLinkList()->addSiteLink() instead.

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...
189
190
		$this->assertTrue( $item->getSiteLinkList()->getBySiteId( 'kittens' )->equals( $newLink ) );
191
	}
192
193
	public function testEmptyItemIsEmpty() {
194
		$item = new Item();
195
		$this->assertTrue( $item->isEmpty() );
196
	}
197
198
	public function testItemWithIdIsEmpty() {
199
		$item = new Item( new ItemId( 'Q1337' ) );
200
		$this->assertTrue( $item->isEmpty() );
201
	}
202
203
	public function testItemWithStuffIsNotEmpty() {
204
		$item = new Item();
205
		$item->setAliases( 'en', [ 'foo' ] );
206
		$this->assertFalse( $item->isEmpty() );
207
208
		$item = new Item();
209
		$item->getSiteLinkList()->addNewSiteLink( 'en', 'o_O' );
210
		$this->assertFalse( $item->isEmpty() );
211
212
		$item = new Item();
213
		$item->getStatements()->addStatement( $this->newStatement() );
214
		$this->assertFalse( $item->isEmpty() );
215
	}
216
217
	public function testItemWithSitelinksHasSitelinks() {
218
		$item = new Item();
219
		$item->getSiteLinkList()->addNewSiteLink( 'en', 'foo' );
220
		$this->assertFalse( $item->getSiteLinkList()->isEmpty() );
221
	}
222
223
	public function testItemWithoutSitelinksHasNoSitelinks() {
224
		$item = new Item();
225
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
226
	}
227
228
	private function newStatement() {
229
		$statement = new Statement( new PropertyNoValueSnak( 42 ) );
230
		$statement->setGuid( 'kittens' );
231
		return $statement;
232
	}
233
234
	public function testEmptyConstructor() {
235
		$item = new Item();
236
237
		$this->assertNull( $item->getId() );
238
		$this->assertTrue( $item->getFingerprint()->isEmpty() );
239
		$this->assertTrue( $item->getLabels()->isEmpty() );
240
		$this->assertTrue( $item->getDescriptions()->isEmpty() );
241
		$this->assertTrue( $item->getAliasGroups()->isEmpty() );
242
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
243
		$this->assertTrue( $item->getStatements()->isEmpty() );
244
	}
245
246
	public function testCanConstructWithStatementList() {
247
		$statement = new Statement( new PropertyNoValueSnak( 42 ) );
248
		$statement->setGuid( 'meh' );
249
250
		$statements = new StatementList( $statement );
251
252
		$item = new Item( null, null, null, $statements );
253
254
		$this->assertEquals(
255
			$statements,
256
			$item->getStatements()
257
		);
258
	}
259
260
	public function testSetStatements() {
261
		$item = new Item();
262
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
263
264
		$item->setStatements( new StatementList() );
265
		$this->assertTrue( $item->getStatements()->isEmpty() );
266
	}
267
268
	public function equalsProvider() {
269
		$firstItem = new Item();
270
		$firstItem->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
271
272
		$secondItem = new Item();
273
		$secondItem->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
274
275
		$secondItemWithId = $secondItem->copy();
276
		$secondItemWithId->setId( 42 );
277
278
		$differentId = $secondItemWithId->copy();
279
		$differentId->setId( 43 );
280
281
		return [
282
			[ new Item(), new Item() ],
283
			[ $firstItem, $secondItem ],
284
			[ $secondItem, $secondItemWithId ],
285
			[ $secondItemWithId, $differentId ],
286
		];
287
	}
288
289
	/**
290
	 * @dataProvider equalsProvider
291
	 */
292
	public function testEquals( Item $firstItem, Item $secondItem ) {
293
		$this->assertTrue( $firstItem->equals( $secondItem ) );
294
		$this->assertTrue( $secondItem->equals( $firstItem ) );
295
	}
296
297
	/**
298
	 * @return Item
299
	 */
300
	private function getBaseItem() {
301
		$item = new Item( new ItemId( 'Q42' ) );
302
		$item->setLabel( 'en', 'Same' );
303
		$item->setDescription( 'en', 'Same' );
304
		$item->setAliases( 'en', [ 'Same' ] );
305
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Same' );
306
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
307
308
		return $item;
309
	}
310
311
	public function notEqualsProvider() {
312
		$differentLabel = $this->getBaseItem();
313
		$differentLabel->setLabel( 'en', 'Different' );
314
315
		$differentDescription = $this->getBaseItem();
316
		$differentDescription->setDescription( 'en', 'Different' );
317
318
		$differentAlias = $this->getBaseItem();
319
		$differentAlias->setAliases( 'en', [ 'Different' ] );
320
321
		$differentSiteLink = $this->getBaseItem();
322
		$differentSiteLink->getSiteLinkList()->removeLinkWithSiteId( 'enwiki' );
323
		$differentSiteLink->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Different' );
324
325
		$differentStatement = $this->getBaseItem();
326
		$differentStatement->setStatements( new StatementList() );
327
		$differentStatement->getStatements()->addNewStatement( new PropertyNoValueSnak( 24 ) );
328
329
		$item = $this->getBaseItem();
330
331
		return [
332
			'empty' => [ $item, new Item() ],
333
			'label' => [ $item, $differentLabel ],
334
			'description' => [ $item, $differentDescription ],
335
			'alias' => [ $item, $differentAlias ],
336
			'siteLink' => [ $item, $differentSiteLink ],
337
			'statement' => [ $item, $differentStatement ],
338
		];
339
	}
340
341
	/**
342
	 * @dataProvider notEqualsProvider
343
	 */
344
	public function testNotEquals( Item $firstItem, Item $secondItem ) {
345
		$this->assertFalse( $firstItem->equals( $secondItem ) );
346
		$this->assertFalse( $secondItem->equals( $firstItem ) );
347
	}
348
349
	public function cloneProvider() {
350
		$item = new Item( new ItemId( 'Q1' ) );
351
		$item->setLabel( 'en', 'original' );
352
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 1 ) );
353
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Original' );
354
355
		return [
356
			'copy' => [ $item, $item->copy() ],
357
			'native clone' => [ $item, clone $item ],
358
		];
359
	}
360
361
	/**
362
	 * @dataProvider cloneProvider
363
	 */
364
	public function testCloneIsEqualButNotIdentical( Item $original, Item $clone ) {
365
		$this->assertNotSame( $original, $clone );
366
		$this->assertTrue( $original->equals( $clone ) );
367
		$this->assertSame(
368
			$original->getId(),
369
			$clone->getId(),
370
			'id is immutable and must not be cloned'
371
		);
372
373
		// The clone must not reference the same mutable objects
374
		$this->assertNotSame( $original->getFingerprint(), $clone->getFingerprint() );
375
		$this->assertNotSame( $original->getStatements(), $clone->getStatements() );
376
		$this->assertNotSame(
377
			$original->getStatements()->getFirstStatementWithGuid( null ),
378
			$clone->getStatements()->getFirstStatementWithGuid( null )
379
		);
380
		$this->assertNotSame( $original->getSiteLinkList(), $clone->getSiteLinkList() );
381
		$this->assertSame(
382
			$original->getSiteLinkList()->getBySiteId( 'enwiki' ),
383
			$clone->getSiteLinkList()->getBySiteId( 'enwiki' ),
384
			'SiteLink is immutable and must not be cloned'
385
		);
386
	}
387
388
	/**
389
	 * @dataProvider cloneProvider
390
	 */
391
	public function testOriginalDoesNotChangeWithClone( Item $original, Item $clone ) {
392
		$originalStatement = $original->getStatements()->getFirstStatementWithGuid( null );
393
		$clonedStatement = $clone->getStatements()->getFirstStatementWithGuid( null );
394
395
		$clone->setLabel( 'en', 'clone' );
396
		$clone->setDescription( 'en', 'clone' );
397
		$clone->setAliases( 'en', [ 'clone' ] );
398
		$clonedStatement->setGuid( 'clone' );
399
		$clonedStatement->setMainSnak( new PropertySomeValueSnak( 666 ) );
400
		$clonedStatement->setRank( Statement::RANK_DEPRECATED );
401
		$clonedStatement->getQualifiers()->addSnak( new PropertyNoValueSnak( 1 ) );
402
		$clonedStatement->getReferences()->addNewReference( new PropertyNoValueSnak( 1 ) );
403
		$clone->getSiteLinkList()->removeLinkWithSiteId( 'enwiki' );
404
405
		$this->assertSame( 'original', $original->getFingerprint()->getLabel( 'en' )->getText() );
406
		$this->assertFalse( $original->getFingerprint()->hasDescription( 'en' ) );
407
		$this->assertFalse( $original->getFingerprint()->hasAliasGroup( 'en' ) );
408
		$this->assertNull( $originalStatement->getGuid() );
409
		$this->assertSame( 'novalue', $originalStatement->getMainSnak()->getType() );
410
		$this->assertSame( Statement::RANK_NORMAL, $originalStatement->getRank() );
411
		$this->assertTrue( $originalStatement->getQualifiers()->isEmpty() );
412
		$this->assertTrue( $originalStatement->getReferences()->isEmpty() );
413
		$this->assertFalse( $original->getSiteLinkList()->isEmpty() );
414
	}
415
416
	// Below are tests copied from EntityTest
417
418
	public function labelProvider() {
419
		return [
420
			[ 'en', 'spam' ],
421
			[ 'en', 'spam', 'spam' ],
422
			[ 'de', 'foo bar baz' ],
423
		];
424
	}
425
426
	/**
427
	 * @dataProvider labelProvider
428
	 * @param string $languageCode
429
	 * @param string $labelText
430
	 * @param string $moarText
431
	 */
432
	public function testSetLabel( $languageCode, $labelText, $moarText = 'ohi there' ) {
433
		$entity = $this->getNewEmpty();
434
435
		$entity->setLabel( $languageCode, $labelText );
436
437
		$this->assertSame( $labelText, $entity->getFingerprint()->getLabel( $languageCode )->getText() );
438
439
		$entity->setLabel( $languageCode, $moarText );
440
441
		$this->assertSame( $moarText, $entity->getFingerprint()->getLabel( $languageCode )->getText() );
442
	}
443
444
	public function descriptionProvider() {
445
		return [
446
			[ 'en', 'spam' ],
447
			[ 'en', 'spam', 'spam' ],
448
			[ 'de', 'foo bar baz' ],
449
		];
450
	}
451
452
	/**
453
	 * @dataProvider descriptionProvider
454
	 * @param string $languageCode
455
	 * @param string $description
456
	 * @param string $moarText
457
	 */
458
	public function testSetDescription( $languageCode, $description, $moarText = 'ohi there' ) {
459
		$entity = $this->getNewEmpty();
460
461
		$entity->setDescription( $languageCode, $description );
462
463
		$this->assertSame( $description, $entity->getFingerprint()->getDescription( $languageCode )->getText() );
464
465
		$entity->setDescription( $languageCode, $moarText );
466
467
		$this->assertSame( $moarText, $entity->getFingerprint()->getDescription( $languageCode )->getText() );
468
	}
469
470
	public function aliasesProvider() {
471
		return [
472
			[ [
473
				       'en' => [ [ 'spam' ] ]
474
			       ] ],
475
			[ [
476
				       'en' => [ [ 'foo', 'bar', 'baz' ] ]
477
			       ] ],
478
			[ [
479
				       'en' => [ [ 'foo', 'bar' ], [ 'baz', 'spam' ] ]
480
			       ] ],
481
			[ [
482
				       'en' => [ [ 'foo', 'bar', 'baz' ] ],
483
				       'de' => [ [ 'foobar' ], [ 'baz' ] ],
484
			       ] ],
485
			// with duplicates
486
			[ [
487
				       'en' => [ [ 'spam', 'ham', 'ham' ] ]
488
			       ] ],
489
			[ [
490
				       'en' => [ [ 'foo', 'bar' ], [ 'bar', 'spam' ] ]
491
			       ] ],
492
		];
493
	}
494
495
	/**
496
	 * @dataProvider aliasesProvider
497
	 */
498
	public function testSetAliases( array $aliasesLists ) {
499
		$entity = $this->getNewEmpty();
500
501
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
502
			foreach ( $aliasesList as $aliases ) {
503
				$entity->setAliases( $langCode, $aliases );
504
			}
505
		}
506
507
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
508
			$expected = array_values( array_unique( array_pop( $aliasesList ) ) );
509
			$actual = $entity->getFingerprint()->getAliasGroup( $langCode )->getAliases();
510
			$this->assertSame( $expected, $actual );
511
		}
512
	}
513
514
	/**
515
	 * @dataProvider aliasesProvider
516
	 */
517
	public function testSetEmptyAlias( array $aliasesLists ) {
518
		$entity = $this->getNewEmpty();
519
520
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
521
			foreach ( $aliasesList as $aliases ) {
522
				$entity->setAliases( $langCode, $aliases );
523
			}
524
		}
525
		$entity->setAliases( 'zh', [ 'wind', 'air', '', 'fire' ] );
526
		$entity->setAliases( 'zu', [ '', '' ] );
527
528
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
529
			$expected = array_values( array_unique( array_pop( $aliasesList ) ) );
530
			asort( $aliasesList );
531
532
			$actual = $entity->getFingerprint()->getAliasGroup( $langCode )->getAliases();
533
			asort( $actual );
534
535
			$this->assertEquals( $expected, $actual );
536
		}
537
	}
538
539
	public function instanceProvider() {
540
		$entities = [];
541
542
		// empty
543
		$entity = $this->getNewEmpty();
544
		$entities[] = $entity;
545
546
		// ID only
547
		$entity = clone $entity;
548
		$entity->setId( 44 );
549
550
		$entities[] = $entity;
551
552
		// with labels and stuff
553
		$entity = $this->getNewEmpty();
554
		$entity->setAliases( 'en', [ 'o', 'noez' ] );
555
		$entity->setLabel( 'de', 'spam' );
556
		$entity->setDescription( 'en', 'foo bar baz' );
557
558
		$entities[] = $entity;
559
560
		// with labels etc and ID
561
		$entity = clone $entity;
562
		$entity->setId( 42 );
563
564
		$entities[] = $entity;
565
566
		$argLists = [];
567
568
		foreach ( $entities as $entity ) {
569
			$argLists[] = [ $entity ];
570
		}
571
572
		return $argLists;
573
	}
574
575
	/**
576
	 * @dataProvider instanceProvider
577
	 * @param Item $entity
578
	 */
579
	public function testCopy( Item $entity ) {
580
		$copy = $entity->copy();
581
582
		// The equality method alone is not enough since it does not check the IDs.
583
		$this->assertTrue( $entity->equals( $copy ) );
584
		$this->assertEquals( $entity->getId(), $copy->getId() );
585
586
		$this->assertNotSame( $entity, $copy );
587
	}
588
589
	public function testCopyRetainsLabels() {
590
		$item = new Item();
591
592
		$item->getFingerprint()->setLabel( 'en', 'foo' );
593
		$item->getFingerprint()->setLabel( 'de', 'bar' );
594
595
		$newItem = $item->copy();
596
597
		$this->assertTrue( $newItem->getFingerprint()->getLabels()->hasTermForLanguage( 'en' ) );
598
		$this->assertTrue( $newItem->getFingerprint()->getLabels()->hasTermForLanguage( 'de' ) );
599
	}
600
601
	/**
602
	 * @dataProvider instanceProvider
603
	 * @param Item $entity
604
	 */
605
	public function testSerialize( Item $entity ) {
606
		$string = serialize( $entity );
607
608
		$this->assertInternalType( 'string', $string );
609
610
		$instance = unserialize( $string );
611
612
		$this->assertTrue( $entity->equals( $instance ) );
613
		$this->assertEquals( $entity->getId(), $instance->getId() );
614
	}
615
616
	public function testWhenNoStuffIsSet_getFingerprintReturnsEmptyFingerprint() {
617
		$entity = $this->getNewEmpty();
618
619
		$this->assertEquals(
620
			new Fingerprint(),
621
			$entity->getFingerprint()
622
		);
623
	}
624
625
	public function testWhenLabelsAreSet_getFingerprintReturnsFingerprintWithLabels() {
626
		$entity = $this->getNewEmpty();
627
628
		$entity->setLabel( 'en', 'foo' );
629
		$entity->setLabel( 'de', 'bar' );
630
631
		$this->assertEquals(
632
			new Fingerprint(
633
				new TermList( [
634
					new Term( 'en', 'foo' ),
635
					new Term( 'de', 'bar' ),
636
				] )
637
			),
638
			$entity->getFingerprint()
639
		);
640
	}
641
642
	public function testWhenTermsAreSet_getFingerprintReturnsFingerprintWithTerms() {
643
		$entity = $this->getNewEmpty();
644
645
		$entity->setLabel( 'en', 'foo' );
646
		$entity->setDescription( 'en', 'foo bar' );
647
		$entity->setAliases( 'en', [ 'foo', 'bar' ] );
648
649
		$this->assertEquals(
650
			new Fingerprint(
651
				new TermList( [
652
					new Term( 'en', 'foo' ),
653
				] ),
654
				new TermList( [
655
					new Term( 'en', 'foo bar' )
656
				] ),
657
				new AliasGroupList( [
658
					new AliasGroup( 'en', [ 'foo', 'bar' ] )
659
				] )
660
			),
661
			$entity->getFingerprint()
662
		);
663
	}
664
665
	public function testGivenEmptyFingerprint_noTermsAreSet() {
666
		$entity = $this->getNewEmpty();
667
		$entity->setFingerprint( new Fingerprint() );
668
669
		$this->assertTrue( $entity->getFingerprint()->isEmpty() );
670
	}
671
672
	public function testGivenEmptyFingerprint_existingTermsAreRemoved() {
673
		$entity = $this->getNewEmpty();
674
675
		$entity->setLabel( 'en', 'foo' );
676
		$entity->setDescription( 'en', 'foo bar' );
677
		$entity->setAliases( 'en', [ 'foo', 'bar' ] );
678
679
		$entity->setFingerprint( new Fingerprint() );
680
681
		$this->assertTrue( $entity->getFingerprint()->isEmpty() );
682
	}
683
684
	public function testWhenSettingFingerprint_getFingerprintReturnsIt() {
685
		$fingerprint = new Fingerprint(
686
			new TermList( [
687
				new Term( 'en', 'english label' ),
688
			] ),
689
			new TermList( [
690
				new Term( 'en', 'english description' )
691
			] ),
692
			new AliasGroupList( [
693
				new AliasGroup( 'en', [ 'first en alias', 'second en alias' ] )
694
			] )
695
		);
696
697
		$entity = $this->getNewEmpty();
698
		$entity->setFingerprint( $fingerprint );
699
		$newFingerprint = $entity->getFingerprint();
700
701
		$this->assertSame( $fingerprint, $newFingerprint );
702
	}
703
704
	public function testGetLabels() {
705
		$item = new Item();
706
		$item->setLabel( 'en', 'foo' );
707
708
		$this->assertEquals(
709
			new TermList( [
710
				new Term( 'en', 'foo' )
711
			] ),
712
			$item->getLabels()
713
		);
714
	}
715
716
	public function testGetDescriptions() {
717
		$item = new Item();
718
		$item->setDescription( 'en', 'foo bar' );
719
720
		$this->assertEquals(
721
			new TermList( [
722
				new Term( 'en', 'foo bar' )
723
			] ),
724
			$item->getDescriptions()
725
		);
726
	}
727
728
	public function testGetAliasGroups() {
729
		$item = new Item();
730
		$item->setAliases( 'en', [ 'foo', 'bar' ] );
731
732
		$this->assertEquals(
733
			new AliasGroupList( [
734
				new AliasGroup( 'en', [ 'foo', 'bar' ] )
735
			] ),
736
			$item->getAliasGroups()
737
		);
738
	}
739
740
	public function testGetLabels_sameListAsFingerprint() {
741
		$item = new Item();
742
743
		$this->assertSame(
744
			$item->getFingerprint()->getLabels(),
745
			$item->getLabels()
746
		);
747
	}
748
749
	public function testGetDescriptions_sameListAsFingerprint() {
750
		$item = new Item();
751
752
		$this->assertSame(
753
			$item->getFingerprint()->getDescriptions(),
754
			$item->getDescriptions()
755
		);
756
	}
757
758
	public function testGetAliasGroups_sameListAsFingerprint() {
759
		$item = new Item();
760
761
		$this->assertSame(
762
			$item->getFingerprint()->getAliasGroups(),
763
			$item->getAliasGroups()
764
		);
765
	}
766
767
	/**
768
	 * @dataProvider clearableProvider
769
	 */
770
	public function testClear( Item $item ) {
771
		$clone = $item->copy();
772
773
		$item->clear();
774
775
		$this->assertEquals( $clone->getId(), $item->getId(), 'cleared Item should keep its id' );
776
		$this->assertTrue( $item->isEmpty(), 'cleared Item should be empty' );
777
	}
778
779
	public function clearableProvider() {
780
		return [
781
			'empty' => [ new Item( new ItemId( 'Q23' ) ), ],
782
			'with fingerprint' => [
783
				new Item(
784
					new ItemId( 'Q42' ),
785
					new Fingerprint( new TermList( [ new Term( 'en', 'foo' ) ] ) )
786
				),
787
			],
788
			'with sitelink' => [
789
				new Item(
790
					new ItemId( 'Q123' ),
791
					null,
792
					new SiteLinkList( [ new SiteLink( 'enwiki', 'Wikidata' ) ] )
793
				)
794
			],
795
			'with statement' => [
796
				new Item(
797
					new ItemId( 'Q321' ),
798
					null,
799
					null,
800
					new StatementList( [ $this->newStatement() ] )
801
				)
802
			]
803
		];
804
	}
805
806
}
807