Merge "Added "maxPartitionsTry" option to JobQueueFederated"
[lhc/web/wiklou.git] / tests / phpunit / includes / TitleTest.php
index 6399d48..6bfe545 100644 (file)
@@ -1,12 +1,10 @@
 <?php
 
 /**
- *
  * @group Database
  *        ^--- needed for language cache stuff
  */
 class TitleTest extends MediaWikiTestCase {
-
        protected function setUp() {
                parent::setUp();
 
@@ -20,7 +18,10 @@ class TitleTest extends MediaWikiTestCase {
                ) );
        }
 
-       function testLegalChars() {
+       /**
+        * @covers Title::legalChars
+        */
+       public function testLegalChars() {
                $titlechars = Title::legalChars();
 
                foreach ( range( 1, 255 ) as $num ) {
@@ -33,13 +34,161 @@ class TitleTest extends MediaWikiTestCase {
                }
        }
 
+       /**
+        * See also mediawiki.Title.test.js
+        * @covers Title::secureAndSplit
+        * @todo This method should be split into 2 separate tests each with a provider
+        */
+       public function testSecureAndSplit() {
+               // Valid
+               foreach ( array(
+                       'Sandbox',
+                       'A "B"',
+                       'A \'B\'',
+                       '.com',
+                       '~',
+                       '"',
+                       '\'',
+                       'Talk:Sandbox',
+                       'Talk:Foo:Sandbox',
+                       'File:Example.svg',
+                       'File_talk:Example.svg',
+                       'Foo/.../Sandbox',
+                       'Sandbox/...',
+                       'A~~',
+                       // Length is 256 total, but only title part matters
+                       'Category:' . str_repeat( 'x', 248 ),
+                       str_repeat( 'x', 252 )
+               ) as $text ) {
+                       $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" );
+               }
+
+               // Invalid
+               foreach ( array(
+                       '',
+                       '__  __',
+                       '  __  ',
+                       // Bad characters forbidden regardless of wgLegalTitleChars
+                       'A [ B',
+                       'A ] B',
+                       'A { B',
+                       'A } B',
+                       'A < B',
+                       'A > B',
+                       'A | B',
+                       // URL encoding
+                       'A%20B',
+                       'A%23B',
+                       'A%2523B',
+                       // XML/HTML character entity references
+                       // Note: Commented out because they are not marked invalid by the PHP test as
+                       // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
+                       //'A &eacute; B',
+                       //'A &#233; B',
+                       //'A &#x00E9; B',
+                       // Subject of NS_TALK does not roundtrip to NS_MAIN
+                       'Talk:File:Example.svg',
+                       // Directory navigation
+                       '.',
+                       '..',
+                       './Sandbox',
+                       '../Sandbox',
+                       'Foo/./Sandbox',
+                       'Foo/../Sandbox',
+                       'Sandbox/.',
+                       'Sandbox/..',
+                       // Tilde
+                       'A ~~~ Name',
+                       'A ~~~~ Signature',
+                       'A ~~~~~ Timestamp',
+                       str_repeat( 'x', 256 ),
+                       // Namespace prefix without actual title
+                       // ':', // bug 54044
+                       'Talk:',
+                       'Category: ',
+                       'Category: #bar'
+               ) as $text ) {
+                       $this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
+               }
+       }
+
+       public static function provideConvertByteClassToUnicodeClass() {
+               return array(
+                       array(
+                               ' %!"$&\'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+',
+                               ' %!"$&\'()*,\\-./0-9:;=?@A-Z\\\\\\^_`a-z~+\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTYf-\\xFF+',
+                               'QWERTYf-\\x7F+\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTY\\x66-\\xFD+',
+                               'QWERTYf-\\x7F+\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTYf-y+',
+                               'QWERTYf-y+',
+                       ),
+                       array(
+                               'QWERTYf-\\x80+',
+                               'QWERTYf-\\x7F+\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTY\\x66-\\x80+\\x23',
+                               'QWERTYf-\\x7F+#\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTY\\x66-\\x80+\\xD3',
+                               'QWERTYf-\\x7F+\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               '\\\\\\x99',
+                               '\\\\\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               '-\\x99',
+                               '\\-\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               'QWERTY\\-\\x99',
+                               'QWERTY\\-\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               '\\\\x99',
+                               '\\\\x99',
+                       ),
+                       array(
+                               'A-\\x9F',
+                               'A-\\x7F\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               '\\x66-\\x77QWERTY\\x88-\\x91FXZ',
+                               'f-wQWERTYFXZ\\u0080-\\uFFFF',
+                       ),
+                       array(
+                               '\\x66-\\x99QWERTY\\xAA-\\xEEFXZ',
+                               'f-\\x7FQWERTYFXZ\\u0080-\\uFFFF',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideConvertByteClassToUnicodeClass
+        * @covers Title::convertByteClassToUnicodeClass
+        */
+       public function testConvertByteClassToUnicodeClass( $byteClass, $unicodeClass ) {
+               $this->assertEquals( $unicodeClass, Title::convertByteClassToUnicodeClass( $byteClass ) );
+       }
+
        /**
         * @dataProvider provideBug31100
+        * @covers Title::fixSpecialName
         */
-       function testBug31100FixSpecialName( $text, $expectedParam ) {
+       public function testBug31100FixSpecialName( $text, $expectedParam ) {
                $title = Title::newFromText( $text );
                $fixed = $title->fixSpecialName();
-               $stuff = explode( '/', $fixed->getDbKey(), 2 );
+               $stuff = explode( '/', $fixed->getDBkey(), 2 );
                if ( count( $stuff ) == 2 ) {
                        $par = $stuff[1];
                } else {
@@ -55,17 +204,18 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'Special:Version/param', 'param' ),
                );
        }
-       
+
        /**
         * Auth-less test of Title::isValidMoveOperation
-        * 
+        *
         * @group Database
         * @param string $source
         * @param string $target
-        * @param array|string|true $expected Required error
+        * @param array|string|bool $expected Required error
         * @dataProvider provideTestIsValidMoveOperation
+        * @covers Title::isValidMoveOperation
         */
-       function testIsValidMoveOperation( $source, $target, $expected ) {
+       public function testIsValidMoveOperation( $source, $target, $expected ) {
                $title = Title::newFromText( $source );
                $nt = Title::newFromText( $target );
                $errors = $title->isValidMoveOperation( $nt, false );
@@ -78,11 +228,11 @@ class TitleTest extends MediaWikiTestCase {
                        }
                }
        }
-       
+
        /**
         * Provides test parameter values for testIsValidMoveOperation()
         */
-       function dataTestIsValidMoveOperation() {
+       public function dataTestIsValidMoveOperation() {
                return array(
                        array( 'Test', 'Test', 'selfmove' ),
                        array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
@@ -95,18 +245,17 @@ class TitleTest extends MediaWikiTestCase {
         * @param array $whitelistRegexp
         * @param string $source
         * @param string $action
-        * @param array|string|true $expected Required error
+        * @param array|string|bool $expected Required error
         *
-        * @covers Title::checkReadPermission
+        * @covers Title::checkReadPermissions
         * @dataProvider dataWgWhitelistReadRegexp
         */
-       function testWgWhitelistReadRegexp($whitelistRegexp, $source, $action, $expected) {
-
+       public function testWgWhitelistReadRegexp( $whitelistRegexp, $source, $action, $expected ) {
                // $wgWhitelistReadRegexp must be an array. Since the provided test cases
                // usually have only one regex, it is more concise to write the lonely regex
                // as a string. Thus we cast to an array() to honor $wgWhitelistReadRegexp
                // type requisite.
-               if( is_string( $whitelistRegexp ) ) {
+               if ( is_string( $whitelistRegexp ) ) {
                        $whitelistRegexp = array( $whitelistRegexp );
                }
 
@@ -126,8 +275,8 @@ class TitleTest extends MediaWikiTestCase {
                $wgWhitelistRead = array( 'some random non sense title' );
 
                global $wgWhitelistReadRegexp;
-               $oldWhitelistRegexp    = $wgWhitelistReadRegexp;
-               $wgWhitelistReadRegexp = $whitelistRegexp ;
+               $oldWhitelistRegexp = $wgWhitelistReadRegexp;
+               $wgWhitelistReadRegexp = $whitelistRegexp;
 
                // Just use $wgUser which in test is a user object for '127.0.0.1'
                global $wgUser;
@@ -141,12 +290,11 @@ class TitleTest extends MediaWikiTestCase {
                $wgWhitelistRead = $oldWhitelist;
                $wgWhitelistReadRegexp = $oldWhitelistRegexp;
 
-               if( is_bool( $expected ) ) {
+               if ( is_bool( $expected ) ) {
                        # Forge the assertion message depending on the assertion expectation
                        $allowableness = $expected
                                ? " should be allowed"
-                               : " should NOT be allowed"
-                       ;
+                               : " should NOT be allowed";
                        $this->assertEquals( $expected, $errors, "User action '$action' on [[$source]] $allowableness." );
                } else {
                        $errors = $this->flattenErrorsArray( $errors );
@@ -159,8 +307,8 @@ class TitleTest extends MediaWikiTestCase {
        /**
         * Provides test parameter values for testWgWhitelistReadRegexp()
         */
-       function dataWgWhitelistReadRegexp() {
-               $ALLOWED    = true;
+       public function dataWgWhitelistReadRegexp() {
+               $ALLOWED = true;
                $DISALLOWED = false;
 
                return array(
@@ -195,25 +343,27 @@ class TitleTest extends MediaWikiTestCase {
                );
        }
 
-       function flattenErrorsArray( $errors ) {
+       public function flattenErrorsArray( $errors ) {
                $result = array();
                foreach ( $errors as $error ) {
                        $result[] = $error[0];
                }
+
                return $result;
        }
-       
+
        public static function provideTestIsValidMoveOperation() {
-               return array( 
+               return array(
                        array( 'Test', 'Test', 'selfmove' ),
                        array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
                );
        }
 
        /**
-        * @dataProvider provideCasesForGetpageviewlanguage
+        * @dataProvider provideGetPageViewLanguage
+        * @covers Title::getPageViewLanguage
         */
-       function testGetpageviewlanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) {
+       public function testGetPageViewLanguage( $expected, $titleText, $contLang, $lang, $variant, $msg = '' ) {
                global $wgLanguageCode, $wgContLang, $wgLang, $wgDefaultLanguageVariant, $wgAllowUserJs;
 
                // Setup environnement for this test
@@ -233,7 +383,7 @@ class TitleTest extends MediaWikiTestCase {
                );
        }
 
-       function provideCasesForGetpageviewlanguage() {
+       public static function provideGetPageViewLanguage() {
                # Format:
                # - expected
                # - Title name
@@ -246,36 +396,37 @@ class TitleTest extends MediaWikiTestCase {
                        array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', false ),
                        array( 'zh', 'Help:I_need_somebody', 'zh', 'zh-tw', false ),
 
-                       array( 'es',    'Help:I_need_somebody',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About',           'es', 'zh-tw', 'zh-cn' ),
-                       array( 'es',    'MediaWiki:About/',          'es', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'es', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-cn', 'Help:I_need_somebody',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About',           'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh',    'MediaWiki:About/',          'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'de',    'MediaWiki:About/de',        'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-cn', 'MediaWiki:About/zh-cn',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'MediaWiki:About/zh-tw',     'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.js',       'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'MediaWiki:Common.css',      'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Common.js',    'zh', 'zh-tw', 'zh-cn' ),
-                       array( 'en',    'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
-
-                       array( 'zh-tw', 'Special:NewPages',       'es', 'zh-tw', 'zh-cn' ),
-                       array( 'zh-tw', 'Special:NewPages',       'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'Help:I_need_somebody', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'es', 'MediaWiki:About/', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'es', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-cn', 'Help:I_need_somebody', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh', 'MediaWiki:About/', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'de', 'MediaWiki:About/de', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-cn', 'MediaWiki:About/zh-cn', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'MediaWiki:About/zh-tw', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'MediaWiki:Common.css', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Common.js', 'zh', 'zh-tw', 'zh-cn' ),
+                       array( 'en', 'User:JohnDoe/Monobook.css', 'zh', 'zh-tw', 'zh-cn' ),
+
+                       array( 'zh-tw', 'Special:NewPages', 'es', 'zh-tw', 'zh-cn' ),
+                       array( 'zh-tw', 'Special:NewPages', 'zh', 'zh-tw', 'zh-cn' ),
 
                );
        }
 
        /**
         * @dataProvider provideBaseTitleCases
+        * @covers Title::getBaseText
         */
-       function testExtractingBaseTextFromTitle( $title, $expected, $msg='' ) {
+       public function testGetBaseText( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getBaseText(),
@@ -283,18 +434,19 @@ class TitleTest extends MediaWikiTestCase {
                );
        }
 
-       function provideBaseTitleCases() {
+       public static function provideBaseTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
-                       array('User:Foo/Bar/Baz', 'Foo/Bar' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe/subOne' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo/Bar' ),
                );
        }
 
        /**
         * @dataProvider provideRootTitleCases
+        * @covers Title::getRootText
         */
-       function testExtractingRootTextFromTitle( $title, $expected, $msg='' ) {
+       public function testGetRootText( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getRootText(),
@@ -305,16 +457,17 @@ class TitleTest extends MediaWikiTestCase {
        public static function provideRootTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'John Doe' ),
-                       array('User:Foo/Bar/Baz', 'Foo' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'John Doe' ),
+                       array( 'User:Foo/Bar/Baz', 'Foo' ),
                );
        }
 
        /**
         * @todo Handle $wgNamespacesWithSubpages cases
         * @dataProvider provideSubpageTitleCases
+        * @covers Title::getSubpageText
         */
-       function testExtractingSubpageTextFromTitle( $title, $expected, $msg='' ) {
+       public function testGetSubpageText( $title, $expected, $msg = '' ) {
                $title = Title::newFromText( $title );
                $this->assertEquals( $expected,
                        $title->getSubpageText(),
@@ -322,12 +475,11 @@ class TitleTest extends MediaWikiTestCase {
                );
        }
 
-       function provideSubpageTitleCases() {
+       public static function provideSubpageTitleCases() {
                return array(
                        # Title, expected base, optional message
-                       array('User:John_Doe/subOne/subTwo', 'subTwo' ),
-                       array('User:John_Doe/subOne', 'subOne' ),
+                       array( 'User:John_Doe/subOne/subTwo', 'subTwo' ),
+                       array( 'User:John_Doe/subOne', 'subOne' ),
                );
        }
-
 }