f8de1ad964bf372acc55b617e6c982a90d309ab4
[lhc/web/wiklou.git] / tests / phpunit / includes / MWNamespaceTest.php
1 <?php
2 /**
3 * @author Antoine Musso
4 * @copyright Copyright © 2011, Antoine Musso
5 * @file
6 */
7
8 /**
9 * Test class for MWNamespace.
10 * Generated by PHPUnit on 2011-02-20 at 21:01:55.
11 * @todo covers tags
12 * @todo FIXME: this test file is a mess
13 */
14 class MWNamespaceTest extends MediaWikiTestCase {
15 protected function setUp() {
16 parent::setUp();
17
18 $this->setMwGlobals( [
19 'wgContentNamespaces' => [ NS_MAIN ],
20 'wgNamespacesWithSubpages' => [
21 NS_TALK => true,
22 NS_USER => true,
23 NS_USER_TALK => true,
24 ],
25 'wgCapitalLinks' => true,
26 'wgCapitalLinkOverrides' => [],
27 'wgNonincludableNamespaces' => [],
28 ] );
29 }
30
31 # ### START OF TESTS #########################################################
32
33 /**
34 * @todo Write more texts, handle $wgAllowImageMoving setting
35 * @covers MWNamespace::isMovable
36 */
37 public function testIsMovable() {
38 $this->assertFalse( MWNamespace::isMovable( NS_SPECIAL ) );
39 # @todo FIXME: Write more tests!!
40 }
41
42 /**
43 * Please make sure to change testIsTalk() if you change the assertions below
44 * @covers MWNamespace::isSubject
45 */
46 public function testIsSubject() {
47 // Special namespaces
48 $this->assertIsSubject( NS_MEDIA );
49 $this->assertIsSubject( NS_SPECIAL );
50
51 // Subject pages
52 $this->assertIsSubject( NS_MAIN );
53 $this->assertIsSubject( NS_USER );
54 $this->assertIsSubject( 100 ); # user defined
55
56 // Talk pages
57 $this->assertIsNotSubject( NS_TALK );
58 $this->assertIsNotSubject( NS_USER_TALK );
59 $this->assertIsNotSubject( 101 ); # user defined
60 }
61
62 /**
63 * Reverse of testIsSubject().
64 * Please update testIsSubject() if you change assertions below
65 * @covers MWNamespace::isTalk
66 */
67 public function testIsTalk() {
68 // Special namespaces
69 $this->assertIsNotTalk( NS_MEDIA );
70 $this->assertIsNotTalk( NS_SPECIAL );
71
72 // Subject pages
73 $this->assertIsNotTalk( NS_MAIN );
74 $this->assertIsNotTalk( NS_USER );
75 $this->assertIsNotTalk( 100 ); # user defined
76
77 // Talk pages
78 $this->assertIsTalk( NS_TALK );
79 $this->assertIsTalk( NS_USER_TALK );
80 $this->assertIsTalk( 101 ); # user defined
81 }
82
83 /**
84 * @covers MWNamespace::getSubject
85 */
86 public function testGetSubject() {
87 // Special namespaces are their own subjects
88 $this->assertEquals( NS_MEDIA, MWNamespace::getSubject( NS_MEDIA ) );
89 $this->assertEquals( NS_SPECIAL, MWNamespace::getSubject( NS_SPECIAL ) );
90
91 $this->assertEquals( NS_MAIN, MWNamespace::getSubject( NS_TALK ) );
92 $this->assertEquals( NS_USER, MWNamespace::getSubject( NS_USER_TALK ) );
93 }
94
95 /**
96 * Regular getTalk() calls
97 * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in
98 * the function testGetTalkExceptions()
99 * @covers MWNamespace::getTalk
100 */
101 public function testGetTalk() {
102 $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_MAIN ) );
103 $this->assertEquals( NS_TALK, MWNamespace::getTalk( NS_TALK ) );
104 $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER ) );
105 $this->assertEquals( NS_USER_TALK, MWNamespace::getTalk( NS_USER_TALK ) );
106 }
107
108 /**
109 * Exceptions with getTalk()
110 * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them.
111 * @expectedException MWException
112 * @covers MWNamespace::getTalk
113 */
114 public function testGetTalkExceptionsForNsMedia() {
115 $this->assertNull( MWNamespace::getTalk( NS_MEDIA ) );
116 }
117
118 /**
119 * Exceptions with getTalk()
120 * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them.
121 * @expectedException MWException
122 * @covers MWNamespace::getTalk
123 */
124 public function testGetTalkExceptionsForNsSpecial() {
125 $this->assertNull( MWNamespace::getTalk( NS_SPECIAL ) );
126 }
127
128 /**
129 * Regular getAssociated() calls
130 * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in
131 * the function testGetAssociatedExceptions()
132 * @covers MWNamespace::getAssociated
133 */
134 public function testGetAssociated() {
135 $this->assertEquals( NS_TALK, MWNamespace::getAssociated( NS_MAIN ) );
136 $this->assertEquals( NS_MAIN, MWNamespace::getAssociated( NS_TALK ) );
137 }
138
139 # ## Exceptions with getAssociated()
140 # ## NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises
141 # ## an exception for them.
142 /**
143 * @expectedException MWException
144 * @covers MWNamespace::getAssociated
145 */
146 public function testGetAssociatedExceptionsForNsMedia() {
147 $this->assertNull( MWNamespace::getAssociated( NS_MEDIA ) );
148 }
149
150 /**
151 * @expectedException MWException
152 * @covers MWNamespace::getAssociated
153 */
154 public function testGetAssociatedExceptionsForNsSpecial() {
155 $this->assertNull( MWNamespace::getAssociated( NS_SPECIAL ) );
156 }
157
158 /**
159 * @todo Implement testExists().
160 */
161 /*
162 public function testExists() {
163 // Remove the following lines when you implement this test.
164 $this->markTestIncomplete(
165 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
166 );
167 }
168 */
169
170 /**
171 * Test MWNamespace::equals
172 * Note if we add a namespace registration system with keys like 'MAIN'
173 * we should add tests here for equivilance on things like 'MAIN' == 0
174 * and 'MAIN' == NS_MAIN.
175 * @covers MWNamespace::equals
176 */
177 public function testEquals() {
178 $this->assertTrue( MWNamespace::equals( NS_MAIN, NS_MAIN ) );
179 $this->assertTrue( MWNamespace::equals( NS_MAIN, 0 ) ); // In case we make NS_MAIN 'MAIN'
180 $this->assertTrue( MWNamespace::equals( NS_USER, NS_USER ) );
181 $this->assertTrue( MWNamespace::equals( NS_USER, 2 ) );
182 $this->assertTrue( MWNamespace::equals( NS_USER_TALK, NS_USER_TALK ) );
183 $this->assertTrue( MWNamespace::equals( NS_SPECIAL, NS_SPECIAL ) );
184 $this->assertFalse( MWNamespace::equals( NS_MAIN, NS_TALK ) );
185 $this->assertFalse( MWNamespace::equals( NS_USER, NS_USER_TALK ) );
186 $this->assertFalse( MWNamespace::equals( NS_PROJECT, NS_TEMPLATE ) );
187 }
188
189 /**
190 * @covers MWNamespace::subjectEquals
191 */
192 public function testSubjectEquals() {
193 $this->assertSameSubject( NS_MAIN, NS_MAIN );
194 $this->assertSameSubject( NS_MAIN, 0 ); // In case we make NS_MAIN 'MAIN'
195 $this->assertSameSubject( NS_USER, NS_USER );
196 $this->assertSameSubject( NS_USER, 2 );
197 $this->assertSameSubject( NS_USER_TALK, NS_USER_TALK );
198 $this->assertSameSubject( NS_SPECIAL, NS_SPECIAL );
199 $this->assertSameSubject( NS_MAIN, NS_TALK );
200 $this->assertSameSubject( NS_USER, NS_USER_TALK );
201
202 $this->assertDifferentSubject( NS_PROJECT, NS_TEMPLATE );
203 $this->assertDifferentSubject( NS_SPECIAL, NS_MAIN );
204 }
205
206 /**
207 * @covers MWNamespace::subjectEquals
208 */
209 public function testSpecialAndMediaAreDifferentSubjects() {
210 $this->assertDifferentSubject(
211 NS_MEDIA, NS_SPECIAL,
212 "NS_MEDIA and NS_SPECIAL are different subject namespaces"
213 );
214 $this->assertDifferentSubject(
215 NS_SPECIAL, NS_MEDIA,
216 "NS_SPECIAL and NS_MEDIA are different subject namespaces"
217 );
218 }
219
220 /**
221 * @todo Implement testGetCanonicalNamespaces().
222 */
223 /*
224 public function testGetCanonicalNamespaces() {
225 // Remove the following lines when you implement this test.
226 $this->markTestIncomplete(
227 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
228 );
229 }
230 */
231 /**
232 * @todo Implement testGetCanonicalName().
233 */
234 /*
235 public function testGetCanonicalName() {
236 // Remove the following lines when you implement this test.
237 $this->markTestIncomplete(
238 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
239 );
240 }
241 */
242 /**
243 * @todo Implement testGetCanonicalIndex().
244 */
245 /*
246 public function testGetCanonicalIndex() {
247 // Remove the following lines when you implement this test.
248 $this->markTestIncomplete(
249 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
250 );
251 }
252 */
253
254 /**
255 * @todo Implement testGetValidNamespaces().
256 */
257 /*
258 public function testGetValidNamespaces() {
259 // Remove the following lines when you implement this test.
260 $this->markTestIncomplete(
261 'This test has not been implemented yet. Rely on $wgCanonicalNamespaces.'
262 );
263 }
264 */
265
266 /**
267 * @covers MWNamespace::canTalk
268 */
269 public function testCanTalk() {
270 $this->assertCanNotTalk( NS_MEDIA );
271 $this->assertCanNotTalk( NS_SPECIAL );
272
273 $this->assertCanTalk( NS_MAIN );
274 $this->assertCanTalk( NS_TALK );
275 $this->assertCanTalk( NS_USER );
276 $this->assertCanTalk( NS_USER_TALK );
277
278 // User defined namespaces
279 $this->assertCanTalk( 100 );
280 $this->assertCanTalk( 101 );
281 }
282
283 /**
284 * @covers MWNamespace::isContent
285 */
286 public function testIsContent() {
287 // NS_MAIN is a content namespace per DefaultSettings.php
288 // and per function definition.
289
290 $this->assertIsContent( NS_MAIN );
291
292 // Other namespaces which are not expected to be content
293
294 $this->assertIsNotContent( NS_MEDIA );
295 $this->assertIsNotContent( NS_SPECIAL );
296 $this->assertIsNotContent( NS_TALK );
297 $this->assertIsNotContent( NS_USER );
298 $this->assertIsNotContent( NS_CATEGORY );
299 $this->assertIsNotContent( 100 );
300 }
301
302 /**
303 * Similar to testIsContent() but alters the $wgContentNamespaces
304 * global variable.
305 * @covers MWNamespace::isContent
306 */
307 public function testIsContentAdvanced() {
308 global $wgContentNamespaces;
309
310 // Test that user defined namespace #252 is not content
311 $this->assertIsNotContent( 252 );
312
313 // Bless namespace # 252 as a content namespace
314 $wgContentNamespaces[] = 252;
315
316 $this->assertIsContent( 252 );
317
318 // Makes sure NS_MAIN was not impacted
319 $this->assertIsContent( NS_MAIN );
320 }
321
322 /**
323 * @covers MWNamespace::isWatchable
324 */
325 public function testIsWatchable() {
326 // Specials namespaces are not watchable
327 $this->assertIsNotWatchable( NS_MEDIA );
328 $this->assertIsNotWatchable( NS_SPECIAL );
329
330 // Core defined namespaces are watchables
331 $this->assertIsWatchable( NS_MAIN );
332 $this->assertIsWatchable( NS_TALK );
333
334 // Additional, user defined namespaces are watchables
335 $this->assertIsWatchable( 100 );
336 $this->assertIsWatchable( 101 );
337 }
338
339 /**
340 * @covers MWNamespace::hasSubpages
341 */
342 public function testHasSubpages() {
343 global $wgNamespacesWithSubpages;
344
345 // Special namespaces:
346 $this->assertHasNotSubpages( NS_MEDIA );
347 $this->assertHasNotSubpages( NS_SPECIAL );
348
349 // Namespaces without subpages
350 $this->assertHasNotSubpages( NS_MAIN );
351
352 $wgNamespacesWithSubpages[NS_MAIN] = true;
353 $this->assertHasSubpages( NS_MAIN );
354
355 $wgNamespacesWithSubpages[NS_MAIN] = false;
356 $this->assertHasNotSubpages( NS_MAIN );
357
358 // Some namespaces with subpages
359 $this->assertHasSubpages( NS_TALK );
360 $this->assertHasSubpages( NS_USER );
361 $this->assertHasSubpages( NS_USER_TALK );
362 }
363
364 /**
365 * @covers MWNamespace::getContentNamespaces
366 */
367 public function testGetContentNamespaces() {
368 global $wgContentNamespaces;
369
370 $this->assertEquals(
371 [ NS_MAIN ],
372 MWNamespace::getContentNamespaces(),
373 '$wgContentNamespaces is an array with only NS_MAIN by default'
374 );
375
376 # test !is_array( $wgcontentNamespaces )
377 $wgContentNamespaces = '';
378 $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
379
380 $wgContentNamespaces = false;
381 $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
382
383 $wgContentNamespaces = null;
384 $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
385
386 $wgContentNamespaces = 5;
387 $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
388
389 # test $wgContentNamespaces === []
390 $wgContentNamespaces = [];
391 $this->assertEquals( [ NS_MAIN ], MWNamespace::getContentNamespaces() );
392
393 # test !in_array( NS_MAIN, $wgContentNamespaces )
394 $wgContentNamespaces = [ NS_USER, NS_CATEGORY ];
395 $this->assertEquals(
396 [ NS_MAIN, NS_USER, NS_CATEGORY ],
397 MWNamespace::getContentNamespaces(),
398 'NS_MAIN is forced in $wgContentNamespaces even if unwanted'
399 );
400
401 # test other cases, return $wgcontentNamespaces as is
402 $wgContentNamespaces = [ NS_MAIN ];
403 $this->assertEquals(
404 [ NS_MAIN ],
405 MWNamespace::getContentNamespaces()
406 );
407
408 $wgContentNamespaces = [ NS_MAIN, NS_USER, NS_CATEGORY ];
409 $this->assertEquals(
410 [ NS_MAIN, NS_USER, NS_CATEGORY ],
411 MWNamespace::getContentNamespaces()
412 );
413 }
414
415 /**
416 * @covers MWNamespace::getSubjectNamespaces
417 */
418 public function testGetSubjectNamespaces() {
419 $subjectsNS = MWNamespace::getSubjectNamespaces();
420 $this->assertContains( NS_MAIN, $subjectsNS,
421 "Talk namespaces should have NS_MAIN" );
422 $this->assertNotContains( NS_TALK, $subjectsNS,
423 "Talk namespaces should have NS_TALK" );
424
425 $this->assertNotContains( NS_MEDIA, $subjectsNS,
426 "Talk namespaces should not have NS_MEDIA" );
427 $this->assertNotContains( NS_SPECIAL, $subjectsNS,
428 "Talk namespaces should not have NS_SPECIAL" );
429 }
430
431 /**
432 * @covers MWNamespace::getTalkNamespaces
433 */
434 public function testGetTalkNamespaces() {
435 $talkNS = MWNamespace::getTalkNamespaces();
436 $this->assertContains( NS_TALK, $talkNS,
437 "Subject namespaces should have NS_TALK" );
438 $this->assertNotContains( NS_MAIN, $talkNS,
439 "Subject namespaces should not have NS_MAIN" );
440
441 $this->assertNotContains( NS_MEDIA, $talkNS,
442 "Subject namespaces should not have NS_MEDIA" );
443 $this->assertNotContains( NS_SPECIAL, $talkNS,
444 "Subject namespaces should not have NS_SPECIAL" );
445 }
446
447 /**
448 * Some namespaces are always capitalized per code definition
449 * in MWNamespace::$alwaysCapitalizedNamespaces
450 * @covers MWNamespace::isCapitalized
451 */
452 public function testIsCapitalizedHardcodedAssertions() {
453 // NS_MEDIA and NS_FILE are treated the same
454 $this->assertEquals(
455 MWNamespace::isCapitalized( NS_MEDIA ),
456 MWNamespace::isCapitalized( NS_FILE ),
457 'NS_MEDIA and NS_FILE have same capitalization rendering'
458 );
459
460 // Boths are capitalized by default
461 $this->assertIsCapitalized( NS_MEDIA );
462 $this->assertIsCapitalized( NS_FILE );
463
464 // Always capitalized namespaces
465 // @see MWNamespace::$alwaysCapitalizedNamespaces
466 $this->assertIsCapitalized( NS_SPECIAL );
467 $this->assertIsCapitalized( NS_USER );
468 $this->assertIsCapitalized( NS_MEDIAWIKI );
469 }
470
471 /**
472 * Follows up for testIsCapitalizedHardcodedAssertions() but alter the
473 * global $wgCapitalLink setting to have extended coverage.
474 *
475 * MWNamespace::isCapitalized() rely on two global settings:
476 * $wgCapitalLinkOverrides = []; by default
477 * $wgCapitalLinks = true; by default
478 * This function test $wgCapitalLinks
479 *
480 * Global setting correctness is tested against the NS_PROJECT and
481 * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials
482 * @covers MWNamespace::isCapitalized
483 */
484 public function testIsCapitalizedWithWgCapitalLinks() {
485 global $wgCapitalLinks;
486
487 $this->assertIsCapitalized( NS_PROJECT );
488 $this->assertIsCapitalized( NS_PROJECT_TALK );
489
490 $wgCapitalLinks = false;
491
492 // hardcoded namespaces (see above function) are still capitalized:
493 $this->assertIsCapitalized( NS_SPECIAL );
494 $this->assertIsCapitalized( NS_USER );
495 $this->assertIsCapitalized( NS_MEDIAWIKI );
496
497 // setting is correctly applied
498 $this->assertIsNotCapitalized( NS_PROJECT );
499 $this->assertIsNotCapitalized( NS_PROJECT_TALK );
500 }
501
502 /**
503 * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now
504 * testing the $wgCapitalLinkOverrides global.
505 *
506 * @todo split groups of assertions in autonomous testing functions
507 * @covers MWNamespace::isCapitalized
508 */
509 public function testIsCapitalizedWithWgCapitalLinkOverrides() {
510 global $wgCapitalLinkOverrides;
511
512 // Test default settings
513 $this->assertIsCapitalized( NS_PROJECT );
514 $this->assertIsCapitalized( NS_PROJECT_TALK );
515
516 // hardcoded namespaces (see above function) are capitalized:
517 $this->assertIsCapitalized( NS_SPECIAL );
518 $this->assertIsCapitalized( NS_USER );
519 $this->assertIsCapitalized( NS_MEDIAWIKI );
520
521 // Hardcoded namespaces remains capitalized
522 $wgCapitalLinkOverrides[NS_SPECIAL] = false;
523 $wgCapitalLinkOverrides[NS_USER] = false;
524 $wgCapitalLinkOverrides[NS_MEDIAWIKI] = false;
525
526 $this->assertIsCapitalized( NS_SPECIAL );
527 $this->assertIsCapitalized( NS_USER );
528 $this->assertIsCapitalized( NS_MEDIAWIKI );
529
530 $wgCapitalLinkOverrides[NS_PROJECT] = false;
531 $this->assertIsNotCapitalized( NS_PROJECT );
532
533 $wgCapitalLinkOverrides[NS_PROJECT] = true;
534 $this->assertIsCapitalized( NS_PROJECT );
535
536 unset( $wgCapitalLinkOverrides[NS_PROJECT] );
537 $this->assertIsCapitalized( NS_PROJECT );
538 }
539
540 /**
541 * @covers MWNamespace::hasGenderDistinction
542 */
543 public function testHasGenderDistinction() {
544 // Namespaces with gender distinctions
545 $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER ) );
546 $this->assertTrue( MWNamespace::hasGenderDistinction( NS_USER_TALK ) );
547
548 // Other ones, "genderless"
549 $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MEDIA ) );
550 $this->assertFalse( MWNamespace::hasGenderDistinction( NS_SPECIAL ) );
551 $this->assertFalse( MWNamespace::hasGenderDistinction( NS_MAIN ) );
552 $this->assertFalse( MWNamespace::hasGenderDistinction( NS_TALK ) );
553 }
554
555 /**
556 * @covers MWNamespace::isNonincludable
557 */
558 public function testIsNonincludable() {
559 global $wgNonincludableNamespaces;
560
561 $wgNonincludableNamespaces = [ NS_USER ];
562
563 $this->assertTrue( MWNamespace::isNonincludable( NS_USER ) );
564 $this->assertFalse( MWNamespace::isNonincludable( NS_TEMPLATE ) );
565 }
566
567 # ###### HELPERS ###########################################################
568 function __call( $method, $args ) {
569 // Call the real method if it exists
570 if ( method_exists( $this, $method ) ) {
571 return $this->$method( $args );
572 }
573
574 if ( preg_match(
575 '/^assert(Has|Is|Can)(Not|)(Subject|Talk|Watchable|Content|Subpages|Capitalized)$/',
576 $method,
577 $m
578 ) ) {
579 # Interprets arguments:
580 $ns = $args[0];
581 $msg = isset( $args[1] ) ? $args[1] : " dummy message";
582
583 # Forge the namespace constant name:
584 if ( $ns === 0 ) {
585 $ns_name = "NS_MAIN";
586 } else {
587 $ns_name = "NS_" . strtoupper( MWNamespace::getCanonicalName( $ns ) );
588 }
589 # ... and the MWNamespace method name
590 $nsMethod = strtolower( $m[1] ) . $m[3];
591
592 $expect = ( $m[2] === '' );
593 $expect_name = $expect ? 'TRUE' : 'FALSE';
594
595 return $this->assertEquals( $expect,
596 MWNamespace::$nsMethod( $ns, $msg ),
597 "MWNamespace::$nsMethod( $ns_name ) should returns $expect_name"
598 );
599 }
600
601 throw new Exception( __METHOD__ . " could not find a method named $method\n" );
602 }
603
604 function assertSameSubject( $ns1, $ns2, $msg = '' ) {
605 $this->assertTrue( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
606 }
607
608 function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
609 $this->assertFalse( MWNamespace::subjectEquals( $ns1, $ns2, $msg ) );
610 }
611 }