Passed
Push — langAssertions ( 0e6369...680829 )
by no
27:39 queued 24:23
created

ItemTest::testCloneIsEqualButNotIdentical()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 23
rs 9.0856
cc 1
eloc 17
nc 1
nop 2
1
<?php
2
3
namespace Wikibase\DataModel\Tests\Entity;
4
5
use Wikibase\DataModel\Entity\Item;
6
use Wikibase\DataModel\Entity\ItemId;
7
use Wikibase\DataModel\SiteLink;
8
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
9
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
10
use Wikibase\DataModel\Statement\Statement;
11
use Wikibase\DataModel\Statement\StatementList;
12
13
/**
14
 * @covers Wikibase\DataModel\Entity\Item
15
 * @covers Wikibase\DataModel\Entity\Entity
16
 *
17
 * Some tests for this class are located in ItemMultilangTextsTest,
18
 * ItemNewEmptyTest and ItemNewFromArrayTest.
19
 *
20
 * @since 0.1
21
 *
22
 * @group Wikibase
23
 * @group WikibaseItem
24
 * @group WikibaseDataModel
25
 * @group WikibaseItemTest
26
 *
27
 * @licence GNU GPL v2+
28
 * @author Jeroen De Dauw < [email protected] >
29
 * @author John Erling Blad < [email protected] >
30
 * @author Michał Łazowik
31
 */
32
class ItemTest extends EntityTest {
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\Tests\Entity\EntityTest has been deprecated with message: This test class is to be phased out, and should not be used from outside of the component!

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
33
34
	/**
35
	 * @see EntityTest::getNewEmpty
36
	 *
37
	 * @since 0.1
38
	 *
39
	 * @return Item
40
	 */
41
	protected function getNewEmpty() {
42
		return new Item();
43
	}
44
45
	public function testGetId() {
46
		$item = new Item();
47
		$this->assertNull( $item->getId() );
48
49
		$item->setId( new ItemId( 'Q1' ) );
50
		$this->assertEquals( new ItemId( 'Q1' ), $item->getId() );
51
52
		$item->setId( null );
53
		$this->assertNull( $item->getId() );
54
55
		$item = new Item( new ItemId( 'Q2' ) );
56
		$this->assertEquals( new ItemId( 'Q2' ), $item->getId() );
57
	}
58
59
	public function testSetIdUsingNumber() {
60
		$item = new Item();
61
		$item->setId( 42 );
62
		$this->assertEquals( new ItemId( 'Q42' ), $item->getId() );
63
	}
64
65
	public function testGetSiteLinkWithNonSetSiteId() {
66
		$item = new Item();
67
68
		$this->setExpectedException( 'OutOfBoundsException' );
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...
69
		$item->getSiteLinkList()->getBySiteId( 'enwiki' );
70
	}
71
72
	/**
73
	 * @dataProvider simpleSiteLinkProvider
74
	 */
75
	public function testAddSiteLink( SiteLink $siteLink ) {
76
		$item = new Item();
77
78
		$item->getSiteLinkList()->addSiteLink( $siteLink );
79
80
		$this->assertEquals(
81
			$siteLink,
82
			$item->getSiteLinkList()->getBySiteId( $siteLink->getSiteId() )
83
		);
84
	}
85
86
	public function simpleSiteLinkProvider() {
87
		$argLists = array();
88
89
		$argLists[] = array(
90
			new SiteLink(
91
				'enwiki',
92
				'Wikidata',
93
				array(
94
					new ItemId( 'Q42' )
95
				)
96
			)
97
		);
98
		$argLists[] = array(
99
			new SiteLink(
100
				'nlwiki',
101
				'Wikidata'
102
			)
103
		);
104
		$argLists[] = array(
105
			new SiteLink(
106
				'enwiki',
107
				'Nyan!',
108
				array(
109
					new ItemId( 'Q42' ),
110
					new ItemId( 'Q149' )
111
				)
112
			)
113
		);
114
		$argLists[] = array(
115
			new SiteLink(
116
				'foo bar',
117
				'baz bah',
118
				array(
119
					new ItemId( 'Q3' ),
120
					new ItemId( 'Q7' )
121
				)
122
			)
123
		);
124
125
		return $argLists;
126
	}
127
128
	/**
129
	 * @dataProvider simpleSiteLinksProvider
130
	 */
131
	public function testGetSiteLinks() {
132
		$siteLinks = func_get_args();
133
		$item = new Item();
134
135
		foreach ( $siteLinks as $siteLink ) {
136
			$item->getSiteLinkList()->addSiteLink( $siteLink );
137
		}
138
139
		$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...
140
		$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...
141
	}
142
143
	public function simpleSiteLinksProvider() {
144
		$argLists = array();
145
146
		$argLists[] = array();
147
148
		$argLists[] = array( new SiteLink( 'enwiki', 'Wikidata', array( new ItemId( 'Q42' ) ) ) );
149
150
		$argLists[] = array(
151
			new SiteLink( 'enwiki', 'Wikidata' ),
152
			new SiteLink( 'nlwiki', 'Wikidata', array( new ItemId( 'Q3' ) ) )
153
		);
154
155
		$argLists[] = array(
156
			new SiteLink( 'enwiki', 'Wikidata' ),
157
			new SiteLink( 'nlwiki', 'Wikidata' ),
158
			new SiteLink( 'foo bar', 'baz bah', array( new ItemId( 'Q2' ) ) )
159
		);
160
161
		return $argLists;
162
	}
163
164
	public function testHasLinkToSiteForFalse() {
165
		$item = new Item();
166
		$item->getSiteLinkList()->addNewSiteLink( 'ENWIKI', 'Wikidata', array( new ItemId( 'Q42' ) ) );
167
168
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'enwiki' ) );
169
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'dewiki' ) );
170
		$this->assertFalse( $item->getSiteLinkList()->hasLinkWithSiteId( 'foo bar' ) );
