3 class LanguageTest
extends MediaWikiTestCase
{
11 $this->lang
= Language
::factory( 'en' );
17 function testLanguageConvertDoubleWidthToSingleWidth() {
19 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
20 $this->lang
->normalizeForSearch(
21 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
23 'convertDoubleWidth() with the full alphabet and digits'
28 * @dataProvider provideFormattableTimes
30 function testFormatTimePeriod( $seconds, $format, $expected, $desc ) {
31 $this->assertEquals( $expected, $this->lang
->formatTimePeriod( $seconds, $format ), $desc );
34 function provideFormattableTimes() {
40 'formatTimePeriod() rounding (<10s)'
44 array( 'noabbrevs' => true ),
46 'formatTimePeriod() rounding (<10s)'
52 'formatTimePeriod() rounding (<10s)'
56 array( 'noabbrevs' => true ),
58 'formatTimePeriod() rounding (<10s)'
64 'formatTimePeriod() rounding (<60s)'
68 array( 'noabbrevs' => true ),
70 'formatTimePeriod() rounding (<60s)'
76 'formatTimePeriod() rounding (<1h)'
80 array( 'noabbrevs' => true ),
81 '2 minutes 0 seconds',
82 'formatTimePeriod() rounding (<1h)'
88 'formatTimePeriod() rounding (<1h)'
92 array( 'noabbrevs' => true ),
93 '1 hour 0 minutes 0 seconds',
94 'formatTimePeriod() rounding (<1h)'
100 'formatTimePeriod() rounding (>=1h)'
104 array( 'noabbrevs' => true ),
105 '2 hours 0 minutes 0 seconds',
106 'formatTimePeriod() rounding (>=1h)'
112 'formatTimePeriod() rounding (>=1h), avoidseconds'
116 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
118 'formatTimePeriod() rounding (>=1h), avoidseconds'
124 'formatTimePeriod() rounding (>=1h), avoidminutes'
128 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
130 'formatTimePeriod() rounding (>=1h), avoidminutes'
136 'formatTimePeriod() rounding (=48h), avoidseconds'
140 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
141 '48 hours 0 minutes',
142 'formatTimePeriod() rounding (=48h), avoidseconds'
148 'formatTimePeriod() rounding (>48h), avoidminutes'
152 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
154 'formatTimePeriod() rounding (>48h), avoidminutes'
160 'formatTimePeriod() rounding (>48h), avoidseconds'
164 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
165 '2 days 1 hour 0 minutes',
166 'formatTimePeriod() rounding (>48h), avoidseconds'
172 'formatTimePeriod() rounding (>48h), avoidminutes'
176 array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ),
178 'formatTimePeriod() rounding (>48h), avoidminutes'
184 'formatTimePeriod() rounding (>48h), avoidseconds'
188 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
189 '3 days 0 hours 0 minutes',
190 'formatTimePeriod() rounding (>48h), avoidseconds'
196 'formatTimePeriod() rounding, (>48h), avoidseconds'
200 array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ),
201 '2 days 0 hours 0 minutes',
202 'formatTimePeriod() rounding, (>48h), avoidseconds'
208 'formatTimePeriod() rounding, recursion, (>48h)'
212 array( 'noabbrevs' => true ),
213 '2 days 1 hour 1 minute 1 second',
214 'formatTimePeriod() rounding, recursion, (>48h)'
220 function testTruncate() {
223 $this->lang
->truncate( "1234567890", 0, 'XXX' ),
224 'truncate prefix, len 0, small ellipsis'
229 $this->lang
->truncate( "1234567890", 8, 'XXX' ),
230 'truncate prefix, small ellipsis'
235 $this->lang
->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
236 'truncate prefix, large ellipsis'
241 $this->lang
->truncate( "1234567890", -8, 'XXX' ),
242 'truncate suffix, small ellipsis'
247 $this->lang
->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
248 'truncate suffix, large ellipsis'
253 * @dataProvider provideHTMLTruncateData()
255 function testTruncateHtml( $len, $ellipsis, $input, $expected ) {
259 $this->lang
->truncateHTML( $input, $len, $ellipsis )
264 * Array format is ($len, $ellipsis, $input, $expected)
266 function provideHTMLTruncateData() {
268 array( 0, 'XXX', "1234567890", "XXX" ),
269 array( 8, 'XXX', "1234567890", "12345XXX" ),
270 array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ),
272 '<p><span style="font-weight:bold;"></span></p>',
273 '<p><span style="font-weight:bold;"></span></p>',
276 '<p><span style="font-weight:bold;">123456789</span></p>',
277 '<p><span style="font-weight:bold;">***</span></p>',
280 '<p><span style="font-weight:bold;"> 23456789</span></p>',
281 '<p><span style="font-weight:bold;">***</span></p>',
284 '<p><span style="font-weight:bold;">123456789</span></p>',
285 '<p><span style="font-weight:bold;">***</span></p>',
288 '<p><span style="font-weight:bold;">123456789</span></p>',
289 '<p><span style="font-weight:bold;">1***</span></p>',
292 '<tt><span style="font-weight:bold;">123456789</span></tt>',
293 '<tt><span style="font-weight:bold;">12***</span></tt>',
296 '<p><a href="www.mediawiki.org">123456789</a></p>',
297 '<p><a href="www.mediawiki.org">123***</a></p>',
300 '<p><a href="www.mediawiki.org">12 456789</a></p>',
301 '<p><a href="www.mediawiki.org">12 ***</a></p>',
304 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
305 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
308 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
309 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
312 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
313 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
316 '<p><font style="font-weight:bold;">123456789</font></p>',
317 '<p><font style="font-weight:bold;">123456789</font></p>',
323 * Test Language::isValidBuiltInCode()
324 * @dataProvider provideLanguageCodes
326 function testBuiltInCodeValidation( $code, $message = '' ) {
328 (bool) Language
::isValidBuiltInCode( $code ),
329 "validating code $code $message"
333 function testBuiltInCodeValidationRejectUnderscore() {
335 (bool) Language
::isValidBuiltInCode( 'be_tarask' ),
336 "reject underscore in language code"
340 function provideLanguageCodes() {
342 array( 'fr' , 'Two letters, minor case' ),
343 array( 'EN' , 'Two letters, upper case' ),
344 array( 'tyv' , 'Three letters' ),
345 array( 'tokipona' , 'long language code' ),
346 array( 'be-tarask', 'With dash' ),
347 array( 'Zh-classical', 'Begin with upper case, dash' ),
348 array( 'Be-x-old', 'With extension (two dashes)' ),
353 * @dataProvider provideSprintfDateSamples
355 function testSprintfDate( $format, $ts, $expected, $msg ) {
358 $this->lang
->sprintfDate( $format, $ts ),
359 "sprintfDate('$format', '$ts'): $msg"
363 * bug 33454. sprintfDate should always use UTC.
364 * @dataProvider provideSprintfDateSamples
366 function testSprintfDateTZ( $format, $ts, $expected, $msg ) {
367 $oldTZ = date_default_timezone_get();
368 $res = date_default_timezone_set( 'Asia/Seoul' );
370 $this->markTestSkipped( "Error setting Timezone" );
375 $this->lang
->sprintfDate( $format, $ts ),
376 "sprintfDate('$format', '$ts'): $msg"
379 date_default_timezone_set( $oldTZ );
382 function provideSprintfDateSamples() {
387 '1390', // note because we're testing English locale we get Latin-standard digits
388 'Iranian calendar full year'
394 'Iranian calendar short year'
400 'ISO 8601 (week) year'
420 // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
443 'Month index, not zero pad'
449 'Month index. Zero pad'
467 'Genitive month name (same in EN)'
473 'Day of month (not zero pad)'
479 'Day of month (zero-pad)'
485 'Day of year (zero-indexed)'
491 'Day of week (abbrev)'
503 'Day of week (Mon=1, Sun=7)'
509 'Day of week (Sun=0, Sat=6)'
545 '12 hour, zero padded'
587 'Days in current month'
592 '2012-01-02T09:07:05+00:00',
598 'Mon, 02 Jan 2012 09:07:05 +0000',
623 'Hebrew number of days in month'
629 'Hebrew genitive month name (No difference in EN)'
665 'Raw numerals (doesn\'t mean much in EN)'
668 '[[Y "(yea"\\r)]] \\"xx\\"',
670 '[[2012 (year)]] "x"',
678 * @dataProvider provideFormatSizes
680 function testFormatSize( $size, $expected, $msg ) {
683 $this->lang
->formatSize( $size ),
684 "formatSize('$size'): $msg"
688 function provideFormatSizes() {
735 // How big!? THIS BIG!
740 * @dataProvider provideFormatBitrate
742 function testFormatBitrate( $bps, $expected, $msg ) {
745 $this->lang
->formatBitrate( $bps ),
746 "formatBitrate('$bps'): $msg"
750 function provideFormatBitrate() {
760 "999 bits per second"
765 "1 kilobit per second"
770 "1 megabit per second"
775 "1 gigabit per second"
780 "1 terabit per second"
785 "1 petabit per second"
790 "1 exabit per second"
795 "1 zetabit per second"
800 "1 yottabit per second"
805 "1,000 yottabits per second"
813 * @dataProvider provideFormatDuration
815 function testFormatDuration( $duration, $expected, $intervals = array() ) {
818 $this->lang
->formatDuration( $duration, $intervals ),
819 "formatDuration('$duration'): $expected"
823 function provideFormatDuration() {
862 365.25 * 86400, // 365.25 * 86400 = 31557600
895 '2 hours, 30 minutes and 1 second'
899 '1 hour and 1 second'
902 31557600 +
2 * 86400 +
9000,
903 '1 year, 2 days, 2 hours and 30 minutes'
906 42 * 1000 * 31557600 +
42,
907 '42 millennia and 42 seconds'
925 31557600 +
2 * 86400 +
9000,
926 '1 year, 2 days and 150 minutes',
927 array( 'years', 'days', 'minutes' ),
932 array( 'years', 'days' ),
935 31557600 +
2 * 86400 +
9000,
936 '1 year, 2 days and 150 minutes',
937 array( 'minutes', 'days', 'years' ),
942 array( 'days', 'years' ),
948 * @dataProvider provideCheckTitleEncodingData
950 function testCheckTitleEncoding( $s ) {
953 $this->lang
->checkTitleEncoding($s),
954 "checkTitleEncoding('$s')"
958 function provideCheckTitleEncodingData() {
961 array( "United States of America" ), // 7bit ASCII
962 array( rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ),
965 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
968 // The following two data sets come from bug 36839. They fail if checkTitleEncoding uses a regexp to test for
969 // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding
970 // uses mb_check_encoding for its test.
973 "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn%7C"
974 . "Catherine%20Willows%7CDavid%20Hodges%7CDavid%20Phillips%7CGil%20Grissom%7CGreg%20Sanders%7CHodges%7C"
975 . "Internet%20Movie%20Database%7CJim%20Brass%7CLady%20Heather%7C"
976 . "Les%20Experts%20(s%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e)%7CLes%20Experts%20:%20Manhattan%7C"
977 . "Les%20Experts%20:%20Miami%7CListe%20des%20personnages%20des%20Experts%7C"
978 . "Liste%20des%20%C3%A9pisodes%20des%20Experts%7CMod%C3%A8le%20discussion:Palette%20Les%20Experts%7C"
979 . "Nick%20Stokes%7CPersonnage%20de%20fiction%7CPersonnage%20fictif%7CPersonnage%20de%20fiction%7C"
980 . "Personnages%20r%C3%A9currents%20dans%20Les%20Experts%7CRaymond%20Langston%7CRiley%20Adams%7C"
981 . "Saison%201%20des%20Experts%7CSaison%2010%20des%20Experts%7CSaison%2011%20des%20Experts%7C"
982 . "Saison%2012%20des%20Experts%7CSaison%202%20des%20Experts%7CSaison%203%20des%20Experts%7C"
983 . "Saison%204%20des%20Experts%7CSaison%205%20des%20Experts%7CSaison%206%20des%20Experts%7C"
984 . "Saison%207%20des%20Experts%7CSaison%208%20des%20Experts%7CSaison%209%20des%20Experts%7C"
985 . "Sara%20Sidle%7CSofia%20Curtis%7CS%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e%7CWallace%20Langham%7C"
986 . "Warrick%20Brown%7CWendy%20Simms%7C%C3%89tats-Unis"
991 "Mod%C3%A8le%3AArrondissements%20homonymes%7CMod%C3%A8le%3ABandeau%20standard%20pour%20page%20d'homonymie%7C"
992 . "Mod%C3%A8le%3ABatailles%20homonymes%7CMod%C3%A8le%3ACantons%20homonymes%7C"
993 . "Mod%C3%A8le%3ACommunes%20fran%C3%A7aises%20homonymes%7CMod%C3%A8le%3AFilms%20homonymes%7C"
994 . "Mod%C3%A8le%3AGouvernements%20homonymes%7CMod%C3%A8le%3AGuerres%20homonymes%7CMod%C3%A8le%3AHomonymie%7C"
995 . "Mod%C3%A8le%3AHomonymie%20bateau%7CMod%C3%A8le%3AHomonymie%20d'%C3%A9tablissements%20scolaires%20ou"
996 . "%20universitaires%7CMod%C3%A8le%3AHomonymie%20d'%C3%AEles%7CMod%C3%A8le%3AHomonymie%20de%20clubs%20sportifs%7C"
997 . "Mod%C3%A8le%3AHomonymie%20de%20comt%C3%A9s%7CMod%C3%A8le%3AHomonymie%20de%20monument%7C"
998 . "Mod%C3%A8le%3AHomonymie%20de%20nom%20romain%7CMod%C3%A8le%3AHomonymie%20de%20parti%20politique%7C"
999 . "Mod%C3%A8le%3AHomonymie%20de%20route%7CMod%C3%A8le%3AHomonymie%20dynastique%7C"
1000 . "Mod%C3%A8le%3AHomonymie%20vid%C3%A9oludique%7CMod%C3%A8le%3AHomonymie%20%C3%A9difice%20religieux%7C"
1001 . "Mod%C3%A8le%3AInternationalisation%7CMod%C3%A8le%3AIsom%C3%A9rie%7CMod%C3%A8le%3AParonymie%7C"
1002 . "Mod%C3%A8le%3APatronyme%7CMod%C3%A8le%3APatronyme%20basque%7CMod%C3%A8le%3APatronyme%20italien%7C"
1003 . "Mod%C3%A8le%3APatronymie%7CMod%C3%A8le%3APersonnes%20homonymes%7CMod%C3%A8le%3ASaints%20homonymes%7C"
1004 . "Mod%C3%A8le%3ATitres%20homonymes%7CMod%C3%A8le%3AToponymie%7CMod%C3%A8le%3AUnit%C3%A9s%20homonymes%7C"
1005 . "Mod%C3%A8le%3AVilles%20homonymes%7CMod%C3%A8le%3A%C3%89difices%20religieux%20homonymes"