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' ),
501 * Test too short timestamp
502 * @expectedException MWException
504 function testSprintfDateTooShortTimestamp() {
505 $this->getLang()->sprintfDate( 'xiY', '1234567890123' );
509 * Test too long timestamp
510 * @expectedException MWException
512 function testSprintfDateTooLongTimestamp() {
513 $this->getLang()->sprintfDate( 'xiY', '123456789012345' );
517 * Test too short timestamp
518 * @expectedException MWException
520 function testSprintfDateNotAllDigitTimestamp() {
521 $this->getLang()->sprintfDate( 'xiY', '-1234567890123' );
525 * @dataProvider provideSprintfDateSamples
527 function testSprintfDate( $format, $ts, $expected, $msg ) {
530 $this->getLang()->sprintfDate( $format, $ts ),
531 "sprintfDate('$format', '$ts'): $msg"
536 * sprintfDate should always use UTC when no zone is given.
537 * @dataProvider provideSprintfDateSamples
539 function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) {
540 $oldTZ = date_default_timezone_get();
541 $res = date_default_timezone_set( 'Asia/Seoul' );
543 $this->markTestSkipped( "Error setting Timezone" );
548 $this->getLang()->sprintfDate( $format, $ts ),
549 "sprintfDate('$format', '$ts'): $msg"
552 date_default_timezone_set( $oldTZ );
556 * sprintfDate should use passed timezone
557 * @dataProvider provideSprintfDateSamples
559 function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) {
560 $tz = new DateTimeZone( 'Asia/Seoul' );
562 $this->markTestSkipped( "Error getting Timezone" );
567 $this->getLang()->sprintfDate( $format, $ts, $tz ),
568 "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg"
572 public static function provideSprintfDateSamples() {
577 '1390', // note because we're testing English locale we get Latin-standard digits
579 'Iranian calendar full year'
586 'Iranian calendar short year'
593 'ISO 8601 (week) year'
616 // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
643 'Month index, not zero pad'
650 'Month index. Zero pad'
671 'Genitive month name (same in EN)'
678 'Day of month (not zero pad)'
685 'Day of month (zero-pad)'
692 'Day of year (zero-indexed)'
699 'Day of week (abbrev)'
713 'Day of week (Mon=1, Sun=7)'
720 'Day of week (Sun=0, Sat=6)'
762 '12 hour, zero padded'
811 'Days in current month'
816 '2012-01-02T09:07:05+00:00',
817 '2012-01-02T09:07:05+09:00',
823 'Mon, 02 Jan 2012 09:07:05 +0000',
824 'Mon, 02 Jan 2012 09:07:05 +0900',
832 'Timezone identifier'
853 'Timezone offset with colon'
860 'Timezone abbreviation'
867 'Timezone offset in seconds'
895 'Hebrew number of days in month'
902 'Hebrew genitive month name (No difference in EN)'
944 'Raw numerals (doesn\'t mean much in EN)'
947 '[[Y "(yea"\\r)]] \\"xx\\"',
949 '[[2012 (year)]] "x"',
950 '[[2012 (year)]] "x"',
958 * @dataProvider provideFormatSizes
960 function testFormatSize( $size, $expected, $msg ) {
963 $this->getLang()->formatSize( $size ),
964 "formatSize('$size'): $msg"
968 public static function provideFormatSizes() {
1015 // How big!? THIS BIG!
1020 * @dataProvider provideFormatBitrate
1022 function testFormatBitrate( $bps, $expected, $msg ) {
1023 $this->assertEquals(
1025 $this->getLang()->formatBitrate( $bps ),
1026 "formatBitrate('$bps'): $msg"
1030 public static function provideFormatBitrate() {
1040 "999 bits per second"
1045 "1 kilobit per second"
1050 "1 megabit per second"
1055 "1 gigabit per second"
1060 "1 terabit per second"
1065 "1 petabit per second"
1070 "1 exabit per second"
1075 "1 zetabit per second"
1080 "1 yottabit per second"
1085 "1,000 yottabits per second"
1092 * @dataProvider provideFormatDuration
1094 function testFormatDuration( $duration, $expected, $intervals = array() ) {
1095 $this->assertEquals(
1097 $this->getLang()->formatDuration( $duration, $intervals ),
1098 "formatDuration('$duration'): $expected"
1102 public static function provideFormatDuration() {
1141 // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952
1142 ( 365 +
( 24 * 3 +
25 ) / 400.0 ) * 86400,
1175 '2 hours, 30 minutes and 1 second'
1179 '1 hour and 1 second'
1182 31556952 +
2 * 86400 +
9000,
1183 '1 year, 2 days, 2 hours and 30 minutes'
1186 42 * 1000 * 31556952 +
42,
1187 '42 millennia and 42 seconds'
1205 31556952 +
2 * 86400 +
9000,
1206 '1 year, 2 days and 150 minutes',
1207 array( 'years', 'days', 'minutes' ),
1212 array( 'years', 'days' ),
1215 31556952 +
2 * 86400 +
9000,
1216 '1 year, 2 days and 150 minutes',
1217 array( 'minutes', 'days', 'years' ),
1222 array( 'days', 'years' ),
1228 * @dataProvider provideCheckTitleEncodingData
1230 function testCheckTitleEncoding( $s ) {
1231 $this->assertEquals(
1233 $this->getLang()->checkTitleEncoding( $s ),
1234 "checkTitleEncoding('$s')"
1238 public static function provideCheckTitleEncodingData() {
1241 array( "United States of America" ), // 7bit ASCII
1242 array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
1245 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
1248 // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for
1249 // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding
1250 // uses mb_check_encoding for its test.
1253 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
1254 . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
1255 . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
1256 . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
1257 . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
1258 . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
1259 . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
1260 . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
1261 . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
1262 . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
1263 . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
1264 . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
1265 . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
1266 . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
1271 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C"
1272 . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C"
1273 . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C"
1274 . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C"
1275 . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou"
1276 . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C"
1277 . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C"
1278 . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C"
1279 . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C"
1280 . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C"
1281 . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C"
1282 . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C"
1283 . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C"
1284 . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C"
1285 . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes"
1292 * @dataProvider provideRomanNumeralsData
1294 function testRomanNumerals( $num, $numerals ) {
1295 $this->assertEquals(
1297 Language
::romanNumeral( $num ),
1298 "romanNumeral('$num')"
1302 public static function provideRomanNumeralsData() {
1317 array( 49, 'XLIX' ),
1321 array( 80, 'LXXX' ),
1323 array( 99, 'XCIX' ),
1326 array( 300, 'CCC' ),
1330 array( 700, 'DCC' ),
1331 array( 800, 'DCCC' ),
1333 array( 999, 'CMXCIX' ),
1335 array( 1989, 'MCMLXXXIX' ),
1336 array( 2000, 'MM' ),
1337 array( 3000, 'MMM' ),
1338 array( 4000, 'MMMM' ),
1339 array( 5000, 'MMMMM' ),
1340 array( 6000, 'MMMMMM' ),
1341 array( 7000, 'MMMMMMM' ),
1342 array( 8000, 'MMMMMMMM' ),
1343 array( 9000, 'MMMMMMMMM' ),
1344 array( 9999, 'MMMMMMMMMCMXCIX' ),
1345 array( 10000, 'MMMMMMMMMM' ),
1350 * @dataProvider providePluralData
1352 function testConvertPlural( $expected, $number, $forms ) {
1353 $chosen = $this->getLang()->convertPlural( $number, $forms );
1354 $this->assertEquals( $expected, $chosen );
1357 public static function providePluralData() {
1358 // Params are: [expected text, number given, [the plural forms]]
1360 array( 'plural', 0, array(
1361 'singular', 'plural'
1363 array( 'explicit zero', 0, array(
1364 '0=explicit zero', 'singular', 'plural'
1366 array( 'explicit one', 1, array(
1367 'singular', 'plural', '1=explicit one',
1369 array( 'singular', 1, array(
1370 'singular', 'plural', '0=explicit zero',
1372 array( 'plural', 3, array(
1373 '0=explicit zero', '1=explicit one', 'singular', 'plural'
1375 array( 'explicit eleven', 11, array(
1376 'singular', 'plural', '11=explicit eleven',
1378 array( 'plural', 12, array(
1379 'singular', 'plural', '11=explicit twelve',
1381 array( 'plural', 12, array(
1382 'singular', 'plural', '=explicit form',
1384 array( 'other', 2, array(
1385 'kissa=kala', '1=2=3', 'other',
1387 array( '', 2, array(
1388 '0=explicit zero', '1=explicit one',
1394 * @covers Language::translateBlockExpiry()
1395 * @dataProvider provideTranslateBlockExpiry
1397 function testTranslateBlockExpiry( $expectedData, $str, $desc ) {
1398 $lang = $this->getLang();
1399 if ( is_array( $expectedData ) ) {
1400 list( $func, $arg ) = $expectedData;
1401 $expected = $lang->$func( $arg );
1403 $expected = $expectedData;
1405 $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc );
1408 public static function provideTranslateBlockExpiry() {
1410 array( '2 hours', '2 hours', 'simple data from ipboptions' ),
1411 array( 'indefinite', 'infinite', 'infinite from ipboptions' ),
1412 array( 'indefinite', 'infinity', 'alternative infinite from ipboptions' ),
1413 array( 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ),
1414 array( array( 'formatDuration', 1023 * 60 * 60 ), '1023 hours', 'relative' ),
1415 array( array( 'formatDuration', -1023 ), '-1023 seconds', 'negative relative' ),
1416 array( array( 'formatDuration', 0 ), 'now', 'now' ),
1417 array( array( 'timeanddate', '20120102070000' ), '2012-1-1 7:00 +1 day', 'mixed, handled as absolute' ),
1418 array( array( 'timeanddate', '19910203040506' ), '1991-2-3 4:05:06', 'absolute' ),
1419 array( array( 'timeanddate', '19700101000000' ), '1970-1-1 0:00:00', 'absolute at epoch' ),
1420 array( array( 'timeanddate', '19691231235959' ), '1969-12-31 23:59:59', 'time before epoch' ),
1421 array( 'dummy', 'dummy', 'return garbage as is' ),
1426 * @covers Language::commafy()
1427 * @dataProvider provideCommafyData
1429 function testCommafy( $number, $numbersWithCommas ) {
1430 $this->assertEquals(
1432 $this->getLang()->commafy( $number ),
1433 "commafy('$number')"
1437 public static function provideCommafyData() {
1441 array( 100, '100' ),
1442 array( 1000, '1,000' ),
1443 array( 10000, '10,000' ),
1444 array( 100000, '100,000' ),
1445 array( 1000000, '1,000,000' ),
1446 array( 1.0001, '1.0001' ),
1447 array( 10.0001, '10.0001' ),
1448 array( 100.0001, '100.0001' ),
1449 array( 1000.0001, '1,000.0001' ),
1450 array( 10000.0001, '10,000.0001' ),
1451 array( 100000.0001, '100,000.0001' ),
1452 array( 1000000.0001, '1,000,000.0001' ),
1456 function testListToText() {
1457 $lang = $this->getLang();
1458 $and = $lang->getMessageFromDB( 'and' );
1459 $s = $lang->getMessageFromDB( 'word-separator' );
1460 $c = $lang->getMessageFromDB( 'comma-separator' );
1462 $this->assertEquals( '', $lang->listToText( array() ) );
1463 $this->assertEquals( 'a', $lang->listToText( array( 'a' ) ) );
1464 $this->assertEquals( "a{$and}{$s}b", $lang->listToText( array( 'a', 'b' ) ) );
1465 $this->assertEquals( "a{$c}b{$and}{$s}c", $lang->listToText( array( 'a', 'b', 'c' ) ) );
1466 $this->assertEquals( "a{$c}b{$c}c{$and}{$s}d", $lang->listToText( array( 'a', 'b', 'c', 'd' ) ) );
1470 * @dataProvider provideIsSupportedLanguage
1472 function testIsSupportedLanguage( $code, $expected, $comment ) {
1473 $this->assertEquals( $expected, Language
::isSupportedLanguage( $code ), $comment );
1476 public static function provideIsSupportedLanguage() {
1478 array( 'en', true, 'is supported language' ),
1479 array( 'fi', true, 'is supported language' ),
1480 array( 'bunny', false, 'is not supported language' ),
1481 array( 'FI', false, 'is not supported language, input should be in lower case' ),