171
	}
172
173
	public function testHasLinkToSiteForTrue() {
174
		$item = new Item();
175
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Wikidata', array( new ItemId( 'Q42' ) ) );
176
		$item->getSiteLinkList()->addNewSiteLink( 'dewiki', 'Wikidata' );
177
		$item->getSiteLinkList()->addNewSiteLink( 'foo bar', 'Wikidata' );
178
179
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'enwiki' ) );
180
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'dewiki' ) );
181
		$this->assertTrue( $item->getSiteLinkList()->hasLinkWithSiteId( 'foo bar' ) );
182
	}
183
184
	public function testEmptyItemReturnsEmptySiteLinkList() {
185
		$item = new Item();
186
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
187
	}
188
189
	public function testAddSiteLinkOverridesOldLinks() {
190
		$item = new Item();
191
192
		$item->getSiteLinkList()->addNewSiteLink( 'kittens', 'foo' );
193
194
		$newLink = new SiteLink( 'kittens', 'bar' );
195
		$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...
196
197
		$this->assertTrue( $item->getSiteLinkList()->getBySiteId( 'kittens' )->equals( $newLink ) );
198
	}
199
200
	public function testEmptyItemIsEmpty() {
201
		$item = new Item();
202
		$this->assertTrue( $item->isEmpty() );
203
	}
204
205
	public function testItemWithIdIsEmpty() {
206
		$item = new Item( new ItemId( 'Q1337' ) );
207
		$this->assertTrue( $item->isEmpty() );
208
	}
209
210
	public function testItemWithStuffIsNotEmpty() {
211
		$item = new Item();
212
		$item->getFingerprint()->setAliasGroup( 'en', array( 'foo' ) );
213
		$this->assertFalse( $item->isEmpty() );
214
215
		$item = new Item();
216
		$item->getSiteLinkList()->addNewSiteLink( 'en', 'o_O' );
217
		$this->assertFalse( $item->isEmpty() );
218
219
		$item = new Item();
220
		$item->getStatements()->addStatement( $this->newStatement() );
221
		$this->assertFalse( $item->isEmpty() );
222
	}
223
224
	public function testItemWithSitelinksHasSitelinks() {
225
		$item = new Item();
226
		$item->getSiteLinkList()->addNewSiteLink( 'en', 'foo' );
227
		$this->assertFalse( $item->getSiteLinkList()->isEmpty() );
228
	}
229
230
	public function testItemWithoutSitelinksHasNoSitelinks() {
231
		$item = new Item();
232
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
233
	}
234
235
	private function newStatement() {
236
		$statement = new Statement( new PropertyNoValueSnak( 42 ) );
237
		$statement->setGuid( 'kittens' );
238
		return $statement;
239
	}
