f4f80d6920a3209c8657304d70276418b7de52a6
[lhc/web/wiklou.git] / tests / phpunit / languages / LanguageTest.php
1 <?php
2
3 class LanguageTest extends MediaWikiTestCase {
4
5 /**
6 * @var Language
7 */
8 private $lang;
9
10 function setUp() {
11 $this->lang = Language::factory( 'en' );
12 }
13 function tearDown() {
14 unset( $this->lang );
15 }
16
17 function testLanguageConvertDoubleWidthToSingleWidth() {
18 $this->assertEquals(
19 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
20 $this->lang->normalizeForSearch(
21 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
22 ),
23 'convertDoubleWidth() with the full alphabet and digits'
24 );
25 }
26
27 /** @dataProvider provideFormattableTimes */
28 function testFormatTimePeriod( $seconds, $format, $expected, $desc ) {
29 $this->assertEquals( $expected, $this->lang->formatTimePeriod( $seconds, $format ), $desc );
30 }
31
32 function provideFormattableTimes() {
33 return array(
34 array( 9.45, array(), '9.5s', 'formatTimePeriod() rounding (<10s)' ),
35 array( 9.45, array( 'noabbrevs' => true ), '9.5 seconds', 'formatTimePeriod() rounding (<10s)' ),
36 array( 9.95, array(), '10s', 'formatTimePeriod() rounding (<10s)' ),
37 array( 9.95, array( 'noabbrevs' => true ), '10 seconds', 'formatTimePeriod() rounding (<10s)' ),
38 array( 59.55, array(), '1m 0s', 'formatTimePeriod() rounding (<60s)' ),
39 array( 59.55, array( 'noabbrevs' => true ), '1 minute 0 seconds', 'formatTimePeriod() rounding (<60s)' ),
40 array( 119.55, array(), '2m 0s', 'formatTimePeriod() rounding (<1h)' ),
41 array( 119.55, array( 'noabbrevs' => true ), '2 minutes 0 seconds', 'formatTimePeriod() rounding (<1h)' ),
42 array( 3599.55, array(), '1h 0m 0s', 'formatTimePeriod() rounding (<1h)' ),
43 array( 3599.55, array( 'noabbrevs' => true ), '1 hour 0 minutes 0 seconds', 'formatTimePeriod() rounding (<1h)' ),
44 array( 7199.55, array(), '2h 0m 0s', 'formatTimePeriod() rounding (>=1h)' ),
45 array( 7199.55, array( 'noabbrevs' => true ), '2 hours 0 minutes 0 seconds', 'formatTimePeriod() rounding (>=1h)' ),
46 array( 7199.55, 'avoidseconds', '2h 0m', 'formatTimePeriod() rounding (>=1h), avoidseconds' ),
47 array( 7199.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 hours 0 minutes', 'formatTimePeriod() rounding (>=1h), avoidseconds' ),
48 array( 7199.55, 'avoidminutes', '2h 0m', 'formatTimePeriod() rounding (>=1h), avoidminutes' ),
49 array( 7199.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '2 hours 0 minutes', 'formatTimePeriod() rounding (>=1h), avoidminutes' ),
50 array( 172799.55, 'avoidseconds', '48h 0m', 'formatTimePeriod() rounding (=48h), avoidseconds' ),
51 array( 172799.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '48 hours 0 minutes', 'formatTimePeriod() rounding (=48h), avoidseconds' ),
52 array( 259199.55, 'avoidminutes', '3d 0h', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
53 array( 259199.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '3 days 0 hours', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
54 array( 176399.55, 'avoidseconds', '2d 1h 0m', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
55 array( 176399.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 days 1 hour 0 minutes', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
56 array( 176399.55, 'avoidminutes', '2d 1h', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
57 array( 176399.55, array( 'avoid' => 'avoidminutes', 'noabbrevs' => true ), '2 days 1 hour', 'formatTimePeriod() rounding (>48h), avoidminutes' ),
58 array( 259199.55, 'avoidseconds', '3d 0h 0m', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
59 array( 259199.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '3 days 0 hours 0 minutes', 'formatTimePeriod() rounding (>48h), avoidseconds' ),
60 array( 172801.55, 'avoidseconds', '2d 0h 0m', 'formatTimePeriod() rounding, (>48h), avoidseconds' ),
61 array( 172801.55, array( 'avoid' => 'avoidseconds', 'noabbrevs' => true ), '2 days 0 hours 0 minutes', 'formatTimePeriod() rounding, (>48h), avoidseconds' ),
62 array( 176460.55, array(), '2d 1h 1m 1s', 'formatTimePeriod() rounding, recursion, (>48h)' ),
63 array( 176460.55, array( 'noabbrevs' => true ), '2 days 1 hour 1 minute 1 second', 'formatTimePeriod() rounding, recursion, (>48h)' ),
64 );
65
66 }
67
68 function testTruncate() {
69 $this->assertEquals(
70 "XXX",
71 $this->lang->truncate( "1234567890", 0, 'XXX' ),
72 'truncate prefix, len 0, small ellipsis'
73 );
74
75 $this->assertEquals(
76 "12345XXX",
77 $this->lang->truncate( "1234567890", 8, 'XXX' ),
78 'truncate prefix, small ellipsis'
79 );
80
81 $this->assertEquals(
82 "123456789",
83 $this->lang->truncate( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
84 'truncate prefix, large ellipsis'
85 );
86
87 $this->assertEquals(
88 "XXX67890",
89 $this->lang->truncate( "1234567890", -8, 'XXX' ),
90 'truncate suffix, small ellipsis'
91 );
92
93 $this->assertEquals(
94 "123456789",
95 $this->lang->truncate( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
96 'truncate suffix, large ellipsis'
97 );
98 }
99
100 /**
101 * @dataProvider provideHTMLTruncateData()
102 */
103 function testTruncateHtml( $len, $ellipsis, $input, $expected ) {
104 // Actual HTML...
105 $this->assertEquals(
106 $expected,
107 $this->lang->truncateHTML( $input, $len, $ellipsis )
108 );
109 }
110
111 /**
112 * Array format is ($len, $ellipsis, $input, $expected)
113 */
114 function provideHTMLTruncateData() {
115 return array(
116 array( 0, 'XXX', "1234567890", "XXX" ),
117 array( 8, 'XXX', "1234567890", "12345XXX" ),
118 array( 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ),
119 array( 2, '***',
120 '<p><span style="font-weight:bold;"></span></p>',
121 '<p><span style="font-weight:bold;"></span></p>',
122 ),
123 array( 2, '***',
124 '<p><span style="font-weight:bold;">123456789</span></p>',
125 '<p><span style="font-weight:bold;">***</span></p>',
126 ),
127 array( 2, '***',
128 '<p><span style="font-weight:bold;">&nbsp;23456789</span></p>',
129 '<p><span style="font-weight:bold;">***</span></p>',
130 ),
131 array( 3, '***',
132 '<p><span style="font-weight:bold;">123456789</span></p>',
133 '<p><span style="font-weight:bold;">***</span></p>',
134 ),
135 array( 4, '***',
136 '<p><span style="font-weight:bold;">123456789</span></p>',
137 '<p><span style="font-weight:bold;">1***</span></p>',
138 ),
139 array( 5, '***',
140 '<tt><span style="font-weight:bold;">123456789</span></tt>',
141 '<tt><span style="font-weight:bold;">12***</span></tt>',
142 ),
143 array( 6, '***',
144 '<p><a href="www.mediawiki.org">123456789</a></p>',
145 '<p><a href="www.mediawiki.org">123***</a></p>',
146 ),
147 array( 6, '***',
148 '<p><a href="www.mediawiki.org">12&nbsp;456789</a></p>',
149 '<p><a href="www.mediawiki.org">12&nbsp;***</a></p>',
150 ),
151 array( 7, '***',
152 '<small><span style="font-weight:bold;">123<p id="#moo">456</p>789</span></small>',
153 '<small><span style="font-weight:bold;">123<p id="#moo">4***</p></span></small>',
154 ),
155 array( 8, '***',
156 '<div><span style="font-weight:bold;">123<span>4</span>56789</span></div>',
157 '<div><span style="font-weight:bold;">123<span>4</span>5***</span></div>',
158 ),
159 array( 9, '***',
160 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
161 '<p><table style="font-weight:bold;"><tr><td>123456789</td></tr></table></p>',
162 ),
163 array( 10, '***',
164 '<p><font style="font-weight:bold;">123456789</font></p>',
165 '<p><font style="font-weight:bold;">123456789</font></p>',
166 ),
167 );
168 }
169
170 /**
171 * Test Language::isValidBuiltInCode()
172 * @dataProvider provideLanguageCodes
173 */
174 function testBuiltInCodeValidation( $code, $message = '' ) {
175 $this->assertTrue(
176 (bool) Language::isValidBuiltInCode( $code ),
177 "validating code $code $message"
178 );
179 }
180
181 function testBuiltInCodeValidationRejectUnderscore() {
182 $this->assertFalse(
183 (bool) Language::isValidBuiltInCode( 'be_tarask' ),
184 "reject underscore in language code"
185 );
186 }
187
188 function provideLanguageCodes() {
189 return array(
190 array( 'fr' , 'Two letters, minor case' ),
191 array( 'EN' , 'Two letters, upper case' ),
192 array( 'tyv' , 'Three letters' ),
193 array( 'tokipona' , 'long language code' ),
194 array( 'be-tarask', 'With dash' ),
195 array( 'Zh-classical', 'Begin with upper case, dash' ),
196 array( 'Be-x-old', 'With extension (two dashes)' ),
197 );
198 }
199
200 /**
201 * @dataProvider provideSprintfDateSamples
202 */
203 function testSprintfDate( $format, $ts, $expected, $msg ) {
204 $this->assertEquals(
205 $expected,
206 $this->lang->sprintfDate( $format, $ts ),
207 "sprintfDate('$format', '$ts'): $msg"
208 );
209 }
210 /**
211 * bug 33454. sprintfDate should always use UTC.
212 * @dataProvider provideSprintfDateSamples
213 */
214 function testSprintfDateTZ( $format, $ts, $expected, $msg ) {
215 $oldTZ = date_default_timezone_get();
216 $res = date_default_timezone_set( 'Asia/Seoul' );
217 if ( !$res ) {
218 $this->markTestSkipped( "Error setting Timezone" );
219 }
220
221 $this->assertEquals(
222 $expected,
223 $this->lang->sprintfDate( $format, $ts ),
224 "sprintfDate('$format', '$ts'): $msg"
225 );
226
227 date_default_timezone_set( $oldTZ );
228 }
229
230 function provideSprintfDateSamples() {
231 return array(
232 array(
233 'xiY',
234 '20111212000000',
235 '1390', // note because we're testing English locale we get Latin-standard digits
236 'Iranian calendar full year'
237 ),
238 array(
239 'xiy',
240 '20111212000000',
241 '90',
242 'Iranian calendar short year'
243 ),
244 array(
245 'o',
246 '20120101235000',
247 '2011',
248 'ISO 8601 (week) year'
249 ),
250 array(
251 'W',
252 '20120101235000',
253 '52',
254 'Week number'
255 ),
256 array(
257 'W',
258 '20120102235000',
259 '1',
260 'Week number'
261 ),
262 array(
263 'o-\\WW-N',
264 '20091231235000',
265 '2009-W53-4',
266 'leap week'
267 ),
268 // What follows is mostly copied from http://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
269 array(
270 'Y',
271 '20120102090705',
272 '2012',
273 'Full year'
274 ),
275 array(
276 'y',
277 '20120102090705',
278 '12',
279 '2 digit year'
280 ),
281 array(
282 'L',
283 '20120102090705',
284 '1',
285 'Leap year'
286 ),
287 array(
288 'n',
289 '20120102090705',
290 '1',
291 'Month index, not zero pad'
292 ),
293 array(
294 'N',
295 '20120102090705',
296 '01',
297 'Month index. Zero pad'
298 ),
299 array(
300 'M',
301 '20120102090705',
302 'Jan',
303 'Month abbrev'
304 ),
305 array(
306 'F',
307 '20120102090705',
308 'January',
309 'Full month'
310 ),
311 array(
312 'xg',
313 '20120102090705',
314 'January',
315 'Genitive month name (same in EN)'
316 ),
317 array(
318 'j',
319 '20120102090705',
320 '2',
321 'Day of month (not zero pad)'
322 ),
323 array(
324 'd',
325 '20120102090705',
326 '02',
327 'Day of month (zero-pad)'
328 ),
329 array(
330 'z',
331 '20120102090705',
332 '1',
333 'Day of year (zero-indexed)'
334 ),
335 array(
336 'D',
337 '20120102090705',
338 'Mon',
339 'Day of week (abbrev)'
340 ),
341 array(
342 'l',
343 '20120102090705',
344 'Monday',
345 'Full day of week'
346 ),
347 array(
348 'N',
349 '20120101090705',
350 '7',
351 'Day of week (Mon=1, Sun=7)'
352 ),
353 array(
354 'w',
355 '20120101090705',
356 '0',
357 'Day of week (Sun=0, Sat=6)'
358 ),
359 array(
360 'N',
361 '20120102090705',
362 '1',
363 'Day of week'
364 ),
365 array(
366 'a',
367 '20120102090705',
368 'am',
369 'am vs pm'
370 ),
371 array(
372 'A',
373 '20120102120000',
374 'PM',
375 'AM vs PM'
376 ),
377 array(
378 'a',
379 '20120102000000',
380 'am',
381 'AM vs PM'
382 ),
383 array(
384 'g',
385 '20120102090705',
386 '9',
387 '12 hour, not Zero'
388 ),
389 array(
390 'h',
391 '20120102090705',
392 '09',
393 '12 hour, zero padded'
394 ),
395 array(
396 'G',
397 '20120102090705',
398 '9',
399 '24 hour, not zero'
400 ),
401 array(
402 'H',
403 '20120102090705',
404 '09',
405 '24 hour, zero'
406 ),
407 array(
408 'H',
409 '20120102110705',
410 '11',
411 '24 hour, zero'
412 ),
413 array(
414 'i',
415 '20120102090705',
416 '07',
417 'Minutes'
418 ),
419 array(
420 's',
421 '20120102090705',
422 '05',
423 'seconds'
424 ),
425 array(
426 'U',
427 '20120102090705',
428 '1325495225',
429 'unix time'
430 ),
431 array(
432 't',
433 '20120102090705',
434 '31',
435 'Days in current month'
436 ),
437 array(
438 'c',
439 '20120102090705',
440 '2012-01-02T09:07:05+00:00',
441 'ISO 8601 timestamp'
442 ),
443 array(
444 'r',
445 '20120102090705',
446 'Mon, 02 Jan 2012 09:07:05 +0000',
447 'RFC 5322'
448 ),
449 array(
450 'xmj xmF xmn xmY',
451 '20120102090705',
452 '7 Safar 2 1433',
453 'Islamic'
454 ),
455 array(
456 'xij xiF xin xiY',
457 '20120102090705',
458 '12 Dey 10 1390',
459 'Iranian'
460 ),
461 array(
462 'xjj xjF xjn xjY',
463 '20120102090705',
464 '7 Tevet 4 5772',
465 'Hebrew'
466 ),
467 array(
468 'xjt',
469 '20120102090705',
470 '29',
471 'Hebrew number of days in month'
472 ),
473 array(
474 'xjx',
475 '20120102090705',
476 'Tevet',
477 'Hebrew genitive month name (No difference in EN)'
478 ),
479 array(
480 'xkY',
481 '20120102090705',
482 '2555',
483 'Thai year'
484 ),
485 array(
486 'xoY',
487 '20120102090705',
488 '101',
489 'Minguo'
490 ),
491 array(
492 'xtY',
493 '20120102090705',
494 '平成24',
495 'nengo'
496 ),
497 array(
498 'xrxkYY',
499 '20120102090705',
500 'MMDLV2012',
501 'Roman numerals'
502 ),
503 array(
504 'xhxjYY',
505 '20120102090705',
506 \'תשע"ב2012',
507 'Hebrew numberals'
508 ),
509 array(
510 'xnY',
511 '20120102090705',
512 '2012',
513 'Raw numerals (doesn\'t mean much in EN)'
514 ),
515 array(
516 '[[Y "(yea"\\r)]] \\"xx\\"',
517 '20120102090705',
518 '[[2012 (year)]] "x"',
519 'Various escaping'
520 ),
521
522 );
523 }
524
525 /**
526 * @dataProvider provideFormatSizes
527 */
528 function testFormatSize( $size, $expected, $msg ) {
529 $this->assertEquals(
530 $expected,
531 $this->lang->formatSize( $size ),
532 "formatSize('$size'): $msg"
533 );
534 }
535
536 function provideFormatSizes() {
537 return array(
538 array(
539 0,
540 "0 B",
541 "Zero bytes"
542 ),
543 array(
544 1024,
545 "1 KB",
546 "1 kilobyte"
547 ),
548 array(
549 1024 * 1024,
550 "1 MB",
551 "1,024 megabytes"
552 ),
553 array(
554 1024 * 1024 * 1024,
555 "1 GB",
556 "1 gigabytes"
557 ),
558 array(
559 pow( 1024, 4 ),
560 "1 TB",
561 "1 terabyte"
562 ),
563 array(
564 pow( 1024, 5 ),
565 "1 PB",
566 "1 petabyte"
567 ),
568 array(
569 pow( 1024, 6 ),
570 "1 EB",
571 "1,024 exabyte"
572 ),
573 array(
574 pow( 1024, 7 ),
575 "1 ZB",
576 "1 zetabyte"
577 ),
578 array(
579 pow( 1024, 8 ),
580 "1 YB",
581 "1 yottabyte"
582 ),
583 // How big!? THIS BIG!
584 );
585 }
586
587 /**
588 * @dataProvider provideFormatBitrate
589 */
590 function testFormatBitrate( $bps, $expected, $msg ) {
591 $this->assertEquals(
592 $expected,
593 $this->lang->formatBitrate( $bps ),
594 "formatBitrate('$bps'): $msg"
595 );
596 }
597
598 function provideFormatBitrate() {
599 return array(
600 array(
601 0,
602 "0bps",
603 "0 bits per second"
604 ),
605 array(
606 999,
607 "999bps",
608 "1 bits per second"
609 ),
610 array(
611 1000,
612 "1kbps",
613 "1 kilobit per second"
614 ),
615 array(
616 1000 * 1000,
617 "1Mbps",
618 "1 megabit per second"
619 ),
620 array(
621 pow( 10, 9 ),
622 "1Gbps",
623 "1 gigabit per second"
624 ),
625 array(
626 pow( 10, 12 ),
627 "1Tbps",
628 "1 terabit per second"
629 ),
630 array(
631 pow( 10, 15 ),
632 "1Pbps",
633 "1 petabit per second"
634 ),
635 array(
636 pow( 10, 18 ),
637 "1Ebps",
638 "1 exabit per second"
639 ),
640 array(
641 pow( 10, 21 ),
642 "1Zbps",
643 "1 zetabit per second"
644 ),
645 array(
646 pow( 10, 24 ),
647 "1Ybps",
648 "1 yottabit per second"
649 ),
650 array(
651 pow( 10, 27 ),
652 "1,000Ybps",
653 "1,000 yottabits per second"
654 ),
655 );
656 }
657 }