3 class LanguageTest
extends LanguageClassesTestCase
{
4 function testLanguageConvertDoubleWidthToSingleWidth() {
6 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
7 $this->getLang()->normalizeForSearch(
8 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10 'convertDoubleWidth() with the full alphabet and digits'
15 * @dataProvider provideFormattableTimes
17 function testFormatTimePeriod( $seconds, $format, $expected, $desc ) {
18 $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc );
21 public static function provideFormattableTimes() {
27 'formatTimePeriod() rounding (<10s)'
31 array( 'noabbrevs' => true ),
33 'formatTimePeriod() rounding (<10s)'
39 'formatTimePeriod() rounding (<10s)'
43 array( 'noabbrevs' => true ),
45 'formatTimePeriod() rounding (<10s)'
51 'formatTimePeriod() rounding (<60s)'
55 array( 'noabbrevs' => true ),
57 'formatTimePeriod() rounding (<60s)'
63 'formatTimePeriod() rounding (<1h)'
67 array( 'noabbrevs' => true ),
68 '2 minutes 0 seconds',
69 'formatTimePeriod() rounding (<1h)'
75 'formatTimePeriod() rounding (<1h)'
79 array( 'noabbrevs' => true ),
80 '1 hour 0 minutes 0 seconds',
81 'formatTimePeriod() rounding (<1h)'
87 'formatTimePeriod() rounding (>=1h)'
91 array( 'noabbrevs' => true ),
92 '2 hours 0 minutes 0 seconds',
93 'formatTimePeriod() rounding (>=1h)'
99 'formatTimePeriod() rounding (>=1h), avoidseconds'
103 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
105 'formatTimePeriod() rounding (>=1h), avoidseconds'
111 'formatTimePeriod() rounding (>=1h), avoidminutes'
115 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
117 'formatTimePeriod() rounding (>=1h), avoidminutes'
123 'formatTimePeriod() rounding (=48h), avoidseconds'
127 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
128 '48 hours 0 minutes',
129 'formatTimePeriod() rounding (=48h), avoidseconds'
135 'formatTimePeriod() rounding (>48h), avoidminutes'
139 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
141 'formatTimePeriod() rounding (>48h), avoidminutes'
147 'formatTimePeriod() rounding (>48h), avoidseconds'
151 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
152 '2 days 1 hour 0 minutes',
153 'formatTimePeriod() rounding (>48h), avoidseconds'
159 'formatTimePeriod() rounding (>48h), avoidminutes'
163 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
165 'formatTimePeriod() rounding (>48h), avoidminutes'
171 'formatTimePeriod() rounding (>48h), avoidseconds'
175 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
176 '3 days 0 hours 0 minutes',
177 'formatTimePeriod() rounding (>48h), avoidseconds'
183 'formatTimePeriod() rounding, (>48h), avoidseconds'
187 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
188 '2 days 0 hours 0 minutes',
189 'formatTimePeriod() rounding, (>48h), avoidseconds'
195 'formatTimePeriod() rounding, recursion, (>48h)'
199 array( 'noabbrevs' => true ),
200 '2 days 1 hour 1 minute 1 second',
201 'formatTimePeriod() rounding, recursion, (>48h)'
206 function testTruncate() {
209 $this->getLang()->truncate( "1234567890", 0, 'XXX' ),
210 'truncate prefix, len 0, small ellipsis'
215 $this->getLang()->truncate( "1234567890", 8, 'XXX' ),
216 'truncate prefix, small ellipsis'
221 $this->getLang()->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
222 'truncate prefix, large ellipsis'
227 $this->getLang()->truncate( "1234567890", -8, 'XXX' ),
228 'truncate suffix, small ellipsis'
233 $this->getLang()->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
234 'truncate suffix, large ellipsis'
239 * @dataProvider provideHTMLTruncateData()
241 function testTruncateHtml( $len, $ellipsis, $input, $expected ) {
245 $this->getLang()->truncateHTML( $input, $len, $ellipsis )
250 * Array format is ($len, $ellipsis, $input, $expected)
252 public static function provideHTMLTruncateData() {
254 array( 0, 'XXX', "1234567890", "XXX" ),
255 array( 8, 'XXX', "1234567890", "12345XXX" ),
256 array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ),
258 '<p><span style="font-weight:bold;"></span></p>',
259 '<p><span style="font-weight:bold;"></span></p>',
262 '<p><span style="font-weight:bold;">123456789</span></p>',
263 '<p><span style="font-weight:bold;">***</span></p>',
266 '<p><span style="font-weight:bold;"> 23456789</span></p>',
267 '<p><span style="font-weight:bold;">***</span></p>',
270 '<p><span style="font-weight:bold;">123456789</span></p>',
271 '<p><span style="font-weight:bold;">***</span></p>',
274 '<p><span style="font-weight:bold;">123456789</span></p>',
275 '<p><span style="font-weight:bold;">1***</span></p>',
278 '<tt><span style="font-weight:bold;">123456789</span></tt>',
279 '<tt><span style="font-weight:bold;">12***</span></tt>',
282 '<p><a href="www.mediawiki.org">123456789</a></p>',
283 '<p><a href="www.mediawiki.org">123***</a></p>',
286 '<p><a href="www.mediawiki.org">12 456789</a></p>',
287 '<p><a href="www.mediawiki.org">12 ***</a></p>',
290 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
291 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
294 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
295 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
298 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
299 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
302 '<p><font style="font-weight:bold;">123456789</font></p>',
303 '<p><font style="font-weight:bold;">123456789</font></p>',
309 * Test Language::isWellFormedLanguageTag()
310 * @dataProvider provideWellFormedLanguageTags
312 function testWellFormedLanguageTag( $code, $message = '' ) {
314 Language
::isWellFormedLanguageTag( $code ),
315 "validating code $code $message"
320 * The test cases are based on the tests in the GaBuZoMeu parser
321 * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
322 * and distributed as free software, under the GNU General Public Licence.
323 * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
325 public static function provideWellFormedLanguageTags() {
327 array( 'fr', 'two-letter code' ),
328 array( 'fr-latn', 'two-letter code with lower case script code' ),
329 array( 'fr-Latn-FR', 'two-letter code with title case script code and uppercase country code' ),
330 array( 'fr-Latn-419', 'two-letter code with title case script code and region number' ),
331 array( 'fr-FR', 'two-letter code with uppercase' ),
332 array( 'ax-TZ', 'Not in the registry, but well-formed' ),
333 array( 'fr-shadok', 'two-letter code with variant' ),
334 array( 'fr-y-myext-myext2', 'non-x singleton' ),
335 array( 'fra-Latn', 'ISO 639 can be 3-letters' ),
336 array( 'fra', 'three-letter language code' ),
337 array( 'fra-FX', 'three-letter language code with country code' ),
338 array( 'i-klingon', 'grandfathered with singleton' ),
339 array( 'I-kLINgon', 'tags are case-insensitive...' ),
340 array( 'no-bok', 'grandfathered without singleton' ),
341 array( 'i-enochian', 'Grandfathered' ),
342 array( 'x-fr-CH', 'private use' ),
343 array( 'es-419', 'two-letter code with region number' ),
344 array( 'en-Latn-GB-boont-r-extended-sequence-x-private', 'weird, but well-formed' ),
345 array( 'ab-x-abc-x-abc', 'anything goes after x' ),
346 array( 'ab-x-abc-a-a', 'anything goes after x, including several non-x singletons' ),
347 array( 'i-default', 'grandfathered' ),
348 array( 'abcd-Latn', 'Language of 4 chars reserved for future use' ),
349 array( 'AaBbCcDd-x-y-any-x', 'Language of 5-8 chars, registered' ),
350 array( 'de-CH-1901', 'with country and year' ),
351 array( 'en-US-x-twain', 'with country and singleton' ),
352 array( 'zh-cmn', 'three-letter variant' ),
353 array( 'zh-cmn-Hant', 'three-letter variant and script' ),
354 array( 'zh-cmn-Hant-HK', 'three-letter variant, script and country' ),
355 array( 'xr-p-lze', 'Extension' ),
360 * Negative test for Language::isWellFormedLanguageTag()
361 * @dataProvider provideMalformedLanguageTags
363 function testMalformedLanguageTag( $code, $message = '' ) {
365 Language
::isWellFormedLanguageTag( $code ),
366 "validating that code $code is a malformed language tag - $message"
371 * The test cases are based on the tests in the GaBuZoMeu parser
372 * written by Stéphane Bortzmeyer <bortzmeyer@nic.fr>
373 * and distributed as free software, under the GNU General Public Licence.
374 * http://www.bortzmeyer.org/gabuzomeu-parsing-language-tags.html
376 public static function provideMalformedLanguageTags() {
378 array( 'f', 'language too short' ),
379 array( 'f-Latn', 'language too short with script' ),
380 array( 'xr-lxs-qut', 'variants too short' ), # extlangS
381 array( 'fr-Latn-F', 'region too short' ),
382 array( 'a-value', 'language too short with region' ),
383 array( 'tlh-a-b-foo', 'valid three-letter with wrong variant' ),
384 array( 'i-notexist', 'grandfathered but not registered: invalid, even if we only test well-formedness' ),
385 array( 'abcdefghi-012345678', 'numbers too long' ),
386 array( 'ab-abc-abc-abc-abc', 'invalid extensions' ),
387 array( 'ab-abcd-abc', 'invalid extensions' ),
388 array( 'ab-ab-abc', 'invalid extensions' ),
389 array( 'ab-123-abc', 'invalid extensions' ),
390 array( 'a-Hant-ZH', 'short language with valid extensions' ),
391 array( 'a1-Hant-ZH', 'invalid character in language' ),
392 array( 'ab-abcde-abc', 'invalid extensions' ),
393 array( 'ab-1abc-abc', 'invalid characters in extensions' ),
394 array( 'ab-ab-abcd', 'invalid order of extensions' ),
395 array( 'ab-123-abcd', 'invalid order of extensions' ),
396 array( 'ab-abcde-abcd', 'invalid extensions' ),
397 array( 'ab-1abc-abcd', 'invalid characters in extensions' ),
398 array( 'ab-a-b', 'extensions too short' ),
399 array( 'ab-a-x', 'extensions too short, even with singleton' ),
400 array( 'ab--ab', 'two separators' ),
401 array( 'ab-abc-', 'separator in the end' ),
402 array( '-ab-abc', 'separator in the beginning' ),
403 array( 'abcd-efg', 'language too long' ),
404 array( 'aabbccddE', 'tag too long' ),
405 array( 'pa_guru', 'A tag with underscore is invalid in strict mode' ),
406 array( 'de-f', 'subtag too short' ),
411 * Negative test for Language::isWellFormedLanguageTag()
413 function testLenientLanguageTag() {
415 Language
::isWellFormedLanguageTag( 'pa_guru', true ),
416 'pa_guru is a well-formed language tag in lenient mode'
421 * Test Language::isValidBuiltInCode()
422 * @dataProvider provideLanguageCodes
424 function testBuiltInCodeValidation( $code, $message = '' ) {
426 (bool)Language
::isValidBuiltInCode( $code ),
427 "validating code $code $message"
431 function testBuiltInCodeValidationRejectUnderscore() {
433 (bool)Language
::isValidBuiltInCode( 'be_tarask' ),
434 "reject underscore in language code"
438 public static function provideLanguageCodes() {
440 array( 'fr', 'Two letters, minor case' ),
441 array( 'EN', 'Two letters, upper case' ),
442 array( 'tyv', 'Three letters' ),
443 array( 'tokipona', 'long language code' ),
444 array( 'be-tarask', 'With dash' ),
445 array( 'Zh-classical', 'Begin with upper case, dash' ),
446 array( 'Be-x-old', 'With extension (two dashes)' ),
451 * Test Language::isKnownLanguageTag()
452 * @dataProvider provideKnownLanguageTags
454 function testKnownLanguageTag( $code, $message = '' ) {
456 (bool)Language
::isKnownLanguageTag( $code ),
457 "validating code $code - $message"
461 public static function provideKnownLanguageTags() {
463 array( 'fr', 'simple code' ),
464 array( 'bat-smg', 'an MW legacy tag' ),
465 array( 'sgs', 'an internal standard MW name, for which a legacy tag is used externally' ),
470 * Test Language::isKnownLanguageTag()
472 function testKnownCldrLanguageTag() {
473 if ( !class_exists( 'LanguageNames' ) ) {
474 $this->markTestSkipped( 'The LanguageNames class is not available. The cldr extension is probably not installed.' );
478 (bool)Language
::isKnownLanguageTag( 'pal' ),
479 'validating code "pal" an ancient language, which probably will not appear in Names.php, but appears in CLDR in English'
484 * Negative tests for Language::isKnownLanguageTag()
485 * @dataProvider provideUnKnownLanguageTags
487 function testUnknownLanguageTag( $code, $message = '' ) {
489 (bool)Language
::isKnownLanguageTag( $code ),
490 "checking that code $code is invalid - $message"
494 public static function provideUnknownLanguageTags() {
496 array( 'mw', 'non-existent two-letter code' ),
497 array( 'foo"<bar', 'very invalid language code' ),
502 * Test too short timestamp
503 * @expectedException MWException
505 function testSprintfDateTooShortTimestamp() {
506 $this->getLang()->sprintfDate( 'xiY', '1234567890123' );
510 * Test too long timestamp
511 * @expectedException MWException
513 function testSprintfDateTooLongTimestamp() {
514 $this->getLang()->sprintfDate( 'xiY', '123456789012345' );
518 * Test too short timestamp
519 * @expectedException MWException
521 function testSprintfDateNotAllDigitTimestamp() {
522 $this->getLang()->sprintfDate( 'xiY', '-1234567890123' );
526 * @dataProvider provideSprintfDateSamples
528 function testSprintfDate( $format, $ts, $expected, $msg ) {
531 $this->getLang()->sprintfDate( $format, $ts ),
532 "sprintfDate('$format', '$ts'): $msg"
537 * sprintfDate should always use UTC when no zone is given.
538 * @dataProvider provideSprintfDateSamples
540 function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) {
541 $oldTZ = date_default_timezone_get();
542 $res = date_default_timezone_set( 'Asia/Seoul' );
544 $this->markTestSkipped( "Error setting Timezone" );
549 $this->getLang()->sprintfDate( $format, $ts ),
550 "sprintfDate('$format', '$ts'): $msg"
553 date_default_timezone_set( $oldTZ );
557 * sprintfDate should use passed timezone
558 * @dataProvider provideSprintfDateSamples
560 function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) {
561 $tz = new DateTimeZone( 'Asia/Seoul' );
563 $this->markTestSkipped( "Error getting Timezone" );
568 $this->getLang()->sprintfDate( $format, $ts, $tz ),
569 "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg"
573 public static function provideSprintfDateSamples() {
578 '1390', // note because we're testing English locale we get Latin-standard digits
580 'Iranian calendar full year'
587 'Iranian calendar short year'
594 'ISO 8601 (week) year'
617 // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
644 'Month index, not zero pad'
651 'Month index. Zero pad'
672 'Genitive month name (same in EN)'
679 'Day of month (not zero pad)'
686 'Day of month (zero-pad)'
693 'Day of year (zero-indexed)'
700 'Day of week (abbrev)'
714 'Day of week (Mon=1, Sun=7)'
721 'Day of week (Sun=0, Sat=6)'
763 '12 hour, zero padded'
812 'Days in current month'
817 '2012-01-02T09:07:05+00:00',
818 '2012-01-02T09:07:05+09:00',
824 'Mon, 02 Jan 2012 09:07:05 +0000',
825 'Mon, 02 Jan 2012 09:07:05 +0900',
833 'Timezone identifier'
854 'Timezone offset with colon'
861 'Timezone abbreviation'
868 'Timezone offset in seconds'
896 'Hebrew number of days in month'
903 'Hebrew genitive month name (No difference in EN)'
945 'Raw numerals (doesn\'t mean much in EN)'
948 '[[Y "(yea"\\r)]] \\"xx\\"',
950 '[[2012 (year)]] "x"',
951 '[[2012 (year)]] "x"',
959 * @dataProvider provideFormatSizes
961 function testFormatSize( $size, $expected, $msg ) {
964 $this->getLang()->formatSize( $size ),
965 "formatSize('$size'): $msg"
969 public static function provideFormatSizes() {
1016 // How big!? THIS BIG!
1021 * @dataProvider provideFormatBitrate
1023 function testFormatBitrate( $bps, $expected, $msg ) {
1024 $this->assertEquals(
1026 $this->getLang()->formatBitrate( $bps ),
1027 "formatBitrate('$bps'): $msg"
1031 public static function provideFormatBitrate() {
1041 "999 bits per second"
1046 "1 kilobit per second"
1051 "1 megabit per second"
1056 "1 gigabit per second"
1061 "1 terabit per second"
1066 "1 petabit per second"
1071 "1 exabit per second"
1076 "1 zetabit per second"
1081 "1 yottabit per second"
1086 "1,000 yottabits per second"
1093 * @dataProvider provideFormatDuration
1095 function testFormatDuration( $duration, $expected, $intervals = array() ) {
1096 $this->assertEquals(
1098 $this->getLang()->formatDuration( $duration, $intervals ),
1099 "formatDuration('$duration'): $expected"
1103 public static function provideFormatDuration() {
1142 // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952
1143 ( 365 +
( 24 * 3 +
25 ) / 400.0 ) * 86400,
1176 '2 hours, 30 minutes and 1 second'
1180 '1 hour and 1 second'
1183 31556952 +
2 * 86400 +
9000,
1184 '1 year, 2 days, 2 hours and 30 minutes'
1187 42 * 1000 * 31556952 +
42,
1188 '42 millennia and 42 seconds'
1206 31556952 +
2 * 86400 +
9000,
1207 '1 year, 2 days and 150 minutes',
1208 array( 'years', 'days', 'minutes' ),
1213 array( 'years', 'days' ),
1216 31556952 +
2 * 86400 +
9000,
1217 '1 year, 2 days and 150 minutes',
1218 array( 'minutes', 'days', 'years' ),
1223 array( 'days', 'years' ),
1229 * @dataProvider provideCheckTitleEncodingData
1231 function testCheckTitleEncoding( $s ) {
1232 $this->assertEquals(
1234 $this->getLang()->checkTitleEncoding( $s ),
1235 "checkTitleEncoding('$s')"
1239 public static function provideCheckTitleEncodingData() {
1242 array( "United States of America" ), // 7bit ASCII
1243 array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
1246 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
1249 // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for
1250 // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding
1251 // uses mb_check_encoding for its test.
1254 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
1255 . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
1256 . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
1257 . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
1258 . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
1259 . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
1260 . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
1261 . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
1262 . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
1263 . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
1264 . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
1265 . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
1266 . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
1267 . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
1272 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C"
1273 . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C"
1274 . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C"
1275 . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C"
1276 . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou"
1277 . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C"
1278 . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C"
1279 . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C"
1280 . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C"
1281 . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C"
1282 . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C"
1283 . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C"
1284 . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C"
1285 . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C"
1286 . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes"
1293 * @dataProvider provideRomanNumeralsData
1295 function testRomanNumerals( $num, $numerals ) {
1296 $this->assertEquals(
1298 Language
::romanNumeral( $num ),
1299 "romanNumeral('$num')"
1303 public static function provideRomanNumeralsData() {
1318 array( 49, 'XLIX' ),
1322 array( 80, 'LXXX' ),
1324 array( 99, 'XCIX' ),
1327 array( 300, 'CCC' ),
1331 array( 700, 'DCC' ),
1332 array( 800, 'DCCC' ),
1334 array( 999, 'CMXCIX' ),
1336 array( 1989, 'MCMLXXXIX' ),
1337 array( 2000, 'MM' ),
1338 array( 3000, 'MMM' ),
1339 array( 4000, 'MMMM' ),
1340 array( 5000, 'MMMMM' ),
1341 array( 6000, 'MMMMMM' ),
1342 array( 7000, 'MMMMMMM' ),
1343 array( 8000, 'MMMMMMMM' ),
1344 array( 9000, 'MMMMMMMMM' ),
1345 array( 9999, 'MMMMMMMMMCMXCIX' ),
1346 array( 10000, 'MMMMMMMMMM' ),
1351 * @dataProvider providePluralData
1353 function testConvertPlural( $expected, $number, $forms ) {
1354 $chosen = $this->getLang()->convertPlural( $number, $forms );
1355 $this->assertEquals( $expected, $chosen );
1358 public static function providePluralData() {
1359 // Params are: [expected text, number given, [the plural forms]]
1361 array( 'plural', 0, array(
1362 'singular', 'plural'
1364 array( 'explicit zero', 0, array(
1365 '0=explicit zero', 'singular', 'plural'
1367 array( 'explicit one', 1, array(
1368 'singular', 'plural', '1=explicit one',
1370 array( 'singular', 1, array(
1371 'singular', 'plural', '0=explicit zero',
1373 array( 'plural', 3, array(
1374 '0=explicit zero', '1=explicit one', 'singular', 'plural'
1376 array( 'explicit eleven', 11, array(
1377 'singular', 'plural', '11=explicit eleven',
1379 array( 'plural', 12, array(
1380 'singular', 'plural', '11=explicit twelve',
1382 array( 'plural', 12, array(
1383 'singular', 'plural', '=explicit form',
1385 array( 'other', 2, array(
1386 'kissa=kala', '1=2=3', 'other',
1388 array( '', 2, array(
1389 '0=explicit zero', '1=explicit one',
1395 * @covers Language::translateBlockExpiry()
1396 * @dataProvider provideTranslateBlockExpiry
1398 function testTranslateBlockExpiry( $expectedData, $str, $desc ) {
1399 $lang = $this->getLang();
1400 if ( is_array( $expectedData ) ) {
1401 list( $func, $arg ) = $expectedData;
1402 $expected = $lang->$func( $arg );
1404 $expected = $expectedData;
1406 $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc );
1409 public static function provideTranslateBlockExpiry() {
1411 array( '2 hours', '2 hours', 'simple data from ipboptions' ),
1412 array( 'indefinite', 'infinite', 'infinite from ipboptions' ),
1413 array( 'indefinite', 'infinity', 'alternative infinite from ipboptions' ),
1414 array( 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ),
1415 array( array( 'formatDuration', 1023 * 60 * 60 ), '1023 hours', 'relative' ),
1416 array( array( 'formatDuration', -1023 ), '-1023 seconds', 'negative relative' ),
1417 array( array( 'formatDuration', 0 ), 'now', 'now' ),
1418 array( array( 'timeanddate', '20120102070000' ), '2012-1-1 7:00 +1 day', 'mixed, handled as absolute' ),
1419 array( array( 'timeanddate', '19910203040506' ), '1991-2-3 4:05:06', 'absolute' ),
1420 array( array( 'timeanddate', '19700101000000' ), '1970-1-1 0:00:00', 'absolute at epoch' ),
1421 array( array( 'timeanddate', '19691231235959' ), '1969-12-31 23:59:59', 'time before epoch' ),
1422 array( 'dummy', 'dummy', 'return garbage as is' ),
1427 * @covers Language::commafy()
1428 * @dataProvider provideCommafyData
1430 function testCommafy( $number, $numbersWithCommas ) {
1431 $this->assertEquals(
1433 $this->getLang()->commafy( $number ),
1434 "commafy('$number')"
1438 public static function provideCommafyData() {
1442 array( 100, '100' ),
1443 array( 1000, '1,000' ),
1444 array( 10000, '10,000' ),
1445 array( 100000, '100,000' ),
1446 array( 1000000, '1,000,000' ),
1447 array( 1.0001, '1.0001' ),
1448 array( 10.0001, '10.0001' ),
1449 array( 100.0001, '100.0001' ),
1450 array( 1000.0001, '1,000.0001' ),
1451 array( 10000.0001, '10,000.0001' ),
1452 array( 100000.0001, '100,000.0001' ),
1453 array( 1000000.0001, '1,000,000.0001' ),
1457 function testListToText() {
1458 $lang = $this->getLang();
1459 $and = $lang->getMessageFromDB( 'and' );
1460 $s = $lang->getMessageFromDB( 'word-separator' );
1461 $c = $lang->getMessageFromDB( 'comma-separator' );
1463 $this->assertEquals( '', $lang->listToText( array() ) );
1464 $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) );
1465 $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) );
1466 $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) );
1467 $this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) );
1471 * @dataProvider provideIsSupportedLanguage
1473 function testIsSupportedLanguage( $code, $expected, $comment ) {
1474 $this->assertEquals( $expected, Language
::isSupportedLanguage( $code ), $comment );
1477 public static function provideIsSupportedLanguage() {
1479 array( 'en', true, 'is supported language' ),
1480 array( 'fi', true, 'is supported language' ),
1481 array( 'bunny', false, 'is not supported language' ),
1482 array( 'FI', false, 'is not supported language, input should be in lower case' ),