240
241
	public function testClearRemovesAllButId() {
242
		$item = new Item( new ItemId( 'Q42' ) );
243
		$item->getFingerprint()->setLabel( 'en', 'foo' );
244
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Foo' );
245
		$item->getStatements()->addStatement( $this->newStatement() );
246
247
		$item->clear();
248
249
		$this->assertEquals( new ItemId( 'Q42' ), $item->getId() );
250
		$this->assertTrue( $item->getFingerprint()->isEmpty() );
251
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
252
		$this->assertTrue( $item->getStatements()->isEmpty() );
253
	}
254
255
	public function testEmptyConstructor() {
256
		$item = new Item();
257
258
		$this->assertNull( $item->getId() );
259
		$this->assertTrue( $item->getFingerprint()->isEmpty() );
260
		$this->assertTrue( $item->getSiteLinkList()->isEmpty() );
261
		$this->assertTrue( $item->getStatements()->isEmpty() );
262
	}
263
264
	public function testCanConstructWithStatementList() {
265
		$statement = new Statement( new PropertyNoValueSnak( 42 ) );
266
		$statement->setGuid( 'meh' );
267
268
		$statements = new StatementList( $statement );
269
270
		$item = new Item( null, null, null, $statements );
271
272
		$this->assertEquals(
273
			$statements,
274
			$item->getStatements()
275
		);
276
	}
277
278
	public function testSetStatements() {
279
		$item = new Item();
280
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
281
282
		$item->setStatements( new StatementList() );
283
		$this->assertTrue( $item->getStatements()->isEmpty() );
284
	}
285
286
	public function testGetStatementsReturnsCorrectTypeAfterClear() {
287
		$item = new Item();
288
		$item->clear();
289
290
		$this->assertTrue( $item->getStatements()->isEmpty() );
291
	}
292
293
	public function equalsProvider() {
294
		$firstItem = new Item();
295
		$firstItem->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
296
297
		$secondItem = new Item();
298
		$secondItem->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
299
300
		$secondItemWithId = $secondItem->copy();
301
		$secondItemWithId->setId( 42 );
302
303
		$differentId = $secondItemWithId->copy();
304
		$differentId->setId( 43 );
305
306
		return array(
307
			array( new Item(), new Item() ),
308
			array( $firstItem, $secondItem ),
309
			array( $secondItem, $secondItemWithId ),
310
			array( $secondItemWithId, $differentId ),
311
		);
312
	}
313
314
	/**
315
	 * @dataProvider equalsProvider
316
	 */
317
	public function testEquals( Item $firstItem, Item $secondItem ) {
318
		$this->assertTrue( $firstItem->equals( $secondItem ) );
319
		$this->assertTrue( $secondItem->equals( $firstItem ) );
320
	}
321
322
	private function getBaseItem() {
323
		$item = new Item( new ItemId( 'Q42' ) );
324
		$item->getFingerprint()->setLabel( 'en', 'Same' );
325
		$item->getFingerprint()->setDescription( 'en', 'Same' );
326
		$item->getFingerprint()->setAliasGroup( 'en', array( 'Same' ) );
327
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Same' );
328
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 42 ) );
329
330
		return $item;
331
	}
332
333
	public function notEqualsProvider() {
334
		$differentLabel = $this->getBaseItem();
335
		$differentLabel->getFingerprint()->setLabel( 'en', 'Different' );
336
337
		$differentDescription = $this->getBaseItem();
338
		$differentDescription->getFingerprint()->setDescription( 'en', 'Different' );
339
340
		$differentAlias = $this->getBaseItem();
341
		$differentAlias->getFingerprint()->setAliasGroup( 'en', array( 'Different' ) );
342
343
		$differentSiteLink = $this->getBaseItem();
344
		$differentSiteLink->getSiteLinkList()->removeLinkWithSiteId( 'enwiki' );
345
		$differentSiteLink->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Different' );
346
347
		$differentStatement = $this->getBaseItem();
348
		$differentStatement->setStatements( new StatementList() );
349
		$differentStatement->getStatements()->addNewStatement( new PropertyNoValueSnak( 24 ) );
350
351
		$item = $this->getBaseItem();
352
353
		return array(
354
			'empty' => array( $item, new Item() ),
355
			'label' => array( $item, $differentLabel ),
356
			'description' => array( $item, $differentDescription ),
357
			'alias' => array( $item, $differentAlias ),
358
			'siteLink' => array( $item, $differentSiteLink ),
359
			'statement' => array( $item, $differentStatement ),
360
		);
361
	}
