Completed
Pull Request — master (#631)
by Bene
06:22 queued 03:20
created

testPropertyWithStatementsIsNotEmpty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace Wikibase\DataModel\Tests\Entity;
4
5
use InvalidArgumentException;
6
use PHPUnit_Framework_TestCase;
7
use Wikibase\DataModel\Entity\Property;
8
use Wikibase\DataModel\Entity\PropertyId;
9
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
10
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
11
use Wikibase\DataModel\Statement\Statement;
12
use Wikibase\DataModel\Statement\StatementList;
13
use Wikibase\DataModel\Term\AliasGroup;
14
use Wikibase\DataModel\Term\AliasGroupList;
15
use Wikibase\DataModel\Term\Fingerprint;
16
use Wikibase\DataModel\Term\Term;
17
use Wikibase\DataModel\Term\TermList;
18
19
/**
20
 * @covers Wikibase\DataModel\Entity\Property
21
 *
22
 * @group Wikibase
23
 * @group WikibaseProperty
24
 * @group WikibaseDataModel
25
 * @group PropertyTest
26
 *
27
 * @licence GNU GPL v2+
28
 * @author Jeroen De Dauw < [email protected] >
29
 */
30
class PropertyTest extends PHPUnit_Framework_TestCase {
31
32
	private function getNewEmpty() {
33
		return Property::newFromType( 'string' );
34
	}
35
36
	public function testConstructorWithAllParameters() {
37
		$property = new Property(
38
			new PropertyId( 'P42' ),
39
			new Fingerprint(),
40
			'string',
41
			new StatementList()
42
		);
43
		$this->assertInstanceOf( 'Wikibase\DataModel\Entity\Property', $property );
44
		$this->assertEquals( new PropertyId( 'P42' ), $property->getId() );
45
		$this->assertEquals( new Fingerprint(), $property->getFingerprint() );
46
		$this->assertEquals( 'string', $property->getDataTypeId() );
47
		$this->assertEquals( new StatementList(), $property->getStatements() );
48
	}
49
50
	public function testConstructorWithMinimalParameters() {
51
		$property = new Property( null, null, '' );
52
		$this->assertInstanceOf( 'Wikibase\DataModel\Entity\Property', $property );
53
		$this->assertNull( $property->getId() );
54
		$this->assertEquals( new Fingerprint(), $property->getFingerprint() );
55
		$this->assertEquals( '', $property->getDataTypeId() );
56
		$this->assertEquals( new StatementList(), $property->getStatements() );
57
	}
58
59
	/**
60
	 * @expectedException InvalidArgumentException
61
	 */
62
	public function testGivenInvalidType_ConstructorThrowsException() {
63
		new Property( null, null, null );
64
	}
65
66
	public function testNewFromType() {
67
		$property = Property::newFromType( 'string' );
68
		$this->assertInstanceOf( 'Wikibase\DataModel\Entity\Property', $property );
69
		$this->assertEquals( 'string', $property->getDataTypeId() );
70
	}
71
72
	public function testSetAndGetDataTypeId() {
73
		$property = Property::newFromType( 'string' );
74
75
		foreach ( array( 'string', 'foobar', 'nyan', 'string' ) as $typeId ) {
76
			$property->setDataTypeId( $typeId );
77
			$this->assertEquals( $typeId, $property->getDataTypeId() );
78
		}
79
	}
80
81
	public function testWhenIdSetWithNumber_GetIdReturnsPropertyId() {
82
		$property = Property::newFromType( 'string' );
83
		$property->setId( 42 );
84
85
		$this->assertHasCorrectIdType( $property );
86
	}
87
88
	protected function assertHasCorrectIdType( Property $property ) {
89
		$this->assertInstanceOf( 'Wikibase\DataModel\Entity\PropertyId', $property->getId() );
90
	}
91
92
	public function testWhenIdSetWithPropertyId_GetIdReturnsPropertyId() {
93
		$property = Property::newFromType( 'string' );
94
		$property->setId( new PropertyId( 'P42' ) );
95
96
		$this->assertHasCorrectIdType( $property );
97
	}
98
99
	public function testPropertyWithTypeIsEmpty() {
100
		$this->assertTrue( Property::newFromType( 'string' )->isEmpty() );
101
	}
102
103
	public function testPropertyWithIdIsEmpty() {
104
		$property = Property::newFromType( 'string' );
105
		$property->setId( 1337 );
106
		$this->assertTrue( $property->isEmpty() );
107
	}
108
109
	public function testPropertyWithFingerprintIsNotEmpty() {
110
		$property = Property::newFromType( 'string' );
111
		$property->getFingerprint()->setAliasGroup( 'en', array( 'foo' ) );
112
		$this->assertFalse( $property->isEmpty() );
113
	}
114
115
	public function testClearRemovesAllButId() {
116
		$property = Property::newFromType( 'string' );
117
		$property->setId( 42 );
118
		$property->getFingerprint()->setLabel( 'en', 'foo' );
119
		$property->getStatements()->addNewStatement( new PropertyNoValueSnak( 1 ) );
120
121
		$property->clear();
122
123
		$this->assertEquals( new PropertyId( 'P42' ), $property->getId() );
124
		$this->assertTrue( $property->isEmpty() );
125
	}
126
127
	public function testGetStatementsReturnsEmptyListForEmptyProperty() {
128
		$property = Property::newFromType( 'string' );
129
130
		$this->assertEquals( new StatementList(), $property->getStatements() );
131
	}
132
133
	public function testSetAndGetStatements() {
134
		$property = Property::newFromType( 'string' );
135
136
		$statementList = $this->newNonEmptyStatementList();
137
		$property->setStatements( $statementList );
138
139
		$this->assertEquals( $statementList, $property->getStatements() );
140
	}
141
142
	private function newNonEmptyStatementList() {
143
		$statementList = new StatementList();
144
		$statementList->addNewStatement( new PropertyNoValueSnak( 42 ) );
145
		$statementList->addNewStatement( new PropertyNoValueSnak( 1337 ) );
146
147
		return $statementList;
148
	}
149
150
	public function equalsProvider() {
151
		$firstProperty = Property::newFromType( 'string' );
152
		$firstProperty->setStatements( $this->newNonEmptyStatementList() );
153
154
		$secondProperty = Property::newFromType( 'string' );
155
		$secondProperty->setStatements( $this->newNonEmptyStatementList() );
156
157
		$secondPropertyWithId = $secondProperty->copy();
158
		$secondPropertyWithId->setId( 42 );
159
160
		$differentId = $secondPropertyWithId->copy();
161
		$differentId->setId( 43 );
162
163
		return array(
164
			array( Property::newFromType( 'string' ), Property::newFromType( 'string' ) ),
165
			array( $firstProperty, $secondProperty ),
166
			array( $secondProperty, $secondPropertyWithId ),
167
			array( $secondPropertyWithId, $differentId ),
168
		);
169
	}
170
171
	/**
172
	 * @dataProvider equalsProvider
173
	 */
174
	public function testEquals( Property $firstProperty, Property $secondProperty ) {
175
		$this->assertTrue( $firstProperty->equals( $secondProperty ) );
176
		$this->assertTrue( $secondProperty->equals( $firstProperty ) );
177
	}
178
179
	private function getBaseProperty() {
180
		$property = Property::newFromType( 'string' );
181
182
		$property->setId( 42 );
183
		$property->getFingerprint()->setLabel( 'en', 'Same' );
184
		$property->getFingerprint()->setDescription( 'en', 'Same' );
185
		$property->getFingerprint()->setAliasGroup( 'en', array( 'Same' ) );
186
		$property->setStatements( $this->newNonEmptyStatementList() );
187
188
		return $property;
189
	}
190
191
	public function notEqualsProvider() {
192
		$differentLabel = $this->getBaseProperty();
193
		$differentLabel->getFingerprint()->setLabel( 'en', 'Different' );
194
195
		$differentDescription = $this->getBaseProperty();
196
		$differentDescription->getFingerprint()->setDescription( 'en', 'Different' );
197
198
		$differentAlias = $this->getBaseProperty();
199
		$differentAlias->getFingerprint()->setAliasGroup( 'en', array( 'Different' ) );
200
201
		$differentStatement = $this->getBaseProperty();
202
		$differentStatement->setStatements( new StatementList() );
203
204
		$property = $this->getBaseProperty();
205
206
		return array(
207
			'empty' => array( $property, Property::newFromType( 'string' ) ),
208
			'label' => array( $property, $differentLabel ),
209
			'description' => array( $property, $differentDescription ),
210
			'alias' => array( $property, $differentAlias ),
211
			'dataType' => array( Property::newFromType( 'string' ), Property::newFromType( 'foo' ) ),
212
			'statement' => array( $property, $differentStatement ),
213
		);
214
	}
215
216
	/**
217
	 * @dataProvider notEqualsProvider
218
	 */
219
	public function testNotEquals( Property $firstProperty, Property $secondProperty ) {
220
		$this->assertFalse( $firstProperty->equals( $secondProperty ) );
221
		$this->assertFalse( $secondProperty->equals( $firstProperty ) );
222
	}
223
224
	public function testPropertyWithStatementsIsNotEmpty() {
225
		$property = Property::newFromType( 'string' );
226
		$property->setStatements( $this->newNonEmptyStatementList() );
227
228
		$this->assertFalse( $property->isEmpty() );
229
	}
230
231
	public function cloneProvider() {
232
		$property = new Property( new PropertyId( 'P1' ), null, 'string' );
233
		$property->setLabel( 'en', 'original' );
234
		$property->getStatements()->addNewStatement( new PropertyNoValueSnak( 1 ) );
235
236
		return array(
237
			'copy' => array( $property, $property->copy() ),
238
			'native clone' => array( $property, clone $property ),
239
		);
240
	}
241
242
	/**
243
	 * @dataProvider cloneProvider
244
	 */
245
	public function testCloneIsEqualButNotIdentical( Property $original, Property $clone ) {
246
		$this->assertNotSame( $original, $clone );
247
		$this->assertTrue( $original->equals( $clone ) );
248
		$this->assertSame(
249
			$original->getId(),
250
			$clone->getId(),
251
			'id is immutable and must not be cloned'
252
		);
253
254
		// The clone must not reference the same mutable objects
255
		$this->assertNotSame( $original->getFingerprint(), $clone->getFingerprint() );
256
		$this->assertNotSame( $original->getStatements(), $clone->getStatements() );
257
		$this->assertNotSame(
258
			$original->getStatements()->getFirstStatementWithGuid( null ),
259
			$clone->getStatements()->getFirstStatementWithGuid( null )
260
		);
261
	}
262
263
	/**
264
	 * @dataProvider cloneProvider
265
	 */
266
	public function testOriginalDoesNotChangeWithClone( Property $original, Property $clone ) {
267
		$originalStatement = $original->getStatements()->getFirstStatementWithGuid( null );
268
		$clonedStatement = $clone->getStatements()->getFirstStatementWithGuid( null );
269
270
		$clone->setLabel( 'en', 'clone' );
271
		$clone->setDescription( 'en', 'clone' );
272
		$clone->setAliases( 'en', array( 'clone' ) );
273
		$clonedStatement->setGuid( 'clone' );
274
		$clonedStatement->setMainSnak( new PropertySomeValueSnak( 666 ) );
275
		$clonedStatement->setRank( Statement::RANK_DEPRECATED );
276
		$clonedStatement->getQualifiers()->addSnak( new PropertyNoValueSnak( 1 ) );
277
		$clonedStatement->getReferences()->addNewReference( new PropertyNoValueSnak( 1 ) );
278
279
		$this->assertSame( 'original', $original->getFingerprint()->getLabel( 'en' )->getText() );
280
		$this->assertFalse( $original->getFingerprint()->hasDescription( 'en' ) );
281
		$this->assertFalse( $original->getFingerprint()->hasAliasGroup( 'en' ) );
282
		$this->assertNull( $originalStatement->getGuid() );
283
		$this->assertSame( 'novalue', $originalStatement->getMainSnak()->getType() );
284
		$this->assertSame( Statement::RANK_NORMAL, $originalStatement->getRank() );
285
		$this->assertTrue( $originalStatement->getQualifiers()->isEmpty() );
286
		$this->assertTrue( $originalStatement->getReferences()->isEmpty() );
287
	}
288
289
	// Below are tests copied from EntityTest
290
291
	public function labelProvider() {
292
		return array(
293
			array( 'en', 'spam' ),
294
			array( 'en', 'spam', 'spam' ),
295
			array( 'de', 'foo bar baz' ),
296
		);
297
	}
298
299
	/**
300
	 * @dataProvider labelProvider
301
	 * @param string $languageCode
302
	 * @param string $labelText
303
	 * @param string $moarText
304
	 */
305
	public function testSetLabel( $languageCode, $labelText, $moarText = 'ohi there' ) {
306
		$entity = $this->getNewEmpty();
307
308
		$entity->setLabel( $languageCode, $labelText );
309
310
		$this->assertEquals( $labelText, $entity->getFingerprint()->getLabel( $languageCode )->getText() );
311
312
		$entity->setLabel( $languageCode, $moarText );
313
314
		$this->assertEquals( $moarText, $entity->getFingerprint()->getLabel( $languageCode )->getText() );
315
	}
316
317
	public function descriptionProvider() {
318
		return array(
319
			array( 'en', 'spam' ),
320
			array( 'en', 'spam', 'spam' ),
321
			array( 'de', 'foo bar baz' ),
322
		);
323
	}
324
325
	/**
326
	 * @dataProvider descriptionProvider
327
	 * @param string $languageCode
328
	 * @param string $description
329
	 * @param string $moarText
330
	 */
331
	public function testSetDescription( $languageCode, $description, $moarText = 'ohi there' ) {
332
		$entity = $this->getNewEmpty();
333
334
		$entity->setDescription( $languageCode, $description );
335
336
		$this->assertEquals( $description, $entity->getFingerprint()->getDescription( $languageCode )->getText() );
337
338
		$entity->setDescription( $languageCode, $moarText );
339
340
		$this->assertEquals( $moarText, $entity->getFingerprint()->getDescription( $languageCode )->getText() );
341
	}
342
343
	public function aliasesProvider() {
344
		return array(
345
			array( array(
346
				       'en' => array( array( 'spam' ) )
347
			       ) ),
348
			array( array(
349
				       'en' => array( array( 'foo', 'bar', 'baz' ) )
350
			       ) ),
351
			array( array(
352
				       'en' => array( array( 'foo', 'bar' ), array( 'baz', 'spam' ) )
353
			       ) ),
354
			array( array(
355
				       'en' => array( array( 'foo', 'bar', 'baz' ) ),
356
				       'de' => array( array( 'foobar' ), array( 'baz' ) ),
357
			       ) ),
358
			// with duplicates
359
			array( array(
360
				       'en' => array( array( 'spam', 'ham', 'ham' ) )
361
			       ) ),
362
			array( array(
363
				       'en' => array( array( 'foo', 'bar' ), array( 'bar', 'spam' ) )
364
			       ) ),
365
		);
366
	}
367
368
	/**
369
	 * @dataProvider aliasesProvider
370
	 */
371
	public function testSetAliases( array $aliasesLists ) {
372
		$entity = $this->getNewEmpty();
373
374
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
375
			foreach ( $aliasesList as $aliases ) {
376
				$entity->setAliases( $langCode, $aliases );
377
			}
378
		}
379
380
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
381
			$expected = array_values( array_unique( array_pop( $aliasesList ) ) );
382
			asort( $aliasesList );
383
384
			$actual = $entity->getFingerprint()->getAliasGroup( $langCode )->getAliases();
385
			asort( $actual );
386
387
			$this->assertEquals( $expected, $actual );
388
		}
389
	}
