MediaWiki
REL1_23
|
00001 <?php 00002 00003 class LanguageTest extends LanguageClassesTestCase { 00008 public function testLanguageConvertDoubleWidthToSingleWidth() { 00009 $this->assertEquals( 00010 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 00011 $this->getLang()->normalizeForSearch( 00012 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 00013 ), 00014 'convertDoubleWidth() with the full alphabet and digits' 00015 ); 00016 } 00017 00022 public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) { 00023 $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc ); 00024 } 00025 00026 public static function provideFormattableTimes() { 00027 return array( 00028 array( 00029 9.45, 00030 array(), 00031 '9.5 s', 00032 'formatTimePeriod() rounding (<10s)' 00033 ), 00034 array( 00035 9.45, 00036 array( 'noabbrevs' => true ), 00037 '9.5 seconds', 00038 'formatTimePeriod() rounding (<10s)' 00039 ), 00040 array( 00041 9.95, 00042 array(), 00043 '10 s', 00044 'formatTimePeriod() rounding (<10s)' 00045 ), 00046 array( 00047 9.95, 00048 array( 'noabbrevs' => true ), 00049 '10 seconds', 00050 'formatTimePeriod() rounding (<10s)' 00051 ), 00052 array( 00053 59.55, 00054 array(), 00055 '1 min 0 s', 00056 'formatTimePeriod() rounding (<60s)' 00057 ), 00058 array( 00059 59.55, 00060 array( 'noabbrevs' => true ), 00061 '1 minute 0 seconds', 00062 'formatTimePeriod() rounding (<60s)' 00063 ), 00064 array( 00065 119.55, 00066 array(), 00067 '2 min 0 s', 00068 'formatTimePeriod() rounding (<1h)' 00069 ), 00070 array( 00071 119.55, 00072 array( 'noabbrevs' => true ), 00073 '2 minutes 0 seconds', 00074 'formatTimePeriod() rounding (<1h)' 00075 ), 00076 array( 00077 3599.55, 00078 array(), 00079 '1 h 0 min 0 s', 00080 'formatTimePeriod() rounding (<1h)' 00081 ), 00082 array( 00083 3599.55, 00084 array( 'noabbrevs' => true ), 00085 '1 hour 0 minutes 0 seconds', 00086 'formatTimePeriod() rounding (<1h)' 00087 ), 00088 array( 00089 7199.55, 00090 array(), 00091 '2 h 0 min 0 s', 00092 'formatTimePeriod() rounding (>=1h)' 00093 ), 00094 array( 00095 7199.55, 00096 array( 'noabbrevs' => true ), 00097 '2 hours 0 minutes 0 seconds', 00098 'formatTimePeriod() rounding (>=1h)' 00099 ), 00100 array( 00101 7199.55, 00102 'avoidseconds', 00103 '2 h 0 min', 00104 'formatTimePeriod() rounding (>=1h), avoidseconds' 00105 ), 00106 array( 00107 7199.55, 00108 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), 00109 '2 hours 0 minutes', 00110 'formatTimePeriod() rounding (>=1h), avoidseconds' 00111 ), 00112 array( 00113 7199.55, 00114 'avoidminutes', 00115 '2 h 0 min', 00116 'formatTimePeriod() rounding (>=1h), avoidminutes' 00117 ), 00118 array( 00119 7199.55, 00120 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), 00121 '2 hours 0 minutes', 00122 'formatTimePeriod() rounding (>=1h), avoidminutes' 00123 ), 00124 array( 00125 172799.55, 00126 'avoidseconds', 00127 '48 h 0 min', 00128 'formatTimePeriod() rounding (=48h), avoidseconds' 00129 ), 00130 array( 00131 172799.55, 00132 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), 00133 '48 hours 0 minutes', 00134 'formatTimePeriod() rounding (=48h), avoidseconds' 00135 ), 00136 array( 00137 259199.55, 00138 'avoidminutes', 00139 '3 d 0 h', 00140 'formatTimePeriod() rounding (>48h), avoidminutes' 00141 ), 00142 array( 00143 259199.55, 00144 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), 00145 '3 days 0 hours', 00146 'formatTimePeriod() rounding (>48h), avoidminutes' 00147 ), 00148 array( 00149 176399.55, 00150 'avoidseconds', 00151 '2 d 1 h 0 min', 00152 'formatTimePeriod() rounding (>48h), avoidseconds' 00153 ), 00154 array( 00155 176399.55, 00156 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), 00157 '2 days 1 hour 0 minutes', 00158 'formatTimePeriod() rounding (>48h), avoidseconds' 00159 ), 00160 array( 00161 176399.55, 00162 'avoidminutes', 00163 '2 d 1 h', 00164 'formatTimePeriod() rounding (>48h), avoidminutes' 00165 ), 00166 array( 00167 176399.55, 00168 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), 00169 '2 days 1 hour', 00170 'formatTimePeriod() rounding (>48h), avoidminutes' 00171 ), 00172 array( 00173 259199.55, 00174 'avoidseconds', 00175 '3 d 0 h 0 min', 00176 'formatTimePeriod() rounding (>48h), avoidseconds' 00177 ), 00178 array( 00179 259199.55, 00180 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), 00181 '3 days 0 hours 0 minutes', 00182 'formatTimePeriod() rounding (>48h), avoidseconds' 00183 ), 00184 array( 00185 172801.55, 00186 'avoidseconds', 00187 '2 d 0 h 0 min', 00188 'formatTimePeriod() rounding, (>48h), avoidseconds' 00189 ), 00190 array( 00191 172801.55, 00192 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), 00193 '2 days 0 hours 0 minutes', 00194 'formatTimePeriod() rounding, (>48h), avoidseconds' 00195 ), 00196 array( 00197 176460.55, 00198 array(), 00199 '2 d 1 h 1 min 1 s', 00200 'formatTimePeriod() rounding, recursion, (>48h)' 00201 ), 00202 array( 00203 176460.55, 00204 array( 'noabbrevs' => true ), 00205 '2 days 1 hour 1 minute 1 second', 00206 'formatTimePeriod() rounding, recursion, (>48h)' 00207 ), 00208 ); 00209 } 00210 00214 public function testTruncate() { 00215 $this->assertEquals( 00216 "XXX", 00217 $this->getLang()->truncate( "1234567890", 0, 'XXX' ), 00218 'truncate prefix, len 0, small ellipsis' 00219 ); 00220 00221 $this->assertEquals( 00222 "12345XXX", 00223 $this->getLang()->truncate( "1234567890", 8, 'XXX' ), 00224 'truncate prefix, small ellipsis' 00225 ); 00226 00227 $this->assertEquals( 00228 "123456789", 00229 $this->getLang()->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ), 00230 'truncate prefix, large ellipsis' 00231 ); 00232 00233 $this->assertEquals( 00234 "XXX67890", 00235 $this->getLang()->truncate( "1234567890", -8, 'XXX' ), 00236 'truncate suffix, small ellipsis' 00237 ); 00238 00239 $this->assertEquals( 00240 "123456789", 00241 $this->getLang()->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ), 00242 'truncate suffix, large ellipsis' 00243 ); 00244 $this->assertEquals( 00245 "123XXX", 00246 $this->getLang()->truncate( "123 ", 9, 'XXX' ), 00247 'truncate prefix, with spaces' 00248 ); 00249 $this->assertEquals( 00250 "12345XXX", 00251 $this->getLang()->truncate( "12345 8", 11, 'XXX' ), 00252 'truncate prefix, with spaces and non-space ending' 00253 ); 00254 $this->assertEquals( 00255 "XXX234", 00256 $this->getLang()->truncate( "1 234", -8, 'XXX' ), 00257 'truncate suffix, with spaces' 00258 ); 00259 $this->assertEquals( 00260 "12345XXX", 00261 $this->getLang()->truncate( "1234567890", 5, 'XXX', false ), 00262 'truncate without adjustment' 00263 ); 00264 } 00265 00270 public function testTruncateHtml( $len, $ellipsis, $input, $expected ) { 00271 // Actual HTML... 00272 $this->assertEquals( 00273 $expected, 00274 $this->getLang()->truncateHTML( $input, $len, $ellipsis ) 00275 ); 00276 } 00277 00281 public static function provideHTMLTruncateData() { 00282 return array( 00283 array( 0, 'XXX', "1234567890", "XXX" ), 00284 array( 8, 'XXX', "1234567890", "12345XXX" ), 00285 array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ), 00286 array( 2, '***', 00287 '<p><span style="font-weight:bold;"></span></p>', 00288 '<p><span style="font-weight:bold;"></span></p>', 00289 ), 00290 array( 2, '***', 00291 '<p><span style="font-weight:bold;">123456789</span></p>', 00292 '<p><span style="font-weight:bold;">***</span></p>', 00293 ), 00294 array( 2, '***', 00295 '<p><span style="font-weight:bold;"> 23456789</span></p>', 00296 '<p><span style="font-weight:bold;">***</span></p>', 00297 ), 00298 array( 3, '***', 00299 '<p><span style="font-weight:bold;">123456789</span></p>', 00300 '<p><span style="font-weight:bold;">***</span></p>', 00301 ), 00302 array( 4, '***', 00303 '<p><span style="font-weight:bold;">123456789</span></p>', 00304 '<p><span style="font-weight:bold;">1***</span></p>', 00305 ), 00306 array( 5, '***', 00307 '<tt><span style="font-weight:bold;">123456789</span></tt>', 00308 '<tt><span style="font-weight:bold;">12***</span></tt>', 00309 ), 00310 array( 6, '***', 00311 '<p><a href="www.mediawiki.org">123456789</a></p>', 00312 '<p><a href="www.mediawiki.org">123***</a></p>', 00313 ), 00314 array( 6, '***', 00315 '<p><a href="www.mediawiki.org">12 456789</a></p>', 00316 '<p><a href="www.mediawiki.org">12 ***</a></p>', 00317 ), 00318 array( 7, '***', 00319 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>', 00320 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>', 00321 ), 00322 array( 8, '***', 00323 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>', 00324 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>', 00325 ), 00326 array( 9, '***', 00327 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>', 00328 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>', 00329 ), 00330 array( 10, '***', 00331 '<p><font style="font-weight:bold;">123456789</font></p>', 00332 '<p><font style="font-weight:bold;">123456789</font></p>', 00333 ), 00334 ); 00335 } 00336 00342 public function testWellFormedLanguageTag( $code, $message = '' ) { 00343 $this->assertTrue( 00344 Language::isWellFormedLanguageTag( $code ), 00345 "validating code $code $message" 00346 ); 00347 } 00348 00355 public static function provideWellFormedLanguageTags() { 00356 return array( 00357 array( 'fr', 'two-letter code' ), 00358 array( 'fr-latn', 'two-letter code with lower case script code' ), 00359 array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ), 00360 array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ), 00361 array( 'fr-FR', 'two-letter code with uppercase' ), 00362 array( 'ax-TZ', 'Not in the registry, but well-formed' ), 00363 array( 'fr-shadok', 'two-letter code with variant' ), 00364 array( 'fr-y-myext-myext2', 'non-x singleton' ), 00365 array( 'fra-Latn', 'ISO 639 can be 3-letters' ), 00366 array( 'fra', 'three-letter language code' ), 00367 array( 'fra-FX', 'three-letter language code with country code' ), 00368 array( 'i-klingon', 'grandfathered with singleton' ), 00369 array( 'I-kLINgon', 'tags are case-insensitive...' ), 00370 array( 'no-bok', 'grandfathered without singleton' ), 00371 array( 'i-enochian', 'Grandfathered' ), 00372 array( 'x-fr-CH', 'private use' ), 00373 array( 'es-419', 'two-letter code with region number' ), 00374 array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ), 00375 array( 'ab-x-abc-x-abc', 'anything goes after x' ), 00376 array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ), 00377 array( 'i-default', 'grandfathered' ), 00378 array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ), 00379 array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ), 00380 array( 'de-CH-1901', 'with country and year' ), 00381 array( 'en-US-x-twain', 'with country and singleton' ), 00382 array( 'zh-cmn', 'three-letter variant' ), 00383 array( 'zh-cmn-Hant', 'three-letter variant and script' ), 00384 array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ), 00385 array( 'xr-p-lze', 'Extension' ), 00386 ); 00387 } 00388 00394 public function testMalformedLanguageTag( $code, $message = '' ) { 00395 $this->assertFalse( 00396 Language::isWellFormedLanguageTag( $code ), 00397 "validating that code $code is a malformed language tag - $message" 00398 ); 00399 } 00400 00407 public static function provideMalformedLanguageTags() { 00408 return array( 00409 array( 'f', 'language too short' ), 00410 array( 'f-Latn', 'language too short with script' ), 00411 array( 'xr-lxs-qut', 'variants too short' ), # extlangS 00412 array( 'fr-Latn-F', 'region too short' ), 00413 array( 'a-value', 'language too short with region' ), 00414 array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ), 00415 array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ), 00416 array( 'abcdefghi-012345678', 'numbers too long' ), 00417 array( 'ab-abc-abc-abc-abc', 'invalid extensions' ), 00418 array( 'ab-abcd-abc', 'invalid extensions' ), 00419 array( 'ab-ab-abc', 'invalid extensions' ), 00420 array( 'ab-123-abc', 'invalid extensions' ), 00421 array( 'a-Hant-ZH', 'short language with valid extensions' ), 00422 array( 'a1-Hant-ZH', 'invalid character in language' ), 00423 array( 'ab-abcde-abc', 'invalid extensions' ), 00424 array( 'ab-1abc-abc', 'invalid characters in extensions' ), 00425 array( 'ab-ab-abcd', 'invalid order of extensions' ), 00426 array( 'ab-123-abcd', 'invalid order of extensions' ), 00427 array( 'ab-abcde-abcd', 'invalid extensions' ), 00428 array( 'ab-1abc-abcd', 'invalid characters in extensions' ), 00429 array( 'ab-a-b', 'extensions too short' ), 00430 array( 'ab-a-x', 'extensions too short, even with singleton' ), 00431 array( 'ab--ab', 'two separators' ), 00432 array( 'ab-abc-', 'separator in the end' ), 00433 array( '-ab-abc', 'separator in the beginning' ), 00434 array( 'abcd-efg', 'language too long' ), 00435 array( 'aabbccddE', 'tag too long' ), 00436 array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ), 00437 array( 'de-f', 'subtag too short' ), 00438 ); 00439 } 00440 00445 public function testLenientLanguageTag() { 00446 $this->assertTrue( 00447 Language::isWellFormedLanguageTag( 'pa_guru', true ), 00448 'pa_guru is a well-formed language tag in lenient mode' 00449 ); 00450 } 00451 00457 public function testBuiltInCodeValidation( $code, $message = '' ) { 00458 $this->assertTrue( 00459 (bool)Language::isValidBuiltInCode( $code ), 00460 "validating code $code $message" 00461 ); 00462 } 00463 00467 public function testBuiltInCodeValidationRejectUnderscore() { 00468 $this->assertFalse( 00469 (bool)Language::isValidBuiltInCode( 'be_tarask' ), 00470 "reject underscore in language code" 00471 ); 00472 } 00473 00474 public static function provideLanguageCodes() { 00475 return array( 00476 array( 'fr', 'Two letters, minor case' ), 00477 array( 'EN', 'Two letters, upper case' ), 00478 array( 'tyv', 'Three letters' ), 00479 array( 'tokipona', 'long language code' ), 00480 array( 'be-tarask', 'With dash' ), 00481 array( 'Zh-classical', 'Begin with upper case, dash' ), 00482 array( 'Be-x-old', 'With extension (two dashes)' ), 00483 ); 00484 } 00485 00491 public function testKnownLanguageTag( $code, $message = '' ) { 00492 $this->assertTrue( 00493 (bool)Language::isKnownLanguageTag( $code ), 00494 "validating code $code - $message" 00495 ); 00496 } 00497 00498 public static function provideKnownLanguageTags() { 00499 return array( 00500 array( 'fr', 'simple code' ), 00501 array( 'bat-smg', 'an MW legacy tag' ), 00502 array( 'sgs', 'an internal standard MW name, for which a legacy tag is used externally' ), 00503 ); 00504 } 00505 00509 public function testKnownCldrLanguageTag() { 00510 if ( !class_exists( 'LanguageNames' ) ) { 00511 $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' ); 00512 } 00513 00514 $this->assertTrue( 00515 (bool)Language::isKnownLanguageTag( 'pal' ), 00516 'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English' 00517 ); 00518 } 00519 00525 public function testUnknownLanguageTag( $code, $message = '' ) { 00526 $this->assertFalse( 00527 (bool)Language::isKnownLanguageTag( $code ), 00528 "checking that code $code is invalid - $message" 00529 ); 00530 } 00531 00532 public static function provideUnknownLanguageTags() { 00533 return array( 00534 array( 'mw', 'non-existent two-letter code' ), 00535 array( 'foo"<bar', 'very invalid language code' ), 00536 ); 00537 } 00538 00544 public function testSprintfDateTooShortTimestamp() { 00545 $this->getLang()->sprintfDate( 'xiY', '1234567890123' ); 00546 } 00547 00553 public function testSprintfDateTooLongTimestamp() { 00554 $this->getLang()->sprintfDate( 'xiY', '123456789012345' ); 00555 } 00556 00562 public function testSprintfDateNotAllDigitTimestamp() { 00563 $this->getLang()->sprintfDate( 'xiY', '-1234567890123' ); 00564 } 00565 00570 public function testSprintfDate( $format, $ts, $expected, $msg ) { 00571 $this->assertEquals( 00572 $expected, 00573 $this->getLang()->sprintfDate( $format, $ts ), 00574 "sprintfDate('$format', '$ts'): $msg" 00575 ); 00576 } 00577 00583 public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) { 00584 $oldTZ = date_default_timezone_get(); 00585 $res = date_default_timezone_set( 'Asia/Seoul' ); 00586 if ( !$res ) { 00587 $this->markTestSkipped( "Error setting Timezone" ); 00588 } 00589 00590 $this->assertEquals( 00591 $expected, 00592 $this->getLang()->sprintfDate( $format, $ts ), 00593 "sprintfDate('$format', '$ts'): $msg" 00594 ); 00595 00596 date_default_timezone_set( $oldTZ ); 00597 } 00598 00604 public function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) { 00605 $tz = new DateTimeZone( 'Asia/Seoul' ); 00606 if ( !$tz ) { 00607 $this->markTestSkipped( "Error getting Timezone" ); 00608 } 00609 00610 $this->assertEquals( 00611 $expected, 00612 $this->getLang()->sprintfDate( $format, $ts, $tz ), 00613 "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg" 00614 ); 00615 } 00616 00617 public static function provideSprintfDateSamples() { 00618 return array( 00619 array( 00620 'xiY', 00621 '20111212000000', 00622 '1390', // note because we're testing English locale we get Latin-standard digits 00623 '1390', 00624 'Iranian calendar full year' 00625 ), 00626 array( 00627 'xiy', 00628 '20111212000000', 00629 '90', 00630 '90', 00631 'Iranian calendar short year' 00632 ), 00633 array( 00634 'o', 00635 '20120101235000', 00636 '2011', 00637 '2011', 00638 'ISO 8601 (week) year' 00639 ), 00640 array( 00641 'W', 00642 '20120101235000', 00643 '52', 00644 '52', 00645 'Week number' 00646 ), 00647 array( 00648 'W', 00649 '20120102235000', 00650 '1', 00651 '1', 00652 'Week number' 00653 ), 00654 array( 00655 'o-\\WW-N', 00656 '20091231235000', 00657 '2009-W53-4', 00658 '2009-W53-4', 00659 'leap week' 00660 ), 00661 // What follows is mostly copied from https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time 00662 array( 00663 'Y', 00664 '20120102090705', 00665 '2012', 00666 '2012', 00667 'Full year' 00668 ), 00669 array( 00670 'y', 00671 '20120102090705', 00672 '12', 00673 '12', 00674 '2 digit year' 00675 ), 00676 array( 00677 'L', 00678 '20120102090705', 00679 '1', 00680 '1', 00681 'Leap year' 00682 ), 00683 array( 00684 'n', 00685 '20120102090705', 00686 '1', 00687 '1', 00688 'Month index, not zero pad' 00689 ), 00690 array( 00691 'N', 00692 '20120102090705', 00693 '01', 00694 '01', 00695 'Month index. Zero pad' 00696 ), 00697 array( 00698 'M', 00699 '20120102090705', 00700 'Jan', 00701 'Jan', 00702 'Month abbrev' 00703 ), 00704 array( 00705 'F', 00706 '20120102090705', 00707 'January', 00708 'January', 00709 'Full month' 00710 ), 00711 array( 00712 'xg', 00713 '20120102090705', 00714 'January', 00715 'January', 00716 'Genitive month name (same in EN)' 00717 ), 00718 array( 00719 'j', 00720 '20120102090705', 00721 '2', 00722 '2', 00723 'Day of month (not zero pad)' 00724 ), 00725 array( 00726 'd', 00727 '20120102090705', 00728 '02', 00729 '02', 00730 'Day of month (zero-pad)' 00731 ), 00732 array( 00733 'z', 00734 '20120102090705', 00735 '1', 00736 '1', 00737 'Day of year (zero-indexed)' 00738 ), 00739 array( 00740 'D', 00741 '20120102090705', 00742 'Mon', 00743 'Mon', 00744 'Day of week (abbrev)' 00745 ), 00746 array( 00747 'l', 00748 '20120102090705', 00749 'Monday', 00750 'Monday', 00751 'Full day of week' 00752 ), 00753 array( 00754 'N', 00755 '20120101090705', 00756 '7', 00757 '7', 00758 'Day of week (Mon=1, Sun=7)' 00759 ), 00760 array( 00761 'w', 00762 '20120101090705', 00763 '0', 00764 '0', 00765 'Day of week (Sun=0, Sat=6)' 00766 ), 00767 array( 00768 'N', 00769 '20120102090705', 00770 '1', 00771 '1', 00772 'Day of week' 00773 ), 00774 array( 00775 'a', 00776 '20120102090705', 00777 'am', 00778 'am', 00779 'am vs pm' 00780 ), 00781 array( 00782 'A', 00783 '20120102120000', 00784 'PM', 00785 'PM', 00786 'AM vs PM' 00787 ), 00788 array( 00789 'a', 00790 '20120102000000', 00791 'am', 00792 'am', 00793 'AM vs PM' 00794 ), 00795 array( 00796 'g', 00797 '20120102090705', 00798 '9', 00799 '9', 00800 '12 hour, not Zero' 00801 ), 00802 array( 00803 'h', 00804 '20120102090705', 00805 '09', 00806 '09', 00807 '12 hour, zero padded' 00808 ), 00809 array( 00810 'G', 00811 '20120102090705', 00812 '9', 00813 '9', 00814 '24 hour, not zero' 00815 ), 00816 array( 00817 'H', 00818 '20120102090705', 00819 '09', 00820 '09', 00821 '24 hour, zero' 00822 ), 00823 array( 00824 'H', 00825 '20120102110705', 00826 '11', 00827 '11', 00828 '24 hour, zero' 00829 ), 00830 array( 00831 'i', 00832 '20120102090705', 00833 '07', 00834 '07', 00835 'Minutes' 00836 ), 00837 array( 00838 's', 00839 '20120102090705', 00840 '05', 00841 '05', 00842 'seconds' 00843 ), 00844 array( 00845 'U', 00846 '20120102090705', 00847 '1325495225', 00848 '1325462825', 00849 'unix time' 00850 ), 00851 array( 00852 't', 00853 '20120102090705', 00854 '31', 00855 '31', 00856 'Days in current month' 00857 ), 00858 array( 00859 'c', 00860 '20120102090705', 00861 '2012-01-02T09:07:05+00:00', 00862 '2012-01-02T09:07:05+09:00', 00863 'ISO 8601 timestamp' 00864 ), 00865 array( 00866 'r', 00867 '20120102090705', 00868 'Mon, 02 Jan 2012 09:07:05 +0000', 00869 'Mon, 02 Jan 2012 09:07:05 +0900', 00870 'RFC 5322' 00871 ), 00872 array( 00873 'e', 00874 '20120102090705', 00875 'UTC', 00876 'Asia/Seoul', 00877 'Timezone identifier' 00878 ), 00879 array( 00880 'I', 00881 '19880602090705', 00882 '0', 00883 '1', 00884 'DST indicator' 00885 ), 00886 array( 00887 'O', 00888 '20120102090705', 00889 '+0000', 00890 '+0900', 00891 'Timezone offset' 00892 ), 00893 array( 00894 'P', 00895 '20120102090705', 00896 '+00:00', 00897 '+09:00', 00898 'Timezone offset with colon' 00899 ), 00900 array( 00901 'T', 00902 '20120102090705', 00903 'UTC', 00904 'KST', 00905 'Timezone abbreviation' 00906 ), 00907 array( 00908 'Z', 00909 '20120102090705', 00910 '0', 00911 '32400', 00912 'Timezone offset in seconds' 00913 ), 00914 array( 00915 'xmj xmF xmn xmY', 00916 '20120102090705', 00917 '7 Safar 2 1433', 00918 '7 Safar 2 1433', 00919 'Islamic' 00920 ), 00921 array( 00922 'xij xiF xin xiY', 00923 '20120102090705', 00924 '12 Dey 10 1390', 00925 '12 Dey 10 1390', 00926 'Iranian' 00927 ), 00928 array( 00929 'xjj xjF xjn xjY', 00930 '20120102090705', 00931 '7 Tevet 4 5772', 00932 '7 Tevet 4 5772', 00933 'Hebrew' 00934 ), 00935 array( 00936 'xjt', 00937 '20120102090705', 00938 '29', 00939 '29', 00940 'Hebrew number of days in month' 00941 ), 00942 array( 00943 'xjx', 00944 '20120102090705', 00945 'Tevet', 00946 'Tevet', 00947 'Hebrew genitive month name (No difference in EN)' 00948 ), 00949 array( 00950 'xkY', 00951 '20120102090705', 00952 '2555', 00953 '2555', 00954 'Thai year' 00955 ), 00956 array( 00957 'xoY', 00958 '20120102090705', 00959 '101', 00960 '101', 00961 'Minguo' 00962 ), 00963 array( 00964 'xtY', 00965 '20120102090705', 00966 '平成24', 00967 '平成24', 00968 'nengo' 00969 ), 00970 array( 00971 'xrxkYY', 00972 '20120102090705', 00973 'MMDLV2012', 00974 'MMDLV2012', 00975 'Roman numerals' 00976 ), 00977 array( 00978 'xhxjYY', 00979 '20120102090705', 00980 'ה\'תשע"ב2012', 00981 'ה\'תשע"ב2012', 00982 'Hebrew numberals' 00983 ), 00984 array( 00985 'xnY', 00986 '20120102090705', 00987 '2012', 00988 '2012', 00989 'Raw numerals (doesn\'t mean much in EN)' 00990 ), 00991 array( 00992 '[[Y "(yea"\\r)]] \\"xx\\"', 00993 '20120102090705', 00994 '[[2012 (year)]] "x"', 00995 '[[2012 (year)]] "x"', 00996 'Various escaping' 00997 ), 00998 00999 ); 01000 } 01001 01006 public function testFormatSize( $size, $expected, $msg ) { 01007 $this->assertEquals( 01008 $expected, 01009 $this->getLang()->formatSize( $size ), 01010 "formatSize('$size'): $msg" 01011 ); 01012 } 01013 01014 public static function provideFormatSizes() { 01015 return array( 01016 array( 01017 0, 01018 "0 B", 01019 "Zero bytes" 01020 ), 01021 array( 01022 1024, 01023 "1 KB", 01024 "1 kilobyte" 01025 ), 01026 array( 01027 1024 * 1024, 01028 "1 MB", 01029 "1,024 megabytes" 01030 ), 01031 array( 01032 1024 * 1024 * 1024, 01033 "1 GB", 01034 "1 gigabytes" 01035 ), 01036 array( 01037 pow( 1024, 4 ), 01038 "1 TB", 01039 "1 terabyte" 01040 ), 01041 array( 01042 pow( 1024, 5 ), 01043 "1 PB", 01044 "1 petabyte" 01045 ), 01046 array( 01047 pow( 1024, 6 ), 01048 "1 EB", 01049 "1,024 exabyte" 01050 ), 01051 array( 01052 pow( 1024, 7 ), 01053 "1 ZB", 01054 "1 zetabyte" 01055 ), 01056 array( 01057 pow( 1024, 8 ), 01058 "1 YB", 01059 "1 yottabyte" 01060 ), 01061 // How big!? THIS BIG! 01062 ); 01063 } 01064 01069 public function testFormatBitrate( $bps, $expected, $msg ) { 01070 $this->assertEquals( 01071 $expected, 01072 $this->getLang()->formatBitrate( $bps ), 01073 "formatBitrate('$bps'): $msg" 01074 ); 01075 } 01076 01077 public static function provideFormatBitrate() { 01078 return array( 01079 array( 01080 0, 01081 "0 bps", 01082 "0 bits per second" 01083 ), 01084 array( 01085 999, 01086 "999 bps", 01087 "999 bits per second" 01088 ), 01089 array( 01090 1000, 01091 "1 kbps", 01092 "1 kilobit per second" 01093 ), 01094 array( 01095 1000 * 1000, 01096 "1 Mbps", 01097 "1 megabit per second" 01098 ), 01099 array( 01100 pow( 10, 9 ), 01101 "1 Gbps", 01102 "1 gigabit per second" 01103 ), 01104 array( 01105 pow( 10, 12 ), 01106 "1 Tbps", 01107 "1 terabit per second" 01108 ), 01109 array( 01110 pow( 10, 15 ), 01111 "1 Pbps", 01112 "1 petabit per second" 01113 ), 01114 array( 01115 pow( 10, 18 ), 01116 "1 Ebps", 01117 "1 exabit per second" 01118 ), 01119 array( 01120 pow( 10, 21 ), 01121 "1 Zbps", 01122 "1 zetabit per second" 01123 ), 01124 array( 01125 pow( 10, 24 ), 01126 "1 Ybps", 01127 "1 yottabit per second" 01128 ), 01129 array( 01130 pow( 10, 27 ), 01131 "1,000 Ybps", 01132 "1,000 yottabits per second" 01133 ), 01134 ); 01135 } 01136 01141 public function testFormatDuration( $duration, $expected, $intervals = array() ) { 01142 $this->assertEquals( 01143 $expected, 01144 $this->getLang()->formatDuration( $duration, $intervals ), 01145 "formatDuration('$duration'): $expected" 01146 ); 01147 } 01148 01149 public static function provideFormatDuration() { 01150 return array( 01151 array( 01152 0, 01153 '0 seconds', 01154 ), 01155 array( 01156 1, 01157 '1 second', 01158 ), 01159 array( 01160 2, 01161 '2 seconds', 01162 ), 01163 array( 01164 60, 01165 '1 minute', 01166 ), 01167 array( 01168 2 * 60, 01169 '2 minutes', 01170 ), 01171 array( 01172 3600, 01173 '1 hour', 01174 ), 01175 array( 01176 2 * 3600, 01177 '2 hours', 01178 ), 01179 array( 01180 24 * 3600, 01181 '1 day', 01182 ), 01183 array( 01184 2 * 86400, 01185 '2 days', 01186 ), 01187 array( 01188 // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952 01189 ( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400, 01190 '1 year', 01191 ), 01192 array( 01193 2 * 31556952, 01194 '2 years', 01195 ), 01196 array( 01197 10 * 31556952, 01198 '1 decade', 01199 ), 01200 array( 01201 20 * 31556952, 01202 '2 decades', 01203 ), 01204 array( 01205 100 * 31556952, 01206 '1 century', 01207 ), 01208 array( 01209 200 * 31556952, 01210 '2 centuries', 01211 ), 01212 array( 01213 1000 * 31556952, 01214 '1 millennium', 01215 ), 01216 array( 01217 2000 * 31556952, 01218 '2 millennia', 01219 ), 01220 array( 01221 9001, 01222 '2 hours, 30 minutes and 1 second' 01223 ), 01224 array( 01225 3601, 01226 '1 hour and 1 second' 01227 ), 01228 array( 01229 31556952 + 2 * 86400 + 9000, 01230 '1 year, 2 days, 2 hours and 30 minutes' 01231 ), 01232 array( 01233 42 * 1000 * 31556952 + 42, 01234 '42 millennia and 42 seconds' 01235 ), 01236 array( 01237 60, 01238 '60 seconds', 01239 array( 'seconds' ), 01240 ), 01241 array( 01242 61, 01243 '61 seconds', 01244 array( 'seconds' ), 01245 ), 01246 array( 01247 1, 01248 '1 second', 01249 array( 'seconds' ), 01250 ), 01251 array( 01252 31556952 + 2 * 86400 + 9000, 01253 '1 year, 2 days and 150 minutes', 01254 array( 'years', 'days', 'minutes' ), 01255 ), 01256 array( 01257 42, 01258 '0 days', 01259 array( 'years', 'days' ), 01260 ), 01261 array( 01262 31556952 + 2 * 86400 + 9000, 01263 '1 year, 2 days and 150 minutes', 01264 array( 'minutes', 'days', 'years' ), 01265 ), 01266 array( 01267 42, 01268 '0 days', 01269 array( 'days', 'years' ), 01270 ), 01271 ); 01272 } 01273 01278 public function testCheckTitleEncoding( $s ) { 01279 $this->assertEquals( 01280 $s, 01281 $this->getLang()->checkTitleEncoding( $s ), 01282 "checkTitleEncoding('$s')" 01283 ); 01284 } 01285 01286 public static function provideCheckTitleEncodingData() { 01287 return array( 01288 array( "" ), 01289 array( "United States of America" ), // 7bit ASCII 01290 array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ), 01291 array( 01292 rawurldecode( 01293 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn" 01294 ) 01295 ), 01296 // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for 01297 // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding 01298 // uses mb_check_encoding for its test. 01299 array( 01300 rawurldecode( 01301 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C" 01302 . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C" 01303 . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C" 01304 . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C" 01305 . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C" 01306 . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C" 01307 . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C" 01308 . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C" 01309 . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C" 01310 . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C" 01311 . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C" 01312 . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C" 01313 . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C" 01314 . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis" 01315 ), 01316 ), 01317 array( 01318 rawurldecode( 01319 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C" 01320 . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C" 01321 . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C" 01322 . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C" 01323 . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou" 01324 . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C" 01325 . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C" 01326 . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C" 01327 . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C" 01328 . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C" 01329 . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C" 01330 . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C" 01331 . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C" 01332 . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C" 01333 . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes" 01334 ) 01335 ) 01336 ); 01337 } 01338 01343 public function testRomanNumerals( $num, $numerals ) { 01344 $this->assertEquals( 01345 $numerals, 01346 Language::romanNumeral( $num ), 01347 "romanNumeral('$num')" 01348 ); 01349 } 01350 01351 public static function provideRomanNumeralsData() { 01352 return array( 01353 array( 1, 'I' ), 01354 array( 2, 'II' ), 01355 array( 3, 'III' ), 01356 array( 4, 'IV' ), 01357 array( 5, 'V' ), 01358 array( 6, 'VI' ), 01359 array( 7, 'VII' ), 01360 array( 8, 'VIII' ), 01361 array( 9, 'IX' ), 01362 array( 10, 'X' ), 01363 array( 20, 'XX' ), 01364 array( 30, 'XXX' ), 01365 array( 40, 'XL' ), 01366 array( 49, 'XLIX' ), 01367 array( 50, 'L' ), 01368 array( 60, 'LX' ), 01369 array( 70, 'LXX' ), 01370 array( 80, 'LXXX' ), 01371 array( 90, 'XC' ), 01372 array( 99, 'XCIX' ), 01373 array( 100, 'C' ), 01374 array( 200, 'CC' ), 01375 array( 300, 'CCC' ), 01376 array( 400, 'CD' ), 01377 array( 500, 'D' ), 01378 array( 600, 'DC' ), 01379 array( 700, 'DCC' ), 01380 array( 800, 'DCCC' ), 01381 array( 900, 'CM' ), 01382 array( 999, 'CMXCIX' ), 01383 array( 1000, 'M' ), 01384 array( 1989, 'MCMLXXXIX' ), 01385 array( 2000, 'MM' ), 01386 array( 3000, 'MMM' ), 01387 array( 4000, 'MMMM' ), 01388 array( 5000, 'MMMMM' ), 01389 array( 6000, 'MMMMMM' ), 01390 array( 7000, 'MMMMMMM' ), 01391 array( 8000, 'MMMMMMMM' ), 01392 array( 9000, 'MMMMMMMMM' ), 01393 array( 9999, 'MMMMMMMMMCMXCIX' ), 01394 array( 10000, 'MMMMMMMMMM' ), 01395 ); 01396 } 01397 01402 public function testConvertPlural( $expected, $number, $forms ) { 01403 $chosen = $this->getLang()->convertPlural( $number, $forms ); 01404 $this->assertEquals( $expected, $chosen ); 01405 } 01406 01407 public static function providePluralData() { 01408 // Params are: [expected text, number given, [the plural forms]] 01409 return array( 01410 array( 'plural', 0, array( 01411 'singular', 'plural' 01412 ) ), 01413 array( 'explicit zero', 0, array( 01414 '0=explicit zero', 'singular', 'plural' 01415 ) ), 01416 array( 'explicit one', 1, array( 01417 'singular', 'plural', '1=explicit one', 01418 ) ), 01419 array( 'singular', 1, array( 01420 'singular', 'plural', '0=explicit zero', 01421 ) ), 01422 array( 'plural', 3, array( 01423 '0=explicit zero', '1=explicit one', 'singular', 'plural' 01424 ) ), 01425 array( 'explicit eleven', 11, array( 01426 'singular', 'plural', '11=explicit eleven', 01427 ) ), 01428 array( 'plural', 12, array( 01429 'singular', 'plural', '11=explicit twelve', 01430 ) ), 01431 array( 'plural', 12, array( 01432 'singular', 'plural', '=explicit form', 01433 ) ), 01434 array( 'other', 2, array( 01435 'kissa=kala', '1=2=3', 'other', 01436 ) ), 01437 array( '', 2, array( 01438 '0=explicit zero', '1=explicit one', 01439 ) ), 01440 ); 01441 } 01442 01447 public function testTranslateBlockExpiry( $expectedData, $str, $desc ) { 01448 $lang = $this->getLang(); 01449 if ( is_array( $expectedData ) ) { 01450 list( $func, $arg ) = $expectedData; 01451 $expected = $lang->$func( $arg ); 01452 } else { 01453 $expected = $expectedData; 01454 } 01455 $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc ); 01456 } 01457 01458 public static function provideTranslateBlockExpiry() { 01459 return array( 01460 array( '2 hours', '2 hours', 'simple data from ipboptions' ), 01461 array( 'indefinite', 'infinite', 'infinite from ipboptions' ), 01462 array( 'indefinite', 'infinity', 'alternative infinite from ipboptions' ), 01463 array( 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ), 01464 array( array( 'formatDuration', 1023 * 60 * 60 ), '1023 hours', 'relative' ), 01465 array( array( 'formatDuration', -1023 ), '-1023 seconds', 'negative relative' ), 01466 array( array( 'formatDuration', 0 ), 'now', 'now' ), 01467 array( array( 'timeanddate', '20120102070000' ), '2012-1-1 7:00 +1 day', 'mixed, handled as absolute' ), 01468 array( array( 'timeanddate', '19910203040506' ), '1991-2-3 4:05:06', 'absolute' ), 01469 array( array( 'timeanddate', '19700101000000' ), '1970-1-1 0:00:00', 'absolute at epoch' ), 01470 array( array( 'timeanddate', '19691231235959' ), '1969-12-31 23:59:59', 'time before epoch' ), 01471 array( 'dummy', 'dummy', 'return garbage as is' ), 01472 ); 01473 } 01474 01479 public function testCommafy( $number, $numbersWithCommas ) { 01480 $this->assertEquals( 01481 $numbersWithCommas, 01482 $this->getLang()->commafy( $number ), 01483 "commafy('$number')" 01484 ); 01485 } 01486 01487 public static function provideCommafyData() { 01488 return array( 01489 array( -1, '-1' ), 01490 array( 10, '10' ), 01491 array( 100, '100' ), 01492 array( 1000, '1,000' ), 01493 array( 10000, '10,000' ), 01494 array( 100000, '100,000' ), 01495 array( 1000000, '1,000,000' ), 01496 array( -1.0001, '-1.0001' ), 01497 array( 1.0001, '1.0001' ), 01498 array( 10.0001, '10.0001' ), 01499 array( 100.0001, '100.0001' ), 01500 array( 1000.0001, '1,000.0001' ), 01501 array( 10000.0001, '10,000.0001' ), 01502 array( 100000.0001, '100,000.0001' ), 01503 array( 1000000.0001, '1,000,000.0001' ), 01504 array( '200000000000000000000', '200,000,000,000,000,000,000' ), 01505 array( '-200000000000000000000', '-200,000,000,000,000,000,000' ), 01506 ); 01507 } 01508 01512 public function testListToText() { 01513 $lang = $this->getLang(); 01514 $and = $lang->getMessageFromDB( 'and' ); 01515 $s = $lang->getMessageFromDB( 'word-separator' ); 01516 $c = $lang->getMessageFromDB( 'comma-separator' ); 01517 01518 $this->assertEquals( '', $lang->listToText( array() ) ); 01519 $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) ); 01520 $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) ); 01521 $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) ); 01522 $this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) ); 01523 } 01524 01529 public function testIsSupportedLanguage( $code, $expected, $comment ) { 01530 $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment ); 01531 } 01532 01533 public static function provideIsSupportedLanguage() { 01534 return array( 01535 array( 'en', true, 'is supported language' ), 01536 array( 'fi', true, 'is supported language' ), 01537 array( 'bunny', false, 'is not supported language' ), 01538 array( 'FI', false, 'is not supported language, input should be in lower case' ), 01539 ); 01540 } 01541 01546 public function testGetParentLanguage( $code, $expected, $comment ) { 01547 $lang = Language::factory( $code ); 01548 if ( is_null( $expected ) ) { 01549 $this->assertNull( $lang->getParentLanguage(), $comment ); 01550 } else { 01551 $this->assertEquals( $expected, $lang->getParentLanguage()->getCode(), $comment ); 01552 } 01553 } 01554 01555 public static function provideGetParentLanguage() { 01556 return array( 01557 array( 'zh-cn', 'zh', 'zh is the parent language of zh-cn' ), 01558 array( 'zh', 'zh', 'zh is defined as the parent language of zh, because zh converter can convert zh-cn to zh' ), 01559 array( 'zh-invalid', null, 'do not be fooled by arbitrarily composed language codes' ), 01560 array( 'en-gb', null, 'en does not have converter' ), 01561 array( 'en', null, 'en does not have converter. Although FakeConverter handles en -> en conversion but it is useless' ), 01562 ); 01563 } 01564 01569 public function testGetNamespaceAliases( $languageCode, $subset ) { 01570 $language = Language::factory( $languageCode ); 01571 $aliases = $language->getNamespaceAliases(); 01572 foreach ( $subset as $alias => $nsId ) { 01573 $this->assertEquals( $nsId, $aliases[$alias] ); 01574 } 01575 } 01576 01577 public static function provideGetNamespaceAliases() { 01578 // TODO: Add tests for NS_PROJECT_TALK and GenderNamespaces 01579 return array( 01580 array( 01581 'zh', 01582 array( 01583 '文件' => NS_FILE, 01584 '檔案' => NS_FILE, 01585 ), 01586 ), 01587 ); 01588 } 01589 }