1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Wikibase\DataModel\Tests\Entity; |
4
|
|
|
|
5
|
|
|
use PHPUnit_Framework_TestCase; |
6
|
|
|
use Wikibase\DataModel\Entity\ItemId; |
7
|
|
|
use InvalidArgumentException; |
8
|
|
|
use RuntimeException; |
9
|
|
|
use Wikimedia\Assert\ParameterAssertionException; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* @covers Wikibase\DataModel\Entity\ItemId |
13
|
|
|
* @covers Wikibase\DataModel\Entity\EntityId |
14
|
|
|
* |
15
|
|
|
* @group Wikibase |
16
|
|
|
* @group WikibaseDataModel |
17
|
|
|
* |
18
|
|
|
* @license GPL-2.0+ |
19
|
|
|
* @author Jeroen De Dauw < [email protected] > |
20
|
|
|
*/ |
21
|
|
|
class ItemIdTest extends PHPUnit_Framework_TestCase { |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @dataProvider idSerializationProvider |
25
|
|
|
*/ |
26
|
|
|
public function testCanConstructId( $idSerialization, $normalizedIdSerialization ) { |
27
|
|
|
$id = new ItemId( $idSerialization ); |
28
|
|
|
|
29
|
|
|
$this->assertEquals( |
30
|
|
|
$normalizedIdSerialization, |
31
|
|
|
$id->getSerialization() |
32
|
|
|
); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
public function idSerializationProvider() { |
36
|
|
|
return [ |
37
|
|
|
[ 'q1', 'Q1' ], |
38
|
|
|
[ 'q100', 'Q100' ], |
39
|
|
|
[ 'q1337', 'Q1337' ], |
40
|
|
|
[ 'q31337', 'Q31337' ], |
41
|
|
|
[ 'Q31337', 'Q31337' ], |
42
|
|
|
[ 'Q42', 'Q42' ], |
43
|
|
|
[ ':Q42', 'Q42' ], |
44
|
|
|
[ 'foo:Q42', 'foo:Q42' ], |
45
|
|
|
[ 'foo:bar:q42', 'foo:bar:Q42' ], |
46
|
|
|
[ 'Q2147483647', 'Q2147483647' ], |
47
|
|
|
]; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @dataProvider invalidIdSerializationProvider |
52
|
|
|
*/ |
53
|
|
|
public function testCannotConstructWithInvalidSerialization( $invalidSerialization ) { |
54
|
|
|
$this->setExpectedException( InvalidArgumentException::class ); |
|
|
|
|
55
|
|
|
new ItemId( $invalidSerialization ); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function invalidIdSerializationProvider() { |
59
|
|
|
return [ |
60
|
|
|
[ "Q1\n" ], |
61
|
|
|
[ 'q' ], |
62
|
|
|
[ 'p1' ], |
63
|
|
|
[ 'qq1' ], |
64
|
|
|
[ '1q' ], |
65
|
|
|
[ 'q01' ], |
66
|
|
|
[ 'q 1' ], |
67
|
|
|
[ ' q1' ], |
68
|
|
|
[ 'q1 ' ], |
69
|
|
|
[ '1' ], |
70
|
|
|
[ ' ' ], |
71
|
|
|
[ '' ], |
72
|
|
|
[ '0' ], |
73
|
|
|
[ 0 ], |
74
|
|
|
[ 1 ], |
75
|
|
|
[ 'Q2147483648' ], |
76
|
|
|
[ 'Q99999999999' ], |
77
|
|
|
]; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function testGetNumericId() { |
81
|
|
|
$id = new ItemId( 'Q1' ); |
82
|
|
|
$this->assertSame( 1, $id->getNumericId() ); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function testGetEntityType() { |
86
|
|
|
$id = new ItemId( 'Q1' ); |
87
|
|
|
$this->assertSame( 'item', $id->getEntityType() ); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function testSerialize() { |
91
|
|
|
$id = new ItemId( 'Q1' ); |
92
|
|
|
$this->assertSame( '["item","Q1"]', $id->serialize() ); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @dataProvider serializationProvider |
97
|
|
|
*/ |
98
|
|
|
public function testUnserialize( $json, $expected ) { |
99
|
|
|
$id = new ItemId( 'Q1' ); |
100
|
|
|
$id->unserialize( $json ); |
101
|
|
|
$this->assertSame( $expected, $id->getSerialization() ); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
public function serializationProvider() { |
105
|
|
|
return [ |
106
|
|
|
[ '["item","Q2"]', 'Q2' ], |
107
|
|
|
|
108
|
|
|
// All these cases are kind of an injection vector and allow constructing invalid ids. |
109
|
|
|
[ '["string","Q2"]', 'Q2' ], |
110
|
|
|
[ '["","string"]', 'string' ], |
111
|
|
|
[ '["",""]', '' ], |
112
|
|
|
[ '["",2]', 2 ], |
113
|
|
|
[ '["",null]', null ], |
114
|
|
|
[ '', null ], |
115
|
|
|
]; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @dataProvider numericIdProvider |
120
|
|
|
*/ |
121
|
|
|
public function testNewFromNumber( $number ) { |
122
|
|
|
$id = ItemId::newFromNumber( $number ); |
123
|
|
|
$this->assertEquals( 'Q' . $number, $id->getSerialization() ); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
public function numericIdProvider() { |
127
|
|
|
return [ |
128
|
|
|
[ 42 ], |
129
|
|
|
[ '42' ], |
130
|
|
|
[ 42.0 ], |
131
|
|
|
// Check for 32-bit integer overflow on 32-bit PHP systems. |
132
|
|
|
[ 2147483647 ], |
133
|
|
|
[ '2147483647' ], |
134
|
|
|
]; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
public function testNewFromNumberWithRepositoryName() { |
138
|
|
|
$id = ItemId::newFromNumber( 123, 'foo' ); |
139
|
|
|
$this->assertEquals( 'foo:Q123', $id->getSerialization() ); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @dataProvider invalidNumericIdProvider |
144
|
|
|
*/ |
145
|
|
|
public function testNewFromNumberWithInvalidNumericId( $number ) { |
146
|
|
|
$this->setExpectedException( InvalidArgumentException::class ); |
|
|
|
|
147
|
|
|
ItemId::newFromNumber( $number ); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function invalidNumericIdProvider() { |
151
|
|
|
return [ |
152
|
|
|
[ 'Q1' ], |
153
|
|
|
[ '42.1' ], |
154
|
|
|
[ 42.1 ], |
155
|
|
|
[ 2147483648 ], |
156
|
|
|
[ '2147483648' ], |
157
|
|
|
]; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* @dataProvider provideInvalidRepositoryNames |
162
|
|
|
*/ |
163
|
|
|
public function testNewFromNumberThrowsExceptionOnInvalidRepositoryName( $repositoryName ) { |
164
|
|
|
$this->setExpectedException( ParameterAssertionException::class ); |
|
|
|
|
165
|
|
|
ItemId::newFromNumber( 123, $repositoryName ); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
public function provideInvalidRepositoryNames() { |
169
|
|
|
return [ |
170
|
|
|
[ 'fo:o' ], |
171
|
|
|
[ ':' ], |
172
|
|
|
[ 100 ], |
173
|
|
|
[ false ], |
174
|
|
|
[ null ], |
175
|
|
|
]; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
public function testGetNumericIdThrowsExceptionOnForeignIds() { |
179
|
|
|
$this->setExpectedException( RuntimeException::class ); |
|
|
|
|
180
|
|
|
( new ItemId( 'foo:Q42' ) )->getNumericId(); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
} |
184
|
|
|
|
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.