390
391
	/**
392
	 * @dataProvider aliasesProvider
393
	 */
394
	public function testSetEmptyAlias( array $aliasesLists ) {
395
		$entity = $this->getNewEmpty();
396
397
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
398
			foreach ( $aliasesList as $aliases ) {
399
				$entity->setAliases( $langCode, $aliases );
400
			}
401
		}
402
		$entity->setAliases( 'zh', array( 'wind', 'air', '', 'fire' ) );
403
		$entity->setAliases( 'zu', array( '', '' ) );
404
405
		foreach ( $aliasesLists as $langCode => $aliasesList ) {
406
			$expected = array_values( array_unique( array_pop( $aliasesList ) ) );
407
			asort( $aliasesList );
408
409
			$actual = $entity->getFingerprint()->getAliasGroup( $langCode )->getAliases();
410
			asort( $actual );
411
412
			$this->assertEquals( $expected, $actual );
413
		}
414
	}
415
416
	public function instanceProvider() {
417
		$entities = array();
418
419
		// empty
420
		$entity = $this->getNewEmpty();
421
		$entities[] = $entity;
422
423
		// ID only
424
		$entity = clone $entity;
425
		$entity->setId( 44 );
426
427
		$entities[] = $entity;
428
429
		// with labels and stuff
430
		$entity = $this->getNewEmpty();
431
		$entity->setAliases( 'en', array( 'o', 'noez' ) );
432
		$entity->setLabel( 'de', 'spam' );
433
		$entity->setDescription( 'en', 'foo bar baz' );
434
435
		$entities[] = $entity;
436
437
		// with labels etc and ID
438
		$entity = clone $entity;
439
		$entity->setId( 42 );
440
441
		$entities[] = $entity;
442
443
		$argLists = array();
444
445
		foreach ( $entities as $entity ) {
446
			$argLists[] = array( $entity );
447
		}
448
449
		return $argLists;
450
	}