362
363
	/**
364
	 * @dataProvider notEqualsProvider
365
	 */
366
	public function testNotEquals( Item $firstItem, Item $secondItem ) {
367
		$this->assertFalse( $firstItem->equals( $secondItem ) );
368
		$this->assertFalse( $secondItem->equals( $firstItem ) );
369
	}
370
371
	public function cloneProvider() {
372
		$item = new Item( new ItemId( 'Q1' ) );
373
		$item->setLabel( 'en', 'original' );
374
		$item->getStatements()->addNewStatement( new PropertyNoValueSnak( 1 ) );
375
		$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Original' );
376
377
		return array(
378
			'copy' => array( $item, $item->copy() ),
379
			'native clone' => array( $item, clone $item ),
380
		);
381
	}
382
383
	/**
384
	 * @dataProvider cloneProvider
385
	 */
386
	public function testCloneIsEqualButNotIdentical( Item $original, Item $clone ) {
387
		$this->assertNotSame( $original, $clone );
388
		$this->assertTrue( $original->equals( $clone ) );
389
		$this->assertSame(
390
			$original->getId(),
391
			$clone->getId(),
392
			'id is immutable and must not be cloned'
393
		);
394
395
		// The clone must not reference the same mutable objects
396
		$this->assertNotSame( $original->getFingerprint(), $clone->getFingerprint() );
397
		$this->assertNotSame( $original->getStatements(), $clone->getStatements() );
398
		$this->assertNotSame(
399
			$original->getStatements()->getFirstStatementWithGuid( null ),
400
			$clone->getStatements()->getFirstStatementWithGuid( null )
401
		);
402
		$this->assertNotSame( $original->getSiteLinkList(), $clone->getSiteLinkList() );
403
		$this->assertSame(
404
			$original->getSiteLinkList()->getBySiteId( 'enwiki' ),
405
			$clone->getSiteLinkList()->getBySiteId( 'enwiki' ),
406
			'SiteLink is immutable and must not be cloned'
407
		);
408
	}
409
410
	/**
411
	 * @dataProvider cloneProvider
412
	 */
413
	public function testOriginalDoesNotChangeWithClone( Item $original, Item $clone ) {
414
		$originalStatement = $original->getStatements()->getFirstStatementWithGuid( null );
415
		$clonedStatement = $clone->getStatements()->getFirstStatementWithGuid( null );
416
417
		$clone->setLabel( 'en', 'clone' );
418
		$clone->setDescription( 'en', 'clone' );
419
		$clone->setAliases( 'en', array( 'clone' ) );
420
		$clonedStatement->setGuid( 'clone' );
421
		$clonedStatement->setMainSnak( new PropertySomeValueSnak( 666 ) );
422
		$clonedStatement->setRank( Statement::RANK_DEPRECATED );
423
		$clonedStatement->getQualifiers()->addSnak( new PropertyNoValueSnak( 1 ) );
424
		$clonedStatement->getReferences()->addNewReference( new PropertyNoValueSnak( 1 ) );
425
		$clone->getSiteLinkList()->removeLinkWithSiteId( 'enwiki' );
426
427
		$this->assertSame( 'original', $original->getFingerprint()->getLabel( 'en' )->getText() );
428
		$this->assertFalse( $original->getFingerprint()->hasDescription( 'en' ) );
429
		$this->assertFalse( $original->getFingerprint()->hasAliasGroup( 'en' ) );
430
		$this->assertNull( $originalStatement->getGuid() );
431
		$this->assertSame( 'novalue', $originalStatement->getMainSnak()->getType() );
432
		$this->assertSame( Statement::RANK_NORMAL, $originalStatement->getRank() );
433
		$this->assertTrue( $originalStatement->getQualifiers()->isEmpty() );
434
		$this->assertTrue( $originalStatement->getReferences()->isEmpty() );
435
		$this->assertFalse( $original->getSiteLinkList()->isEmpty() );
436
	}
437
438
}
439