3 * @author Antoine Musso
4 * @copyright Copyright © 2011, Antoine Musso
8 class MWNamespaceTest
extends MediaWikiTestCase
{
10 protected function setUp() {
13 $this->setMwGlobals( [
14 'wgContentNamespaces' => [ NS_MAIN
],
15 'wgNamespacesWithSubpages' => [
20 'wgCapitalLinks' => true,
21 'wgCapitalLinkOverrides' => [],
22 'wgNonincludableNamespaces' => [],
27 * @todo Write more texts, handle $wgAllowImageMoving setting
28 * @covers MWNamespace::isMovable
30 public function testIsMovable() {
31 $this->assertFalse( MWNamespace
::isMovable( NS_SPECIAL
) );
34 private function assertIsSubject( $ns ) {
35 $this->assertTrue( MWNamespace
::isSubject( $ns ) );
38 private function assertIsNotSubject( $ns ) {
39 $this->assertFalse( MWNamespace
::isSubject( $ns ) );
43 * Please make sure to change testIsTalk() if you change the assertions below
44 * @covers MWNamespace::isSubject
46 public function testIsSubject() {
48 $this->assertIsSubject( NS_MEDIA
);
49 $this->assertIsSubject( NS_SPECIAL
);
52 $this->assertIsSubject( NS_MAIN
);
53 $this->assertIsSubject( NS_USER
);
54 $this->assertIsSubject( 100 ); # user defined
57 $this->assertIsNotSubject( NS_TALK
);
58 $this->assertIsNotSubject( NS_USER_TALK
);
59 $this->assertIsNotSubject( 101 ); # user defined
62 private function assertIsTalk( $ns ) {
63 $this->assertTrue( MWNamespace
::isTalk( $ns ) );
66 private function assertIsNotTalk( $ns ) {
67 $this->assertFalse( MWNamespace
::isTalk( $ns ) );
71 * Reverse of testIsSubject().
72 * Please update testIsSubject() if you change assertions below
73 * @covers MWNamespace::isTalk
75 public function testIsTalk() {
77 $this->assertIsNotTalk( NS_MEDIA
);
78 $this->assertIsNotTalk( NS_SPECIAL
);
81 $this->assertIsNotTalk( NS_MAIN
);
82 $this->assertIsNotTalk( NS_USER
);
83 $this->assertIsNotTalk( 100 ); # user defined
86 $this->assertIsTalk( NS_TALK
);
87 $this->assertIsTalk( NS_USER_TALK
);
88 $this->assertIsTalk( 101 ); # user defined
92 * @covers MWNamespace::getSubject
94 public function testGetSubject() {
95 // Special namespaces are their own subjects
96 $this->assertEquals( NS_MEDIA
, MWNamespace
::getSubject( NS_MEDIA
) );
97 $this->assertEquals( NS_SPECIAL
, MWNamespace
::getSubject( NS_SPECIAL
) );
99 $this->assertEquals( NS_MAIN
, MWNamespace
::getSubject( NS_TALK
) );
100 $this->assertEquals( NS_USER
, MWNamespace
::getSubject( NS_USER_TALK
) );
104 * Regular getTalk() calls
105 * Namespaces without a talk page (NS_MEDIA, NS_SPECIAL) are tested in
106 * the function testGetTalkExceptions()
107 * @covers MWNamespace::getTalk
109 public function testGetTalk() {
110 $this->assertEquals( NS_TALK
, MWNamespace
::getTalk( NS_MAIN
) );
111 $this->assertEquals( NS_TALK
, MWNamespace
::getTalk( NS_TALK
) );
112 $this->assertEquals( NS_USER_TALK
, MWNamespace
::getTalk( NS_USER
) );
113 $this->assertEquals( NS_USER_TALK
, MWNamespace
::getTalk( NS_USER_TALK
) );
117 * Exceptions with getTalk()
118 * NS_MEDIA does not have talk pages. MediaWiki raise an exception for them.
119 * @expectedException MWException
120 * @covers MWNamespace::getTalk
122 public function testGetTalkExceptionsForNsMedia() {
123 $this->assertNull( MWNamespace
::getTalk( NS_MEDIA
) );
127 * Exceptions with getTalk()
128 * NS_SPECIAL does not have talk pages. MediaWiki raise an exception for them.
129 * @expectedException MWException
130 * @covers MWNamespace::getTalk
132 public function testGetTalkExceptionsForNsSpecial() {
133 $this->assertNull( MWNamespace
::getTalk( NS_SPECIAL
) );
137 * Regular getAssociated() calls
138 * Namespaces without an associated page (NS_MEDIA, NS_SPECIAL) are tested in
139 * the function testGetAssociatedExceptions()
140 * @covers MWNamespace::getAssociated
142 public function testGetAssociated() {
143 $this->assertEquals( NS_TALK
, MWNamespace
::getAssociated( NS_MAIN
) );
144 $this->assertEquals( NS_MAIN
, MWNamespace
::getAssociated( NS_TALK
) );
147 # ## Exceptions with getAssociated()
148 # ## NS_MEDIA and NS_SPECIAL do not have talk pages. MediaWiki raises
149 # ## an exception for them.
151 * @expectedException MWException
152 * @covers MWNamespace::getAssociated
154 public function testGetAssociatedExceptionsForNsMedia() {
155 $this->assertNull( MWNamespace
::getAssociated( NS_MEDIA
) );
159 * @expectedException MWException
160 * @covers MWNamespace::getAssociated
162 public function testGetAssociatedExceptionsForNsSpecial() {
163 $this->assertNull( MWNamespace
::getAssociated( NS_SPECIAL
) );
167 * Test MWNamespace::equals
168 * Note if we add a namespace registration system with keys like 'MAIN'
169 * we should add tests here for equivilance on things like 'MAIN' == 0
170 * and 'MAIN' == NS_MAIN.
171 * @covers MWNamespace::equals
173 public function testEquals() {
174 $this->assertTrue( MWNamespace
::equals( NS_MAIN
, NS_MAIN
) );
175 $this->assertTrue( MWNamespace
::equals( NS_MAIN
, 0 ) ); // In case we make NS_MAIN 'MAIN'
176 $this->assertTrue( MWNamespace
::equals( NS_USER
, NS_USER
) );
177 $this->assertTrue( MWNamespace
::equals( NS_USER
, 2 ) );
178 $this->assertTrue( MWNamespace
::equals( NS_USER_TALK
, NS_USER_TALK
) );
179 $this->assertTrue( MWNamespace
::equals( NS_SPECIAL
, NS_SPECIAL
) );
180 $this->assertFalse( MWNamespace
::equals( NS_MAIN
, NS_TALK
) );
181 $this->assertFalse( MWNamespace
::equals( NS_USER
, NS_USER_TALK
) );
182 $this->assertFalse( MWNamespace
::equals( NS_PROJECT
, NS_TEMPLATE
) );
186 * @covers MWNamespace::subjectEquals
188 public function testSubjectEquals() {
189 $this->assertSameSubject( NS_MAIN
, NS_MAIN
);
190 $this->assertSameSubject( NS_MAIN
, 0 ); // In case we make NS_MAIN 'MAIN'
191 $this->assertSameSubject( NS_USER
, NS_USER
);
192 $this->assertSameSubject( NS_USER
, 2 );
193 $this->assertSameSubject( NS_USER_TALK
, NS_USER_TALK
);
194 $this->assertSameSubject( NS_SPECIAL
, NS_SPECIAL
);
195 $this->assertSameSubject( NS_MAIN
, NS_TALK
);
196 $this->assertSameSubject( NS_USER
, NS_USER_TALK
);
198 $this->assertDifferentSubject( NS_PROJECT
, NS_TEMPLATE
);
199 $this->assertDifferentSubject( NS_SPECIAL
, NS_MAIN
);
203 * @covers MWNamespace::subjectEquals
205 public function testSpecialAndMediaAreDifferentSubjects() {
206 $this->assertDifferentSubject(
207 NS_MEDIA
, NS_SPECIAL
,
208 "NS_MEDIA and NS_SPECIAL are different subject namespaces"
210 $this->assertDifferentSubject(
211 NS_SPECIAL
, NS_MEDIA
,
212 "NS_SPECIAL and NS_MEDIA are different subject namespaces"
216 public function provideHasTalkNamespace() {
219 [ NS_SPECIAL
, false ],
224 [ NS_USER_TALK
, true ],
232 * @dataProvider provideHasTalkNamespace
233 * @covers MWNamespace::hasTalkNamespace
236 * @param bool $expected
238 public function testHasTalkNamespace( $index, $expected ) {
239 $actual = MWNamespace
::hasTalkNamespace( $index );
240 $this->assertSame( $actual, $expected, "NS $index" );
244 * @dataProvider provideHasTalkNamespace
245 * @covers MWNamespace::canTalk
248 * @param bool $expected
250 public function testCanTalk( $index, $expected ) {
251 $actual = MWNamespace
::canTalk( $index );
252 $this->assertSame( $actual, $expected, "NS $index" );
255 private function assertIsContent( $ns ) {
256 $this->assertTrue( MWNamespace
::isContent( $ns ) );
259 private function assertIsNotContent( $ns ) {
260 $this->assertFalse( MWNamespace
::isContent( $ns ) );
264 * @covers MWNamespace::isContent
266 public function testIsContent() {
267 // NS_MAIN is a content namespace per DefaultSettings.php
268 // and per function definition.
270 $this->assertIsContent( NS_MAIN
);
272 // Other namespaces which are not expected to be content
274 $this->assertIsNotContent( NS_MEDIA
);
275 $this->assertIsNotContent( NS_SPECIAL
);
276 $this->assertIsNotContent( NS_TALK
);
277 $this->assertIsNotContent( NS_USER
);
278 $this->assertIsNotContent( NS_CATEGORY
);
279 $this->assertIsNotContent( 100 );
283 * Similar to testIsContent() but alters the $wgContentNamespaces
285 * @covers MWNamespace::isContent
287 public function testIsContentAdvanced() {
288 global $wgContentNamespaces;
290 // Test that user defined namespace #252 is not content
291 $this->assertIsNotContent( 252 );
293 // Bless namespace # 252 as a content namespace
294 $wgContentNamespaces[] = 252;
296 $this->assertIsContent( 252 );
298 // Makes sure NS_MAIN was not impacted
299 $this->assertIsContent( NS_MAIN
);
302 private function assertIsWatchable( $ns ) {
303 $this->assertTrue( MWNamespace
::isWatchable( $ns ) );
306 private function assertIsNotWatchable( $ns ) {
307 $this->assertFalse( MWNamespace
::isWatchable( $ns ) );
311 * @covers MWNamespace::isWatchable
313 public function testIsWatchable() {
314 // Specials namespaces are not watchable
315 $this->assertIsNotWatchable( NS_MEDIA
);
316 $this->assertIsNotWatchable( NS_SPECIAL
);
318 // Core defined namespaces are watchables
319 $this->assertIsWatchable( NS_MAIN
);
320 $this->assertIsWatchable( NS_TALK
);
322 // Additional, user defined namespaces are watchables
323 $this->assertIsWatchable( 100 );
324 $this->assertIsWatchable( 101 );
327 private function assertHasSubpages( $ns ) {
328 $this->assertTrue( MWNamespace
::hasSubpages( $ns ) );
331 private function assertHasNotSubpages( $ns ) {
332 $this->assertFalse( MWNamespace
::hasSubpages( $ns ) );
336 * @covers MWNamespace::hasSubpages
338 public function testHasSubpages() {
339 global $wgNamespacesWithSubpages;
341 // Special namespaces:
342 $this->assertHasNotSubpages( NS_MEDIA
);
343 $this->assertHasNotSubpages( NS_SPECIAL
);
345 // Namespaces without subpages
346 $this->assertHasNotSubpages( NS_MAIN
);
348 $wgNamespacesWithSubpages[NS_MAIN
] = true;
349 $this->assertHasSubpages( NS_MAIN
);
351 $wgNamespacesWithSubpages[NS_MAIN
] = false;
352 $this->assertHasNotSubpages( NS_MAIN
);
354 // Some namespaces with subpages
355 $this->assertHasSubpages( NS_TALK
);
356 $this->assertHasSubpages( NS_USER
);
357 $this->assertHasSubpages( NS_USER_TALK
);
361 * @covers MWNamespace::getContentNamespaces
363 public function testGetContentNamespaces() {
364 global $wgContentNamespaces;
368 MWNamespace
::getContentNamespaces(),
369 '$wgContentNamespaces is an array with only NS_MAIN by default'
372 # test !is_array( $wgcontentNamespaces )
373 $wgContentNamespaces = '';
374 $this->assertEquals( [ NS_MAIN
], MWNamespace
::getContentNamespaces() );
376 $wgContentNamespaces = false;
377 $this->assertEquals( [ NS_MAIN
], MWNamespace
::getContentNamespaces() );
379 $wgContentNamespaces = null;
380 $this->assertEquals( [ NS_MAIN
], MWNamespace
::getContentNamespaces() );
382 $wgContentNamespaces = 5;
383 $this->assertEquals( [ NS_MAIN
], MWNamespace
::getContentNamespaces() );
385 # test $wgContentNamespaces === []
386 $wgContentNamespaces = [];
387 $this->assertEquals( [ NS_MAIN
], MWNamespace
::getContentNamespaces() );
389 # test !in_array( NS_MAIN, $wgContentNamespaces )
390 $wgContentNamespaces = [ NS_USER
, NS_CATEGORY
];
392 [ NS_MAIN
, NS_USER
, NS_CATEGORY
],
393 MWNamespace
::getContentNamespaces(),
394 'NS_MAIN is forced in $wgContentNamespaces even if unwanted'
397 # test other cases, return $wgcontentNamespaces as is
398 $wgContentNamespaces = [ NS_MAIN
];
401 MWNamespace
::getContentNamespaces()
404 $wgContentNamespaces = [ NS_MAIN
, NS_USER
, NS_CATEGORY
];
406 [ NS_MAIN
, NS_USER
, NS_CATEGORY
],
407 MWNamespace
::getContentNamespaces()
412 * @covers MWNamespace::getSubjectNamespaces
414 public function testGetSubjectNamespaces() {
415 $subjectsNS = MWNamespace
::getSubjectNamespaces();
416 $this->assertContains( NS_MAIN
, $subjectsNS,
417 "Talk namespaces should have NS_MAIN" );
418 $this->assertNotContains( NS_TALK
, $subjectsNS,
419 "Talk namespaces should have NS_TALK" );
421 $this->assertNotContains( NS_MEDIA
, $subjectsNS,
422 "Talk namespaces should not have NS_MEDIA" );
423 $this->assertNotContains( NS_SPECIAL
, $subjectsNS,
424 "Talk namespaces should not have NS_SPECIAL" );
428 * @covers MWNamespace::getTalkNamespaces
430 public function testGetTalkNamespaces() {
431 $talkNS = MWNamespace
::getTalkNamespaces();
432 $this->assertContains( NS_TALK
, $talkNS,
433 "Subject namespaces should have NS_TALK" );
434 $this->assertNotContains( NS_MAIN
, $talkNS,
435 "Subject namespaces should not have NS_MAIN" );
437 $this->assertNotContains( NS_MEDIA
, $talkNS,
438 "Subject namespaces should not have NS_MEDIA" );
439 $this->assertNotContains( NS_SPECIAL
, $talkNS,
440 "Subject namespaces should not have NS_SPECIAL" );
443 private function assertIsCapitalized( $ns ) {
444 $this->assertTrue( MWNamespace
::isCapitalized( $ns ) );
447 private function assertIsNotCapitalized( $ns ) {
448 $this->assertFalse( MWNamespace
::isCapitalized( $ns ) );
452 * Some namespaces are always capitalized per code definition
453 * in MWNamespace::$alwaysCapitalizedNamespaces
454 * @covers MWNamespace::isCapitalized
456 public function testIsCapitalizedHardcodedAssertions() {
457 // NS_MEDIA and NS_FILE are treated the same
459 MWNamespace
::isCapitalized( NS_MEDIA
),
460 MWNamespace
::isCapitalized( NS_FILE
),
461 'NS_MEDIA and NS_FILE have same capitalization rendering'
464 // Boths are capitalized by default
465 $this->assertIsCapitalized( NS_MEDIA
);
466 $this->assertIsCapitalized( NS_FILE
);
468 // Always capitalized namespaces
469 // @see MWNamespace::$alwaysCapitalizedNamespaces
470 $this->assertIsCapitalized( NS_SPECIAL
);
471 $this->assertIsCapitalized( NS_USER
);
472 $this->assertIsCapitalized( NS_MEDIAWIKI
);
476 * Follows up for testIsCapitalizedHardcodedAssertions() but alter the
477 * global $wgCapitalLink setting to have extended coverage.
479 * MWNamespace::isCapitalized() rely on two global settings:
480 * $wgCapitalLinkOverrides = []; by default
481 * $wgCapitalLinks = true; by default
482 * This function test $wgCapitalLinks
484 * Global setting correctness is tested against the NS_PROJECT and
485 * NS_PROJECT_TALK namespaces since they are not hardcoded nor specials
486 * @covers MWNamespace::isCapitalized
488 public function testIsCapitalizedWithWgCapitalLinks() {
489 global $wgCapitalLinks;
491 $this->assertIsCapitalized( NS_PROJECT
);
492 $this->assertIsCapitalized( NS_PROJECT_TALK
);
494 $wgCapitalLinks = false;
496 // hardcoded namespaces (see above function) are still capitalized:
497 $this->assertIsCapitalized( NS_SPECIAL
);
498 $this->assertIsCapitalized( NS_USER
);
499 $this->assertIsCapitalized( NS_MEDIAWIKI
);
501 // setting is correctly applied
502 $this->assertIsNotCapitalized( NS_PROJECT
);
503 $this->assertIsNotCapitalized( NS_PROJECT_TALK
);
507 * Counter part for MWNamespace::testIsCapitalizedWithWgCapitalLinks() now
508 * testing the $wgCapitalLinkOverrides global.
510 * @todo split groups of assertions in autonomous testing functions
511 * @covers MWNamespace::isCapitalized
513 public function testIsCapitalizedWithWgCapitalLinkOverrides() {
514 global $wgCapitalLinkOverrides;
516 // Test default settings
517 $this->assertIsCapitalized( NS_PROJECT
);
518 $this->assertIsCapitalized( NS_PROJECT_TALK
);
520 // hardcoded namespaces (see above function) are capitalized:
521 $this->assertIsCapitalized( NS_SPECIAL
);
522 $this->assertIsCapitalized( NS_USER
);
523 $this->assertIsCapitalized( NS_MEDIAWIKI
);
525 // Hardcoded namespaces remains capitalized
526 $wgCapitalLinkOverrides[NS_SPECIAL
] = false;
527 $wgCapitalLinkOverrides[NS_USER
] = false;
528 $wgCapitalLinkOverrides[NS_MEDIAWIKI
] = false;
530 $this->assertIsCapitalized( NS_SPECIAL
);
531 $this->assertIsCapitalized( NS_USER
);
532 $this->assertIsCapitalized( NS_MEDIAWIKI
);
534 $wgCapitalLinkOverrides[NS_PROJECT
] = false;
535 $this->assertIsNotCapitalized( NS_PROJECT
);
537 $wgCapitalLinkOverrides[NS_PROJECT
] = true;
538 $this->assertIsCapitalized( NS_PROJECT
);
540 unset( $wgCapitalLinkOverrides[NS_PROJECT
] );
541 $this->assertIsCapitalized( NS_PROJECT
);
545 * @covers MWNamespace::hasGenderDistinction
547 public function testHasGenderDistinction() {
548 // Namespaces with gender distinctions
549 $this->assertTrue( MWNamespace
::hasGenderDistinction( NS_USER
) );
550 $this->assertTrue( MWNamespace
::hasGenderDistinction( NS_USER_TALK
) );
552 // Other ones, "genderless"
553 $this->assertFalse( MWNamespace
::hasGenderDistinction( NS_MEDIA
) );
554 $this->assertFalse( MWNamespace
::hasGenderDistinction( NS_SPECIAL
) );
555 $this->assertFalse( MWNamespace
::hasGenderDistinction( NS_MAIN
) );
556 $this->assertFalse( MWNamespace
::hasGenderDistinction( NS_TALK
) );
560 * @covers MWNamespace::isNonincludable
562 public function testIsNonincludable() {
563 global $wgNonincludableNamespaces;
565 $wgNonincludableNamespaces = [ NS_USER
];
567 $this->assertTrue( MWNamespace
::isNonincludable( NS_USER
) );
568 $this->assertFalse( MWNamespace
::isNonincludable( NS_TEMPLATE
) );
571 private function assertSameSubject( $ns1, $ns2, $msg = '' ) {
572 $this->assertTrue( MWNamespace
::subjectEquals( $ns1, $ns2 ), $msg );
575 private function assertDifferentSubject( $ns1, $ns2, $msg = '' ) {
576 $this->assertFalse( MWNamespace
::subjectEquals( $ns1, $ns2 ), $msg );