451
452
	/**
453
	 * @dataProvider instanceProvider
454
	 * @param Property $entity
455
	 */
456
	public function testCopy( Property $entity ) {
457
		$copy = $entity->copy();
458
459
		// The equality method alone is not enough since it does not check the IDs.
460
		$this->assertTrue( $entity->equals( $copy ) );
461
		$this->assertEquals( $entity->getId(), $copy->getId() );
462
463
		$this->assertNotSame( $entity, $copy );
464
	}
465
466
	public function testCopyRetainsLabels() {
467
		$property = Property::newFromType( 'string' );
468
469
		$property->getFingerprint()->setLabel( 'en', 'foo' );
470
		$property->getFingerprint()->setLabel( 'de', 'bar' );
471
472
		$newProperty = $property->copy();
473
474
		$this->assertTrue( $newProperty->getFingerprint()->getLabels()->hasTermForLanguage( 'en' ) );
475
		$this->assertTrue( $newProperty->getFingerprint()->getLabels()->hasTermForLanguage( 'de' ) );
476
	}
477
478
	/**
479
	 * @dataProvider instanceProvider
480
	 * @param Property $entity
481
	 */
482
	public function testSerialize( Property $entity ) {
483
		$string = serialize( $entity );
484
485
		$this->assertInternalType( 'string', $string );
486
487
		$instance = unserialize( $string );
488
489
		$this->assertTrue( $entity->equals( $instance ) );
490
		$this->assertEquals( $entity->getId(), $instance->getId() );
491
	}
