3use Wikimedia\TestingAccessWrapper;
12 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
13 $this->
getLang()->normalizeForSearch(
14 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
16 'convertDoubleWidth() with the full alphabet and digits'
25 $this->assertEquals( $expected, $this->
getLang()->formatTimePeriod( $seconds, $format ), $desc );
34 'formatTimePeriod() rounding (<10s)'
38 [
'noabbrevs' =>
true ],
40 'formatTimePeriod() rounding (<10s)'
46 'formatTimePeriod() rounding (<10s)'
50 [
'noabbrevs' =>
true ],
52 'formatTimePeriod() rounding (<10s)'
58 'formatTimePeriod() rounding (<60s)'
62 [
'noabbrevs' =>
true ],
64 'formatTimePeriod() rounding (<60s)'
70 'formatTimePeriod() rounding (<1h)'
74 [
'noabbrevs' =>
true ],
75 '2 minutes 0 seconds',
76 'formatTimePeriod() rounding (<1h)'
82 'formatTimePeriod() rounding (<1h)'
86 [
'noabbrevs' =>
true ],
87 '1 hour 0 minutes 0 seconds',
88 'formatTimePeriod() rounding (<1h)'
94 'formatTimePeriod() rounding (>=1h)'
98 [
'noabbrevs' =>
true ],
99 '2 hours 0 minutes 0 seconds',
100 'formatTimePeriod() rounding (>=1h)'
106 'formatTimePeriod() rounding (>=1h), avoidseconds'
110 [
'avoid' =>
'avoidseconds',
'noabbrevs' =>
true ],
112 'formatTimePeriod() rounding (>=1h), avoidseconds'
118 'formatTimePeriod() rounding (>=1h), avoidminutes'
122 [
'avoid' =>
'avoidminutes',
'noabbrevs' =>
true ],
124 'formatTimePeriod() rounding (>=1h), avoidminutes'
130 'formatTimePeriod() rounding (=48h), avoidseconds'
134 [
'avoid' =>
'avoidseconds',
'noabbrevs' =>
true ],
135 '48 hours 0 minutes',
136 'formatTimePeriod() rounding (=48h), avoidseconds'
142 'formatTimePeriod() rounding (>48h), avoidminutes'
146 [
'avoid' =>
'avoidminutes',
'noabbrevs' =>
true ],
148 'formatTimePeriod() rounding (>48h), avoidminutes'
154 'formatTimePeriod() rounding (>48h), avoidseconds'
158 [
'avoid' =>
'avoidseconds',
'noabbrevs' =>
true ],
159 '2 days 1 hour 0 minutes',
160 'formatTimePeriod() rounding (>48h), avoidseconds'
166 'formatTimePeriod() rounding (>48h), avoidminutes'
170 [
'avoid' =>
'avoidminutes',
'noabbrevs' =>
true ],
172 'formatTimePeriod() rounding (>48h), avoidminutes'
178 'formatTimePeriod() rounding (>48h), avoidseconds'
182 [
'avoid' =>
'avoidseconds',
'noabbrevs' =>
true ],
183 '3 days 0 hours 0 minutes',
184 'formatTimePeriod() rounding (>48h), avoidseconds'
190 'formatTimePeriod() rounding, (>48h), avoidseconds'
194 [
'avoid' =>
'avoidseconds',
'noabbrevs' =>
true ],
195 '2 days 0 hours 0 minutes',
196 'formatTimePeriod() rounding, (>48h), avoidseconds'
202 'formatTimePeriod() rounding, recursion, (>48h)'
206 [
'noabbrevs' =>
true ],
207 '2 days 1 hour 1 minute 1 second',
208 'formatTimePeriod() rounding, recursion, (>48h)'
220 $this->
getLang()->truncateForDatabase(
"1234567890", 0,
'XXX' ),
221 'truncate prefix, len 0, small ellipsis'
226 $this->
getLang()->truncateForDatabase(
"1234567890", 8,
'XXX' ),
227 'truncate prefix, small ellipsis'
232 $this->
getLang()->truncateForDatabase(
"123456789", 5,
'XXXXXXXXXXXXXXX' ),
233 'truncate prefix, large ellipsis'
238 $this->
getLang()->truncateForDatabase(
"1234567890", -8,
'XXX' ),
239 'truncate suffix, small ellipsis'
244 $this->
getLang()->truncateForDatabase(
"123456789", -5,
'XXXXXXXXXXXXXXX' ),
245 'truncate suffix, large ellipsis'
249 $this->
getLang()->truncateForDatabase(
"123 ", 9,
'XXX' ),
250 'truncate prefix, with spaces'
254 $this->
getLang()->truncateForDatabase(
"12345 8", 11,
'XXX' ),
255 'truncate prefix, with spaces and non-space ending'
259 $this->
getLang()->truncateForDatabase(
"1 234", -8,
'XXX' ),
260 'truncate suffix, with spaces'
264 $this->
getLang()->truncateForDatabase(
"1234567890", 5,
'XXX',
false ),
265 'truncate without adjustment'
269 $this->
getLang()->truncateForDatabase(
"泰乐菌素123456789", 11,
'...',
false ),
270 'truncate does not chop Unicode characters in half'
274 $this->
getLang()->truncateForDatabase(
"\n泰乐菌素123456789", 12,
'...',
false ),
275 'truncate does not chop Unicode characters in half if there is a preceding newline'
285 $expected, $string, $length, $ellipsis =
'...', $adjustLength =
true
289 $this->
getLang()->truncateForVisual( $string, $length, $ellipsis, $adjustLength )
298 [
"XXX",
"тестирам да ли ради", 0,
"XXX" ],
299 [
"testnXXX",
"testni scenarij", 8,
"XXX" ],
300 [
"حالة اختبار",
"حالة اختبار", 5,
"XXXXXXXXXXXXXXX" ],
301 [
"XXXедент",
"прецедент", -8,
"XXX" ],
302 [
"XXപിൾ",
"ആപ്പിൾ", -5,
"XX" ],
303 [
"神秘XXX",
"神秘 ", 9,
"XXX" ],
304 [
"ΔημιουργXXX",
"Δημιουργία Σύμπαντος", 11,
"XXX" ],
305 [
"XXXの家です",
"地球は私たちの唯 の家です", -8,
"XXX" ],
306 [
"زندگیXXX",
"زندگی زیباست", 6,
"XXX",
false ],
307 [
"ცხოვრება...",
"ცხოვრება არის საოცარი", 8,
"...",
false ],
308 [
"\nທ່ານ...",
"\nທ່ານບໍ່ຮູ້ຫນັງສື", 5,
"...",
false ],
329 [ 0,
'XXX',
"1234567890",
"XXX" ],
330 [ 8,
'XXX',
"1234567890",
"12345XXX" ],
331 [ 5,
'XXXXXXXXXXXXXXX',
'1234567890',
"1234567890" ],
333 '<p><span style="font-weight:bold;"></span></p>',
334 '<p><span style="font-weight:bold;"></span></p>',
337 '<p><span style="font-weight:bold;">123456789</span></p>',
338 '<p><span style="font-weight:bold;">***</span></p>',
341 '<p><span style="font-weight:bold;"> 23456789</span></p>',
342 '<p><span style="font-weight:bold;">***</span></p>',
345 '<p><span style="font-weight:bold;">123456789</span></p>',
346 '<p><span style="font-weight:bold;">***</span></p>',
349 '<p><span style="font-weight:bold;">123456789</span></p>',
350 '<p><span style="font-weight:bold;">1***</span></p>',
353 '<tt><span style="font-weight:bold;">123456789</span></tt>',
354 '<tt><span style="font-weight:bold;">12***</span></tt>',
357 '<p><a href="www.mediawiki.org">123456789</a></p>',
358 '<p><a href="www.mediawiki.org">123***</a></p>',
361 '<p><a href="www.mediawiki.org">12 456789</a></p>',
362 '<p><a href="www.mediawiki.org">12 ***</a></p>',
365 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
366 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
369 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
370 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
373 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
374 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
377 '<p><font style="font-weight:bold;">123456789</font></p>',
378 '<p><font style="font-weight:bold;">123456789</font></p>',
390 Language::isWellFormedLanguageTag(
$code ),
391 "validating code $code $message"
403 [
'fr',
'two-letter code' ],
404 [
'fr-latn',
'two-letter code with lower case script code' ],
405 [
'fr-Latn-FR',
'two-letter code with title case script code and uppercase country code' ],
406 [
'fr-Latn-419',
'two-letter code with title case script code and region number' ],
407 [
'fr-FR',
'two-letter code with uppercase' ],
408 [
'ax-TZ',
'Not in the registry, but well-formed' ],
409 [
'fr-shadok',
'two-letter code with variant' ],
410 [
'fr-y-myext-myext2',
'non-x singleton' ],
411 [
'fra-Latn',
'ISO 639 can be 3-letters' ],
412 [
'fra',
'three-letter language code' ],
413 [
'fra-FX',
'three-letter language code with country code' ],
414 [
'i-klingon',
'grandfathered with singleton' ],
415 [
'I-kLINgon',
'tags are case-insensitive...' ],
416 [
'no-bok',
'grandfathered without singleton' ],
417 [
'i-enochian',
'Grandfathered' ],
418 [
'x-fr-CH',
'private use' ],
419 [
'es-419',
'two-letter code with region number' ],
420 [
'en-Latn-GB-boont-r-extended-sequence-x-private',
'weird, but well-formed' ],
421 [
'ab-x-abc-x-abc',
'anything goes after x' ],
422 [
'ab-x-abc-a-a',
'anything goes after x, including several non-x singletons' ],
423 [
'i-default',
'grandfathered' ],
424 [
'abcd-Latn',
'Language of 4 chars reserved for future use' ],
425 [
'AaBbCcDd-x-y-any-x',
'Language of 5-8 chars, registered' ],
426 [
'de-CH-1901',
'with country and year' ],
427 [
'en-US-x-twain',
'with country and singleton' ],
428 [
'zh-cmn',
'three-letter variant' ],
429 [
'zh-cmn-Hant',
'three-letter variant and script' ],
430 [
'zh-cmn-Hant-HK',
'three-letter variant, script and country' ],
431 [
'xr-p-lze',
'Extension' ],
442 Language::isWellFormedLanguageTag(
$code ),
443 "validating that code $code is a malformed language tag - $message"
455 [
'f',
'language too short' ],
456 [
'f-Latn',
'language too short with script' ],
457 [
'xr-lxs-qut',
'variants too short' ], # extlangS
458 [
'fr-Latn-F',
'region too short' ],
459 [
'a-value',
'language too short with region' ],
460 [
'tlh-a-b-foo',
'valid three-letter with wrong variant' ],
463 'grandfathered but not registered: invalid, even if we only test well-formedness'
465 [
'abcdefghi-012345678',
'numbers too long' ],
466 [
'ab-abc-abc-abc-abc',
'invalid extensions' ],
467 [
'ab-abcd-abc',
'invalid extensions' ],
468 [
'ab-ab-abc',
'invalid extensions' ],
469 [
'ab-123-abc',
'invalid extensions' ],
470 [
'a-Hant-ZH',
'short language with valid extensions' ],
471 [
'a1-Hant-ZH',
'invalid character in language' ],
472 [
'ab-abcde-abc',
'invalid extensions' ],
473 [
'ab-1abc-abc',
'invalid characters in extensions' ],
474 [
'ab-ab-abcd',
'invalid order of extensions' ],
475 [
'ab-123-abcd',
'invalid order of extensions' ],
476 [
'ab-abcde-abcd',
'invalid extensions' ],
477 [
'ab-1abc-abcd',
'invalid characters in extensions' ],
478 [
'ab-a-b',
'extensions too short' ],
479 [
'ab-a-x',
'extensions too short, even with singleton' ],
480 [
'ab--ab',
'two separators' ],
481 [
'ab-abc-',
'separator in the end' ],
482 [
'-ab-abc',
'separator in the beginning' ],
483 [
'abcd-efg',
'language too long' ],
484 [
'aabbccddE',
'tag too long' ],
485 [
'pa_guru',
'A tag with underscore is invalid in strict mode' ],
486 [
'de-f',
'subtag too short' ],
496 Language::isWellFormedLanguageTag(
'pa_guru',
true ),
497 'pa_guru is a well-formed language tag in lenient mode'
507 $this->assertEquals( $expected,
508 (
bool)Language::isValidBuiltInCode(
$code ),
509 "validating code $code $message"
515 [
'fr',
true,
'Two letters, minor case' ],
516 [
'EN',
false,
'Two letters, upper case' ],
517 [
'tyv',
true,
'Three letters' ],
518 [
'be-tarask',
true,
'With dash' ],
519 [
'be-x-old',
true,
'With extension (two dashes)' ],
520 [
'be_tarask',
false,
'Reject underscores' ],
531 (
bool)Language::isKnownLanguageTag(
$code ),
532 "validating code $code - $message"
538 [
'fr',
'simple code' ],
539 [
'bat-smg',
'an MW legacy tag' ],
540 [
'sgs',
'an internal standard MW name, for which a legacy tag is used externally' ],
548 if ( !class_exists(
'LanguageNames' ) ) {
549 $this->markTestSkipped(
'The LanguageNames class is not available. '
550 .
'The CLDR extension is probably not installed.' );
554 (
bool)Language::isKnownLanguageTag(
'pal' ),
555 'validating code "pal" an ancient language, which probably will '
556 .
'not appear in Names.php, but appears in CLDR in English'
567 (
bool)Language::isKnownLanguageTag(
$code ),
568 "checking that code $code is invalid - $message"
574 [
'mw',
'non-existent two-letter code' ],
575 [
'foo"<bar',
'very invalid language code' ],
585 $this->
getLang()->sprintfDate(
'xiY',
'1234567890123' );
594 $this->
getLang()->sprintfDate(
'xiY',
'123456789012345' );
603 $this->
getLang()->sprintfDate(
'xiY',
'-1234567890123' );
614 $this->
getLang()->sprintfDate( $format, $ts,
null, $ttl ),
615 "sprintfDate('$format', '$ts'): $msg"
618 $dt =
new DateTime( $ts );
619 $lastValidTS = $dt->add(
new DateInterval(
'PT' . ( $ttl - 1 ) .
'S' ) )->format(
'YmdHis' );
622 $this->
getLang()->sprintfDate( $format, $lastValidTS,
null ),
623 "sprintfDate('$format', '$ts'): TTL $ttl too high (output was different at $lastValidTS)"
627 $dt =
new DateTime( $ts );
628 $newTS = $dt->add(
new DateInterval(
'P1Y1M8DT13H1M1S' ) )->format(
'YmdHis' );
631 $this->
getLang()->sprintfDate( $format, $newTS,
null ),
632 "sprintfDate('$format', '$ts'): Missing TTL (output was different at $newTS)"
643 $oldTZ = date_default_timezone_get();
644 $res = date_default_timezone_set(
'Asia/Seoul' );
646 $this->markTestSkipped(
"Error setting Timezone" );
651 $this->
getLang()->sprintfDate( $format, $ts ),
652 "sprintfDate('$format', '$ts'): $msg"
655 date_default_timezone_set( $oldTZ );
664 $tz =
new DateTimeZone(
'Asia/Seoul' );
666 $this->markTestSkipped(
"Error getting Timezone" );
671 $this->
getLang()->sprintfDate( $format, $ts, $tz ),
672 "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg"
689 'If the caller does not set the $ttl variable, do not compute it.'
691 $this->assertInternalType(
'int', $ttl,
'TTL should have been computed.' );
701 'Iranian calendar full year'
708 'Iranian calendar short year'
715 'ISO 8601 (week) year'
766 'Month index, not zero pad'
773 'Month index. Zero pad'
794 'Genitive month name (same in EN)'
801 'Day of month (not zero pad)'
808 'Day of month (zero-pad)'
815 'Day of year (zero-indexed)'
822 'Day of week (abbrev)'
836 'Day of week (Mon=1, Sun=7)'
843 'Day of week (Sun=0, Sat=6)'
885 '12 hour, zero padded'
934 'Days in current month'
939 '2012-01-02T09:07:05+00:00',
940 '2012-01-02T09:07:05+09:00',
946 'Mon, 02 Jan 2012 09:07:05 +0000',
947 'Mon, 02 Jan 2012 09:07:05 +0900',
955 'Timezone identifier'
976 'Timezone offset with colon'
983 'Timezone abbreviation'
990 'Timezone offset in seconds'
1018 'Hebrew number of days in month'
1025 'Hebrew genitive month name (No difference in EN)'
1060 'nengo - last day of heisei'
1067 'nengo - first day of reiwa'
1074 'nengo - second year of reiwa'
1095 'Raw numerals (doesn\'t mean much in EN)'
1098 '[[Y "(yea"\\r)]] \\"xx\\"',
1100 '[[2012 (year)]] "x"',
1101 '[[2012 (year)]] "x"',
1113 $this->assertEquals(
1115 $this->
getLang()->formatSize( $size ),
1116 "formatSize('$size'): $msg"
1176 $this->assertEquals(
1178 $this->
getLang()->formatBitrate( $bps ),
1179 "formatBitrate('$bps'): $msg"
1193 "999 bits per second"
1198 "1 kilobit per second"
1203 "1 megabit per second"
1208 "1 gigabit per second"
1213 "1 terabit per second"
1218 "1 petabit per second"
1223 "1 exabit per second"
1228 "1 zetabit per second"
1233 "1 yottabit per second"
1238 "1,000 yottabits per second"
1248 $this->assertEquals(
1250 $this->
getLang()->formatDuration( $duration, $intervals ),
1251 "formatDuration('$duration'): $expected"
1295 ( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400,
1328 '2 hours, 30 minutes and 1 second'
1332 '1 hour and 1 second'
1335 31556952 + 2 * 86400 + 9000,
1336 '1 year, 2 days, 2 hours and 30 minutes'
1339 42 * 1000 * 31556952 + 42,
1340 '42 millennia and 42 seconds'
1358 31556952 + 2 * 86400 + 9000,
1359 '1 year, 2 days and 150 minutes',
1360 [
'years',
'days',
'minutes' ],
1365 [
'years',
'days' ],
1368 31556952 + 2 * 86400 + 9000,
1369 '1 year, 2 days and 150 minutes',
1370 [
'minutes',
'days',
'years' ],
1375 [
'days',
'years' ],
1385 $this->assertEquals(
1387 $this->
getLang()->checkTitleEncoding(
$s ),
1388 "checkTitleEncoding('$s')"
1396 [
"United States of America" ],
1397 [ rawurldecode(
"S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ],
1400 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
1408 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
1409 .
"Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
1410 .
"Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
1411 .
"Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
1412 .
"Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
1413 .
"Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
1414 .
"Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
1415 .
"Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
1416 .
"Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
1417 .
"Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
1418 .
"Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
1419 .
"Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
1420 .
"Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
1421 .
"Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
1426 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C"
1427 .
"Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C"
1428 .
"Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C"
1429 .
"Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C"
1430 .
"Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou"
1431 .
"%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C"
1432 .
"Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C"
1433 .
"Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C"
1434 .
"Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C"
1435 .
"Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C"
1436 .
"Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C"
1437 .
"Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C"
1438 .
"Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C"
1439 .
"Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C"
1440 .
"Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes"
1452 $this->assertEquals(
1454 Language::romanNumeral( $num ),
1455 "romanNumeral('$num')"
1492 [ 1989,
'MCMLXXXIX' ],
1498 [ 7000,
'MMMMMMM' ],
1499 [ 8000,
'MMMMMMMM' ],
1500 [ 9000,
'MMMMMMMMM' ],
1501 [ 9999,
'MMMMMMMMMCMXCIX' ],
1502 [ 10000,
'MMMMMMMMMM' ],
1511 $this->assertEquals(
1513 Language::hebrewNumeral( $num ),
1514 "hebrewNumeral('$num')"
1561 [ 2000,
"ב' אלפים" ],
1563 [ 3000,
"ג' אלפים" ],
1564 [ 4000,
"ד' אלפים" ],
1565 [ 4904,
"ד'תתק\"ד" ],
1566 [ 5000,
"ה' אלפים" ],
1567 [ 5680,
"ה'תר\"ף" ],
1568 [ 5690,
"ה'תר\"ץ" ],
1569 [ 5708,
"ה'תש\"ח" ],
1570 [ 5720,
"ה'תש\"ך" ],
1571 [ 5740,
"ה'תש\"ם" ],
1572 [ 5750,
"ה'תש\"ן" ],
1573 [ 5775,
"ה'תשע\"ה" ],
1582 $chosen = $this->
getLang()->convertPlural( $number, $forms );
1583 $this->assertEquals( $expected, $chosen );
1590 'singular',
'plural'
1592 [
'explicit zero', 0, [
1593 '0=explicit zero',
'singular',
'plural'
1595 [
'explicit one', 1, [
1596 'singular',
'plural',
'1=explicit one',
1599 'singular',
'plural',
'0=explicit zero',
1602 '0=explicit zero',
'1=explicit one',
'singular',
'plural'
1604 [
'explicit eleven', 11, [
1605 'singular',
'plural',
'11=explicit eleven',
1608 'singular',
'plural',
'11=explicit twelve',
1611 'singular',
'plural',
'=explicit form',
1614 'kissa=kala',
'1=2=3',
'other',
1617 '0=explicit zero',
'1=explicit one',
1630 $this->assertEquals(
1632 $lang->embedBidi(
'123' ),
1633 'embedBidi with neutral argument'
1635 $this->assertEquals(
1636 $lre .
'Ben_(WMF)' . $pdf,
1637 $lang->embedBidi(
'Ben_(WMF)' ),
1638 'embedBidi with LTR argument'
1640 $this->assertEquals(
1641 $rle .
'יהודי (מנוחין)' . $pdf,
1642 $lang->embedBidi(
'יהודי (מנוחין)' ),
1643 'embedBidi with RTL argument'
1653 if ( is_array( $expectedData ) ) {
1654 list( $func, $arg ) = $expectedData;
1655 $expected =
$lang->$func( $arg );
1657 $expected = $expectedData;
1659 $this->assertEquals( $expected,
$lang->translateBlockExpiry( $str,
null, $now ), $desc );
1664 [
'2 hours',
'2 hours', 0,
'simple data from ipboptions' ],
1665 [
'indefinite',
'infinite', 0,
'infinite from ipboptions' ],
1666 [
'indefinite',
'infinity', 0,
'alternative infinite from ipboptions' ],
1667 [
'indefinite',
'indefinite', 0,
'another alternative infinite from ipboptions' ],
1668 [ [
'formatDuration', 1023 * 60 * 60 ],
'1023 hours', 0,
'relative' ],
1669 [ [
'formatDuration', -1023 ],
'-1023 seconds', 0,
'negative relative' ],
1671 [
'formatDuration', 1023 * 60 * 60 ],
1674 'relative with initial timestamp'
1676 [ [
'formatDuration', 0 ],
'now', 0,
'now' ],
1678 [
'timeanddate',
'20120102070000' ],
1679 '2012-1-1 7:00 +1 day',
1681 'mixed, handled as absolute'
1683 [ [
'timeanddate',
'19910203040506' ],
'1991-2-3 4:05:06', 0,
'absolute' ],
1684 [ [
'timeanddate',
'19700101000000' ],
'1970-1-1 0:00:00', 0,
'absolute at epoch' ],
1685 [ [
'timeanddate',
'19691231235959' ],
'1969-12-31 23:59:59', 0,
'time before epoch' ],
1687 [
'timeanddate',
'19910910000000' ],
1692 [
'dummy',
'dummy', 0,
'return garbage as is' ],
1701 $translateNumerals, $langCode, $number, $nocommafy, $expected
1703 $this->
setMwGlobals( [
'wgTranslateNumerals' => $translateNumerals ] );
1704 $lang = Language::factory( $langCode );
1705 $formattedNum =
$lang->formatNum( $number, $nocommafy );
1706 $this->
assertType(
'string', $formattedNum );
1707 $this->assertEquals( $expected, $formattedNum );
1712 [
true,
'en', 100,
false,
'100' ],
1713 [
true,
'en', 101,
true,
'101' ],
1714 [
false,
'en', 103,
false,
'103' ],
1715 [
false,
'en', 104,
true,
'104' ],
1716 [
true,
'en',
'105',
false,
'105' ],
1717 [
true,
'en',
'106',
true,
'106' ],
1718 [
false,
'en',
'107',
false,
'107' ],
1719 [
false,
'en',
'108',
true,
'108' ],
1728 $lang = Language::factory( $langCode );
1730 $localisedNum =
$lang->formatNum( $number );
1731 $normalisedNum =
$lang->parseFormattedNumber( $localisedNum );
1733 $this->assertEquals( $number, $normalisedNum );
1743 [
'zh-classical', 7432 ]
1752 $this->assertEquals(
1754 $this->
getLang()->commafy( $number ),
1755 "commafy('$number')"
1765 [ 10000,
'10,000' ],
1766 [ 100000,
'100,000' ],
1767 [ 1000000,
'1,000,000' ],
1768 [ -1.0001,
'-1.0001' ],
1769 [ 1.0001,
'1.0001' ],
1770 [ 10.0001,
'10.0001' ],
1771 [ 100.0001,
'100.0001' ],
1772 [ 1000.0001,
'1,000.0001' ],
1773 [ 10000.0001,
'10,000.0001' ],
1774 [ 100000.0001,
'100,000.0001' ],
1775 [ 1000000.0001,
'1,000,000.0001' ],
1776 [
'200000000000000000000',
'200,000,000,000,000,000,000' ],
1777 [
'-200000000000000000000',
'-200,000,000,000,000,000,000' ],
1786 $and =
$lang->getMessageFromDB(
'and' );
1787 $s =
$lang->getMessageFromDB(
'word-separator' );
1788 $c =
$lang->getMessageFromDB(
'comma-separator' );
1790 $this->assertEquals(
'',
$lang->listToText( [] ) );
1791 $this->assertEquals(
'a',
$lang->listToText( [
'a' ] ) );
1792 $this->assertEquals(
"a{$and}{$s}b",
$lang->listToText( [
'a',
'b' ] ) );
1793 $this->assertEquals(
"a{$c}b{$and}{$s}c",
$lang->listToText( [
'a',
'b',
'c' ] ) );
1794 $this->assertEquals(
"a{$c}b{$c}c{$and}{$s}d",
$lang->listToText( [
'a',
'b',
'c',
'd' ] ) );
1801 $languageClass = TestingAccessWrapper::newFromClass( Language::class );
1804 Language::getLocalisationCache()->getItem(
'zh',
'mainpage' );
1805 $oldCacheObj = Language::$dataCache;
1806 $this->assertNotCount( 0,
1807 TestingAccessWrapper::newFromObject( Language::$dataCache )->loadedItems );
1810 $lang = Language::factory(
'en' );
1811 $this->assertNotCount( 0, Language::$mLangObjCache );
1814 Language::getFallbacksIncludingSiteLanguage(
'en' );
1815 $this->assertNotCount( 0, $languageClass->fallbackLanguageCache );
1818 $lang->getGrammarTransformations();
1819 $this->assertNotNull( $languageClass->grammarTransformations );
1822 Language::fetchLanguageNames();
1823 $this->assertNotNull( $languageClass->languageNameCache );
1825 Language::clearCaches();
1827 $this->assertNotSame( $oldCacheObj, Language::$dataCache );
1828 $this->assertCount( 0,
1829 TestingAccessWrapper::newFromObject( Language::$dataCache )->loadedItems );
1830 $this->assertCount( 0, Language::$mLangObjCache );
1831 $this->assertCount( 0, $languageClass->fallbackLanguageCache );
1832 $this->assertNull( $languageClass->grammarTransformations );
1833 $this->assertNull( $languageClass->languageNameCache );
1841 $this->assertEquals( $expected, Language::isSupportedLanguage(
$code ), $comment );
1846 [
'en',
true,
'is supported language' ],
1847 [
'fi',
true,
'is supported language' ],
1848 [
'bunny',
false,
'is not supported language' ],
1849 [
'FI',
false,
'is not supported language, input should be in lower case' ],
1859 if ( is_null( $expected ) ) {
1860 $this->assertNull(
$lang->getParentLanguage(), $comment );
1862 $this->assertEquals( $expected,
$lang->getParentLanguage()->getCode(), $comment );
1868 [
'zh-cn',
'zh',
'zh is the parent language of zh-cn' ],
1869 [
'zh',
'zh',
'zh is defined as the parent language of zh, '
1870 .
'because zh converter can convert zh-cn to zh' ],
1871 [
'zh-invalid',
null,
'do not be fooled by arbitrarily composed language codes' ],
1872 [
'de-formal',
null,
'de does not have converter' ],
1873 [
'de',
null,
'de does not have converter' ],
1882 $language = Language::factory( $languageCode );
1883 $aliases = $language->getNamespaceAliases();
1884 foreach ( $subset
as $alias => $nsId ) {
1885 $this->assertEquals( $nsId, $aliases[$alias] );
1907 $en = Language::factory(
'en' );
1908 $this->assertTrue( $en->hasVariant(
'en' ),
'base is always a variant' );
1909 $this->assertFalse( $en->hasVariant(
'en-bogus' ),
'bogus en variant' );
1911 $bogus = Language::factory(
'bogus' );
1912 $this->assertTrue( $bogus->hasVariant(
'bogus' ),
'base is always a variant' );
1919 $en1 = Language::factory(
'en' );
1920 $en2 = Language::factory(
'en' );
1922 $this->assertTrue( $en1->equals( $en2 ),
'en1 equals en2' );
1923 $this->assertTrue( $en2->equals( $en3 ),
'en2 equals en3' );
1924 $this->assertTrue( $en3->equals( $en1 ),
'en3 equals en1' );
1926 $fr = Language::factory(
'fr' );
1927 $this->assertFalse( $en1->equals( $fr ),
'en not equals fr' );
1929 $ar1 = Language::factory(
'ar' );
1931 $this->assertTrue( $ar1->equals( $ar2 ),
'ar equals ar' );
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Helping class to run tests using a clean language instance.
static provideTranslateBlockExpiry()
static provideSprintfDateSamples()
static provideCheckTitleEncodingData()
static provideLanguageCodes()
testLenientLanguageTag()
Negative test for Language::isWellFormedLanguageTag() Language::isWellFormedLanguageTag.
static provideGetParentLanguage()
static provideRomanNumeralsData()
testSprintfDateTooLongTimestamp()
Test too long timestamp MWException Language::sprintfDate.
testWellFormedLanguageTag( $code, $message='')
Test Language::isWellFormedLanguageTag() provideWellFormedLanguageTags Language::isWellFormedLanguage...
static provideMalformedLanguageTags()
The test cases are based on the tests in the GaBuZoMeu parser written by Stéphane Bortzmeyer bortzmey...
testTruncateHtml( $len, $ellipsis, $input, $expected)
provideHTMLTruncateData Language::truncateHTML
testConvertPlural( $expected, $number, $forms)
providePluralData Language::convertPlural
static provideHTMLTruncateData()
testFormatDuration( $duration, $expected, $intervals=[])
provideFormatDuration Language::formatDuration
static provideFormattableTimes()
testFormatSize( $size, $expected, $msg)
provideFormatSizes Language::formatSize
testUnknownLanguageTag( $code, $message='')
Negative tests for Language::isKnownLanguageTag() provideUnKnownLanguageTags Language::isKnownLanguag...
testCommafy( $number, $numbersWithCommas)
Language::commafy() provideCommafyData.
testFormatTimePeriod( $seconds, $format, $expected, $desc)
provideFormattableTimes Language::formatTimePeriod
testHebrewNumeral( $num, $numerals)
provideHebrewNumeralsData Language::hebrewNumeral
static provideFormatDuration()
testListToText()
Language::listToText.
testFormatNum( $translateNumerals, $langCode, $number, $nocommafy, $expected)
provideFormatNum Language::formatNum
testParseFormattedNumber( $langCode, $number)
Language::parseFormattedNumber parseFormattedNumberProvider.
testIsSupportedLanguage( $code, $expected, $comment)
provideIsSupportedLanguage Language::isSupportedLanguage
parseFormattedNumberProvider()
static provideWellFormedLanguageTags()
The test cases are based on the tests in the GaBuZoMeu parser written by Stéphane Bortzmeyer bortzmey...
testSprintfDateNotAllDigitTimestamp()
Test too short timestamp MWException Language::sprintfDate.
static provideFormatBitrate()
testKnownCldrLanguageTag()
Language::isKnownLanguageTag.
testEmbedBidi()
Language::embedBidi()
testLanguageConvertDoubleWidthToSingleWidth()
Language::convertDoubleWidth Language::normalizeForSearch.
static provideHebrewNumeralsData()
testGetParentLanguage( $code, $expected, $comment)
provideGetParentLanguage Language::getParentLanguage
testCheckTitleEncoding( $s)
provideCheckTitleEncodingData Language::checkTitleEncoding
testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg)
sprintfDate should use passed timezone provideSprintfDateSamples Language::sprintfDate
static providePluralData()
testTranslateBlockExpiry( $expectedData, $str, $now, $desc)
Language::translateBlockExpiry() provideTranslateBlockExpiry.
testKnownLanguageTag( $code, $message='')
Test Language::isKnownLanguageTag() provideKnownLanguageTags Language::isKnownLanguageTag.
testGetNamespaceAliases( $languageCode, $subset)
provideGetNamespaceAliases Language::getNamespaceAliases
testFormatBitrate( $bps, $expected, $msg)
provideFormatBitrate Language::formatBitrate
static provideKnownLanguageTags()
static provideGetNamespaceAliases()
testBuiltInCodeValidation( $code, $expected, $message='')
Test Language::isValidBuiltInCode() provideLanguageCodes Language::isValidBuiltInCode.
testClearCaches()
Language::clearCaches.
static provideCommafyData()
testRomanNumerals( $num, $numerals)
provideRomanNumeralsData Language::romanNumeral
testTruncateForVisual( $expected, $string, $length, $ellipsis='...', $adjustLength=true)
provideTruncateData Language::truncateForVisual Language::truncateInternal
testHasVariant()
Language::hasVariant.
testSprintfDateNoTtlIfNotNeeded()
sprintfDate should only calculate a TTL if the caller is going to use it.
testTruncateForDatabase()
Language::truncateForDatabase Language::truncateInternal.
static provideFormatSizes()
testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg)
sprintfDate should always use UTC when no zone is given.
testSprintfDateTooShortTimestamp()
Test too short timestamp MWException Language::sprintfDate.
testEquals()
Language::equals.
static provideTruncateData()
testSprintfDate( $format, $ts, $expected, $msg)
provideSprintfDateSamples Language::sprintfDate
testMalformedLanguageTag( $code, $message='')
Negative test for Language::isWellFormedLanguageTag() provideMalformedLanguageTags Language::isWellFo...
static provideIsSupportedLanguage()
static provideUnknownLanguageTags()
Internationalisation code.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that When $user is not it can be in the form of< username >< more info > e g for bot passwords intended to be added to log contexts Fields it might only if the login was with a bot password it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
processing should stop and the error should be shown to the user * false
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
if(is_array($mode)) switch( $mode) $input
if(!isset( $args[0])) $lang