Exclude redirects from Special:Fewestrevisions
[lhc/web/wiklou.git] / tests / phpunit / includes / registration / VersionCheckerTest.php
1 <?php
2
3 /**
4 * @covers VersionChecker
5 */
6 class VersionCheckerTest extends PHPUnit\Framework\TestCase {
7
8 use MediaWikiCoversValidator;
9 use PHPUnit4And6Compat;
10
11 /**
12 * @dataProvider provideMediaWikiCheck
13 */
14 public function testMediaWikiCheck( $coreVersion, $constraint, $expected ) {
15 $checker = new VersionChecker( $coreVersion, '7.0.0', [] );
16 $this->assertEquals( $expected, !(bool)$checker->checkArray( [
17 'FakeExtension' => [
18 'MediaWiki' => $constraint,
19 ],
20 ] ) );
21 }
22
23 public static function provideMediaWikiCheck() {
24 return [
25 // [ $wgVersion, constraint, expected ]
26 [ '1.25alpha', '>= 1.26', false ],
27 [ '1.25.0', '>= 1.26', false ],
28 [ '1.26alpha', '>= 1.26', true ],
29 [ '1.26alpha', '>= 1.26.0', true ],
30 [ '1.26alpha', '>= 1.26.0-stable', false ],
31 [ '1.26.0', '>= 1.26.0-stable', true ],
32 [ '1.26.1', '>= 1.26.0-stable', true ],
33 [ '1.27.1', '>= 1.26.0-stable', true ],
34 [ '1.26alpha', '>= 1.26.1', false ],
35 [ '1.26alpha', '>= 1.26alpha', true ],
36 [ '1.26alpha', '>= 1.25', true ],
37 [ '1.26.0-alpha.14', '>= 1.26.0-alpha.15', false ],
38 [ '1.26.0-alpha.14', '>= 1.26.0-alpha.10', true ],
39 [ '1.26.1', '>= 1.26.2, <=1.26.0', false ],
40 [ '1.26.1', '^1.26.2', false ],
41 // Accept anything for un-parsable version strings
42 [ '1.26mwf14', '== 1.25alpha', true ],
43 [ 'totallyinvalid', '== 1.0', true ],
44 ];
45 }
46
47 /**
48 * @dataProvider providePhpValidCheck
49 */
50 public function testPhpValidCheck( $phpVersion, $constraint, $expected ) {
51 $checker = new VersionChecker( '1.0.0', $phpVersion, [] );
52 $this->assertEquals( $expected, !(bool)$checker->checkArray( [
53 'FakeExtension' => [
54 'platform' => [
55 'php' => $constraint,
56 ],
57 ],
58 ] ) );
59 }
60
61 public static function providePhpValidCheck() {
62 return [
63 // [ phpVersion, constraint, expected ]
64 [ '7.0.23', '>= 7.0.0', true ],
65 [ '7.0.23', '^7.1.0', false ],
66 [ '7.0.23', '7.0.23', true ],
67 ];
68 }
69
70 /**
71 * @expectedException UnexpectedValueException
72 */
73 public function testPhpInvalidConstraint() {
74 $checker = new VersionChecker( '1.0.0', '7.0.0', [] );
75 $checker->checkArray( [
76 'FakeExtension' => [
77 'platform' => [
78 'php' => 'totallyinvalid',
79 ],
80 ],
81 ] );
82 }
83
84 /**
85 * @dataProvider providePhpInvalidVersion
86 * @expectedException UnexpectedValueException
87 */
88 public function testPhpInvalidVersion( $phpVersion ) {
89 $checker = new VersionChecker( '1.0.0', $phpVersion, [] );
90 }
91
92 public static function providePhpInvalidVersion() {
93 return [
94 // [ phpVersion ]
95 [ '7.abc' ],
96 [ '5.a.x' ],
97 ];
98 }
99
100 /**
101 * @dataProvider provideType
102 */
103 public function testType( $given, $expected ) {
104 $checker = new VersionChecker(
105 '1.0.0',
106 '7.0.0',
107 [ 'phpLoadedExtension' ],
108 [
109 'presentAbility' => true,
110 'presentAbilityWithMessage' => true,
111 'missingAbility' => false,
112 'missingAbilityWithMessage' => false,
113 ],
114 [
115 'presentAbilityWithMessage' => 'Present.',
116 'missingAbilityWithMessage' => 'Missing.',
117 ]
118 );
119 $checker->setLoadedExtensionsAndSkins( [
120 'FakeDependency' => [
121 'version' => '1.0.0',
122 ],
123 'NoVersionGiven' => [],
124 ] );
125 $this->assertEquals( $expected, $checker->checkArray( [
126 'FakeExtension' => $given,
127 ] ) );
128 }
129
130 public static function provideType() {
131 return [
132 // valid type
133 [
134 [
135 'extensions' => [
136 'FakeDependency' => '1.0.0',
137 ],
138 ],
139 [],
140 ],
141 [
142 [
143 'MediaWiki' => '1.0.0',
144 ],
145 [],
146 ],
147 [
148 [
149 'extensions' => [
150 'NoVersionGiven' => '*',
151 ],
152 ],
153 [],
154 ],
155 [
156 [
157 'extensions' => [
158 'NoVersionGiven' => '1.0',
159 ],
160 ],
161 [
162 [
163 'incompatible' => 'FakeExtension',
164 'type' => 'incompatible-extensions',
165 'msg' => 'NoVersionGiven does not expose its version, but FakeExtension requires: 1.0.',
166 ],
167 ],
168 ],
169 [
170 [
171 'extensions' => [
172 'Missing' => '*',
173 ],
174 ],
175 [
176 [
177 'missing' => 'Missing',
178 'type' => 'missing-extensions',
179 'msg' => 'FakeExtension requires Missing to be installed.',
180 ],
181 ],
182 ],
183 [
184 [
185 'extensions' => [
186 'FakeDependency' => '2.0.0',
187 ],
188 ],
189 [
190 [
191 'incompatible' => 'FakeExtension',
192 'type' => 'incompatible-extensions',
193 // phpcs:ignore Generic.Files.LineLength.TooLong
194 'msg' => 'FakeExtension is not compatible with the current installed version of FakeDependency (1.0.0), it requires: 2.0.0.',
195 ],
196 ],
197 ],
198 [
199 [
200 'skins' => [
201 'FakeSkin' => '*',
202 ],
203 ],
204 [
205 [
206 'missing' => 'FakeSkin',
207 'type' => 'missing-skins',
208 'msg' => 'FakeExtension requires FakeSkin to be installed.',
209 ],
210 ],
211 ],
212 [
213 [
214 'platform' => [
215 'ext-phpLoadedExtension' => '*',
216 ],
217 ],
218 [],
219 ],
220 [
221 [
222 'platform' => [
223 'ext-phpMissingExtension' => '*',
224 ],
225 ],
226 [
227 [
228 'missing' => 'phpMissingExtension',
229 'type' => 'missing-phpExtension',
230 // phpcs:ignore Generic.Files.LineLength.TooLong
231 'msg' => 'FakeExtension requires phpMissingExtension PHP extension to be installed.',
232 ],
233 ],
234 ],
235 [
236 [
237 'platform' => [
238 'ability-presentAbility' => true,
239 ],
240 ],
241 [],
242 ],
243 [
244 [
245 'platform' => [
246 'ability-presentAbilityWithMessage' => true,
247 ],
248 ],
249 [],
250 ],
251 [
252 [
253 'platform' => [
254 'ability-presentAbility' => false,
255 ],
256 ],
257 [],
258 ],
259 [
260 [
261 'platform' => [
262 'ability-presentAbilityWithMessage' => false,
263 ],
264 ],
265 [],
266 ],
267 [
268 [
269 'platform' => [
270 'ability-missingAbility' => true,
271 ],
272 ],
273 [
274 [
275 'missing' => 'missingAbility',
276 'type' => 'missing-ability',
277 'msg' => 'FakeExtension requires "missingAbility" ability',
278 ],
279 ],
280 ],
281 [
282 [
283 'platform' => [
284 'ability-missingAbilityWithMessage' => true,
285 ],
286 ],
287 [
288 [
289 'missing' => 'missingAbilityWithMessage',
290 'type' => 'missing-ability',
291 // phpcs:ignore Generic.Files.LineLength.TooLong
292 'msg' => 'FakeExtension requires "missingAbilityWithMessage" ability: Missing.',
293 ],
294 ],
295 ],
296 [
297 [
298 'platform' => [
299 'ability-missingAbility' => false,
300 ],
301 ],
302 [],
303 ],
304 [
305 [
306 'platform' => [
307 'ability-missingAbilityWithMessage' => false,
308 ],
309 ],
310 [],
311 ],
312 ];
313 }
314
315 /**
316 * Check, if a non-parsable version constraint does not throw an exception or
317 * returns any error message.
318 */
319 public function testInvalidConstraint() {
320 $checker = new VersionChecker( '1.0.0', '7.0.0', [] );
321 $checker->setLoadedExtensionsAndSkins( [
322 'FakeDependency' => [
323 'version' => 'not really valid',
324 ],
325 ] );
326 $this->assertEquals( [
327 [
328 'type' => 'invalid-version',
329 'msg' => "FakeDependency does not have a valid version string.",
330 ],
331 ], $checker->checkArray( [
332 'FakeExtension' => [
333 'extensions' => [
334 'FakeDependency' => '1.24.3',
335 ],
336 ],
337 ] ) );
338
339 $checker = new VersionChecker( '1.0.0', '7.0.0', [] );
340 $checker->setLoadedExtensionsAndSkins( [
341 'FakeDependency' => [
342 'version' => '1.24.3',
343 ],
344 ] );
345
346 $this->setExpectedException( UnexpectedValueException::class );
347 $checker->checkArray( [
348 'FakeExtension' => [
349 'FakeDependency' => 'not really valid',
350 ],
351 ] );
352 }
353
354 public function provideInvalidDependency() {
355 return [
356 [
357 [
358 'FakeExtension' => [
359 'platform' => [
360 'undefinedPlatformDependency' => '*',
361 ],
362 ],
363 ],
364 'undefinedPlatformDependency',
365 ],
366 [
367 [
368 'FakeExtension' => [
369 'platform' => [
370 'phpLoadedExtension' => '*',
371 ],
372 ],
373 ],
374 'phpLoadedExtension',
375 ],
376 [
377 [
378 'FakeExtension' => [
379 'platform' => [
380 'ability-invalidAbility' => true,
381 ],
382 ],
383 ],
384 'ability-invalidAbility',
385 ],
386 [
387 [
388 'FakeExtension' => [
389 'platform' => [
390 'presentAbility' => true,
391 ],
392 ],
393 ],
394 'presentAbility',
395 ],
396 [
397 [
398 'FakeExtension' => [
399 'undefinedDependencyType' => '*',
400 ],
401 ],
402 'undefinedDependencyType',
403 ],
404 // T197478
405 [
406 [
407 'FakeExtension' => [
408 'skin' => [
409 'FakeSkin' => '*',
410 ],
411 ],
412 ],
413 'skin',
414 ],
415 ];
416 }
417
418 /**
419 * @dataProvider provideInvalidDependency
420 */
421 public function testInvalidDependency( $depencency, $type ) {
422 $checker = new VersionChecker(
423 '1.0.0',
424 '7.0.0',
425 [ 'phpLoadedExtension' ],
426 [
427 'presentAbility' => true,
428 'missingAbility' => false,
429 ]
430 );
431 $this->setExpectedException(
432 UnexpectedValueException::class,
433 "Dependency type $type unknown in FakeExtension"
434 );
435 $checker->checkArray( $depencency );
436 }
437
438 public function testInvalidPhpExtensionConstraint() {
439 $checker = new VersionChecker( '1.0.0', '7.0.0', [ 'phpLoadedExtension' ] );
440 $this->setExpectedException(
441 UnexpectedValueException::class,
442 'Version constraints for PHP extensions are not supported in FakeExtension'
443 );
444 $checker->checkArray( [
445 'FakeExtension' => [
446 'platform' => [
447 'ext-phpLoadedExtension' => '1.0.0',
448 ],
449 ],
450 ] );
451 }
452
453 /**
454 * @dataProvider provideInvalidAbilityType
455 */
456 public function testInvalidAbilityType( $value ) {
457 $checker = new VersionChecker( '1.0.0', '7.0.0', [], [ 'presentAbility' => true ] );
458 $this->setExpectedException(
459 UnexpectedValueException::class,
460 'Only booleans are allowed to to indicate the presence of abilities in FakeExtension'
461 );
462 $checker->checkArray( [
463 'FakeExtension' => [
464 'platform' => [
465 'ability-presentAbility' => $value,
466 ],
467 ],
468 ] );
469 }
470
471 public function provideInvalidAbilityType() {
472 return [
473 [ null ],
474 [ 1 ],
475 [ '1' ],
476 ];
477 }
478
479 }