492
493
	public function testWhenNoStuffIsSet_getFingerprintReturnsEmptyFingerprint() {
494
		$entity = $this->getNewEmpty();
495
496
		$this->assertEquals(
497
			new Fingerprint(),
498
			$entity->getFingerprint()
499
		);
500
	}
501
502
	public function testWhenLabelsAreSet_getFingerprintReturnsFingerprintWithLabels() {
503
		$entity = $this->getNewEmpty();
504
505
		$entity->setLabel( 'en', 'foo' );
506
		$entity->setLabel( 'de', 'bar' );
507
508
		$this->assertEquals(
509
			new Fingerprint(
510
				new TermList( array(
511
					new Term( 'en', 'foo' ),
512
					new Term( 'de', 'bar' ),
513
				) )
514
			),
515
			$entity->getFingerprint()
516
		);
517
	}
518
519
	public function testWhenTermsAreSet_getFingerprintReturnsFingerprintWithTerms() {
520
		$entity = $this->getNewEmpty();
521
522
		$entity->setLabel( 'en', 'foo' );
523
		$entity->setDescription( 'en', 'foo bar' );
524
		$entity->setAliases( 'en', array( 'foo', 'bar' ) );
525
526
		$this->assertEquals(
527
			new Fingerprint(
528
				new TermList( array(
529
					new Term( 'en', 'foo' ),
530
				) ),
531
				new TermList( array(
532
					new Term( 'en', 'foo bar' )
533
				) ),
534
				new AliasGroupList( array(
535
					new AliasGroup( 'en', array( 'foo', 'bar' ) )
536
				) )
537
			),
538
			$entity->getFingerprint()
539
		);
540
	}
541
542
	public function testGivenEmptyFingerprint_noTermsAreSet() {
543
		$entity = $this->getNewEmpty();
544
		$entity->setFingerprint( new Fingerprint() );
545
546
		$this->assertTrue( $entity->getFingerprint()->isEmpty() );
547
	}
548
549
	public function testGivenEmptyFingerprint_existingTermsAreRemoved() {
550
		$entity = $this->getNewEmpty();
551
552
		$entity->setLabel( 'en', 'foo' );
553
		$entity->setDescription( 'en', 'foo bar' );
554
		$entity->setAliases( 'en', array( 'foo', 'bar' ) );
555
556
		$entity->setFingerprint( new Fingerprint() );
557
558
		$this->assertTrue( $entity->getFingerprint()->isEmpty() );
559
	}
560
561
	public function testWhenSettingFingerprint_getFingerprintReturnsIt() {
562
		$fingerprint = new Fingerprint(
563
			new TermList( array(
564
				new Term( 'en', 'english label' ),
565
			) ),
566
			new TermList( array(
567
				new Term( 'en', 'english description' )
568
			) ),
569
			new AliasGroupList( array(
570
				new AliasGroup( 'en', array( 'first en alias', 'second en alias' ) )
571
			) )
572
		);
573
574
		$entity = $this->getNewEmpty();
575
		$entity->setFingerprint( $fingerprint );
576
		$newFingerprint = $entity->getFingerprint();
577
578
		$this->assertSame( $fingerprint, $newFingerprint );
579
	}
580
581
}
582