MediaWiki  1.33.0
LanguageTest.php
Go to the documentation of this file.
1 <?php
2 
3 use Wikimedia\TestingAccessWrapper;
4 
11  $this->assertEquals(
12  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
13  $this->getLang()->normalizeForSearch(
14  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
15  ),
16  'convertDoubleWidth() with the full alphabet and digits'
17  );
18  }
19 
24  public function testFormatTimePeriod( $seconds, $format, $expected, $desc ) {
25  $this->assertEquals( $expected, $this->getLang()->formatTimePeriod( $seconds, $format ), $desc );
26  }
27 
28  public static function provideFormattableTimes() {
29  return [
30  [
31  9.45,
32  [],
33  '9.5 s',
34  'formatTimePeriod() rounding (<10s)'
35  ],
36  [
37  9.45,
38  [ 'noabbrevs' => true ],
39  '9.5 seconds',
40  'formatTimePeriod() rounding (<10s)'
41  ],
42  [
43  9.95,
44  [],
45  '10 s',
46  'formatTimePeriod() rounding (<10s)'
47  ],
48  [
49  9.95,
50  [ 'noabbrevs' => true ],
51  '10 seconds',
52  'formatTimePeriod() rounding (<10s)'
53  ],
54  [
55  59.55,
56  [],
57  '1 min 0 s',
58  'formatTimePeriod() rounding (<60s)'
59  ],
60  [
61  59.55,
62  [ 'noabbrevs' => true ],
63  '1 minute 0 seconds',
64  'formatTimePeriod() rounding (<60s)'
65  ],
66  [
67  119.55,
68  [],
69  '2 min 0 s',
70  'formatTimePeriod() rounding (<1h)'
71  ],
72  [
73  119.55,
74  [ 'noabbrevs' => true ],
75  '2 minutes 0 seconds',
76  'formatTimePeriod() rounding (<1h)'
77  ],
78  [
79  3599.55,
80  [],
81  '1 h 0 min 0 s',
82  'formatTimePeriod() rounding (<1h)'
83  ],
84  [
85  3599.55,
86  [ 'noabbrevs' => true ],
87  '1 hour 0 minutes 0 seconds',
88  'formatTimePeriod() rounding (<1h)'
89  ],
90  [
91  7199.55,
92  [],
93  '2 h 0 min 0 s',
94  'formatTimePeriod() rounding (>=1h)'
95  ],
96  [
97  7199.55,
98  [ 'noabbrevs' => true ],
99  '2 hours 0 minutes 0 seconds',
100  'formatTimePeriod() rounding (>=1h)'
101  ],
102  [
103  7199.55,
104  'avoidseconds',
105  '2 h 0 min',
106  'formatTimePeriod() rounding (>=1h), avoidseconds'
107  ],
108  [
109  7199.55,
110  [ 'avoid' => 'avoidseconds', 'noabbrevs' => true ],
111  '2 hours 0 minutes',
112  'formatTimePeriod() rounding (>=1h), avoidseconds'
113  ],
114  [
115  7199.55,
116  'avoidminutes',
117  '2 h 0 min',
118  'formatTimePeriod() rounding (>=1h), avoidminutes'
119  ],
120  [
121  7199.55,
122  [ 'avoid' => 'avoidminutes', 'noabbrevs' => true ],
123  '2 hours 0 minutes',
124  'formatTimePeriod() rounding (>=1h), avoidminutes'
125  ],
126  [
127  172799.55,
128  'avoidseconds',
129  '48 h 0 min',
130  'formatTimePeriod() rounding (=48h), avoidseconds'
131  ],
132  [
133  172799.55,
134  [ 'avoid' => 'avoidseconds', 'noabbrevs' => true ],
135  '48 hours 0 minutes',
136  'formatTimePeriod() rounding (=48h), avoidseconds'
137  ],
138  [
139  259199.55,
140  'avoidminutes',
141  '3 d 0 h',
142  'formatTimePeriod() rounding (>48h), avoidminutes'
143  ],
144  [
145  259199.55,
146  [ 'avoid' => 'avoidminutes', 'noabbrevs' => true ],
147  '3 days 0 hours',
148  'formatTimePeriod() rounding (>48h), avoidminutes'
149  ],
150  [
151  176399.55,
152  'avoidseconds',
153  '2 d 1 h 0 min',
154  'formatTimePeriod() rounding (>48h), avoidseconds'
155  ],
156  [
157  176399.55,
158  [ 'avoid' => 'avoidseconds', 'noabbrevs' => true ],
159  '2 days 1 hour 0 minutes',
160  'formatTimePeriod() rounding (>48h), avoidseconds'
161  ],
162  [
163  176399.55,
164  'avoidminutes',
165  '2 d 1 h',
166  'formatTimePeriod() rounding (>48h), avoidminutes'
167  ],
168  [
169  176399.55,
170  [ 'avoid' => 'avoidminutes', 'noabbrevs' => true ],
171  '2 days 1 hour',
172  'formatTimePeriod() rounding (>48h), avoidminutes'
173  ],
174  [
175  259199.55,
176  'avoidseconds',
177  '3 d 0 h 0 min',
178  'formatTimePeriod() rounding (>48h), avoidseconds'
179  ],
180  [
181  259199.55,
182  [ 'avoid' => 'avoidseconds', 'noabbrevs' => true ],
183  '3 days 0 hours 0 minutes',
184  'formatTimePeriod() rounding (>48h), avoidseconds'
185  ],
186  [
187  172801.55,
188  'avoidseconds',
189  '2 d 0 h 0 min',
190  'formatTimePeriod() rounding, (>48h), avoidseconds'
191  ],
192  [
193  172801.55,
194  [ 'avoid' => 'avoidseconds', 'noabbrevs' => true ],
195  '2 days 0 hours 0 minutes',
196  'formatTimePeriod() rounding, (>48h), avoidseconds'
197  ],
198  [
199  176460.55,
200  [],
201  '2 d 1 h 1 min 1 s',
202  'formatTimePeriod() rounding, recursion, (>48h)'
203  ],
204  [
205  176460.55,
206  [ 'noabbrevs' => true ],
207  '2 days 1 hour 1 minute 1 second',
208  'formatTimePeriod() rounding, recursion, (>48h)'
209  ],
210  ];
211  }
212 
217  public function testTruncateForDatabase() {
218  $this->assertEquals(
219  "XXX",
220  $this->getLang()->truncateForDatabase( "1234567890", 0, 'XXX' ),
221  'truncate prefix, len 0, small ellipsis'
222  );
223 
224  $this->assertEquals(
225  "12345XXX",
226  $this->getLang()->truncateForDatabase( "1234567890", 8, 'XXX' ),
227  'truncate prefix, small ellipsis'
228  );
229 
230  $this->assertEquals(
231  "123456789",
232  $this->getLang()->truncateForDatabase( "123456789", 5, 'XXXXXXXXXXXXXXX' ),
233  'truncate prefix, large ellipsis'
234  );
235 
236  $this->assertEquals(
237  "XXX67890",
238  $this->getLang()->truncateForDatabase( "1234567890", -8, 'XXX' ),
239  'truncate suffix, small ellipsis'
240  );
241 
242  $this->assertEquals(
243  "123456789",
244  $this->getLang()->truncateForDatabase( "123456789", -5, 'XXXXXXXXXXXXXXX' ),
245  'truncate suffix, large ellipsis'
246  );
247  $this->assertEquals(
248  "123XXX",
249  $this->getLang()->truncateForDatabase( "123 ", 9, 'XXX' ),
250  'truncate prefix, with spaces'
251  );
252  $this->assertEquals(
253  "12345XXX",
254  $this->getLang()->truncateForDatabase( "12345 8", 11, 'XXX' ),
255  'truncate prefix, with spaces and non-space ending'
256  );
257  $this->assertEquals(
258  "XXX234",
259  $this->getLang()->truncateForDatabase( "1 234", -8, 'XXX' ),
260  'truncate suffix, with spaces'
261  );
262  $this->assertEquals(
263  "12345XXX",
264  $this->getLang()->truncateForDatabase( "1234567890", 5, 'XXX', false ),
265  'truncate without adjustment'
266  );
267  $this->assertEquals(
268  "泰乐菌...",
269  $this->getLang()->truncateForDatabase( "泰乐菌素123456789", 11, '...', false ),
270  'truncate does not chop Unicode characters in half'
271  );
272  $this->assertEquals(
273  "\n泰乐菌...",
274  $this->getLang()->truncateForDatabase( "\n泰乐菌素123456789", 12, '...', false ),
275  'truncate does not chop Unicode characters in half if there is a preceding newline'
276  );
277  }
278 
284  public function testTruncateForVisual(
285  $expected, $string, $length, $ellipsis = '...', $adjustLength = true
286  ) {
287  $this->assertEquals(
288  $expected,
289  $this->getLang()->truncateForVisual( $string, $length, $ellipsis, $adjustLength )
290  );
291  }
292 
296  public static function provideTruncateData() {
297  return [
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 ],
309  ];
310  }
311 
316  public function testTruncateHtml( $len, $ellipsis, $input, $expected ) {
317  // Actual HTML...
318  $this->assertEquals(
319  $expected,
320  $this->getLang()->truncateHtml( $input, $len, $ellipsis )
321  );
322  }
323 
327  public static function provideHTMLTruncateData() {
328  return [
329  [ 0, 'XXX', "1234567890", "XXX" ],
330  [ 8, 'XXX', "1234567890", "12345XXX" ],
331  [ 5, 'XXXXXXXXXXXXXXX', '1234567890', "1234567890" ],
332  [ 2, '***',
333  '<p><span style="font-weight:bold;"></span></p>',
334  '<p><span style="font-weight:bold;"></span></p>',
335  ],
336  [ 2, '***',
337  '<p><span style="font-weight:bold;">123456789</span></p>',
338  '<p><span style="font-weight:bold;">***</span></p>',
339  ],
340  [ 2, '***',
341  '<p><span style="font-weight:bold;">&nbsp;23456789</span></p>',
342  '<p><span style="font-weight:bold;">***</span></p>',
343  ],
344  [ 3, '***',
345  '<p><span style="font-weight:bold;">123456789</span></p>',
346  '<p><span style="font-weight:bold;">***</span></p>',
347  ],
348  [ 4, '***',
349  '<p><span style="font-weight:bold;">123456789</span></p>',
350  '<p><span style="font-weight:bold;">1***</span></p>',
351  ],
352  [ 5, '***',
353  '<tt><span style="font-weight:bold;">123456789</span></tt>',
354  '<tt><span style="font-weight:bold;">12***</span></tt>',
355  ],
356  [ 6, '***',
357  '<p><a href="www.mediawiki.org">123456789</a></p>',
358  '<p><a href="www.mediawiki.org">123***</a></p>',
359  ],
360  [ 6, '***',
361  '<p><a href="www.mediawiki.org">12&nbsp;456789</a></p>',
362  '<p><a href="www.mediawiki.org">12&nbsp;***</a></p>',
363  ],
364  [ 7, '***',
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>',
367  ],
368  [ 8, '***',
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>',
371  ],
372  [ 9, '***',
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>',
375  ],
376  [ 10, '***',
377  '<p><font style="font-weight:bold;">123456789</font></p>',
378  '<p><font style="font-weight:bold;">123456789</font></p>',
379  ],
380  ];
381  }
382 
388  public function testWellFormedLanguageTag( $code, $message = '' ) {
389  $this->assertTrue(
391  "validating code $code $message"
392  );
393  }
394 
401  public static function provideWellFormedLanguageTags() {
402  return [
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' ],
432  ];
433  }
434 
440  public function testMalformedLanguageTag( $code, $message = '' ) {
441  $this->assertFalse(
443  "validating that code $code is a malformed language tag - $message"
444  );
445  }
446 
453  public static function provideMalformedLanguageTags() {
454  return [
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' ],
461  [
462  'i-notexist',
463  'grandfathered but not registered: invalid, even if we only test well-formedness'
464  ],
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' ],
487  ];
488  }
489 
494  public function testLenientLanguageTag() {
495  $this->assertTrue(
496  Language::isWellFormedLanguageTag( 'pa_guru', true ),
497  'pa_guru is a well-formed language tag in lenient mode'
498  );
499  }
500 
506  public function testBuiltInCodeValidation( $code, $expected, $message = '' ) {
507  $this->assertEquals( $expected,
509  "validating code $code $message"
510  );
511  }
512 
513  public static function provideLanguageCodes() {
514  return [
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' ],
521  ];
522  }
523 
529  public function testKnownLanguageTag( $code, $message = '' ) {
530  $this->assertTrue(
532  "validating code $code - $message"
533  );
534  }
535 
536  public static function provideKnownLanguageTags() {
537  return [
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' ],
541  ];
542  }
543 
547  public function testKnownCldrLanguageTag() {
548  if ( !class_exists( 'LanguageNames' ) ) {
549  $this->markTestSkipped( 'The LanguageNames class is not available. '
550  . 'The CLDR extension is probably not installed.' );
551  }
552 
553  $this->assertTrue(
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'
557  );
558  }
559 
565  public function testUnknownLanguageTag( $code, $message = '' ) {
566  $this->assertFalse(
568  "checking that code $code is invalid - $message"
569  );
570  }
571 
572  public static function provideUnknownLanguageTags() {
573  return [
574  [ 'mw', 'non-existent two-letter code' ],
575  [ 'foo"<bar', 'very invalid language code' ],
576  ];
577  }
578 
585  $this->getLang()->sprintfDate( 'xiY', '1234567890123' );
586  }
587 
594  $this->getLang()->sprintfDate( 'xiY', '123456789012345' );
595  }
596 
603  $this->getLang()->sprintfDate( 'xiY', '-1234567890123' );
604  }
605 
610  public function testSprintfDate( $format, $ts, $expected, $msg ) {
611  $ttl = null;
612  $this->assertEquals(
613  $expected,
614  $this->getLang()->sprintfDate( $format, $ts, null, $ttl ),
615  "sprintfDate('$format', '$ts'): $msg"
616  );
617  if ( $ttl ) {
618  $dt = new DateTime( $ts );
619  $lastValidTS = $dt->add( new DateInterval( 'PT' . ( $ttl - 1 ) . 'S' ) )->format( 'YmdHis' );
620  $this->assertEquals(
621  $expected,
622  $this->getLang()->sprintfDate( $format, $lastValidTS, null ),
623  "sprintfDate('$format', '$ts'): TTL $ttl too high (output was different at $lastValidTS)"
624  );
625  } else {
626  // advance the time enough to make all of the possible outputs different (except possibly L)
627  $dt = new DateTime( $ts );
628  $newTS = $dt->add( new DateInterval( 'P1Y1M8DT13H1M1S' ) )->format( 'YmdHis' );
629  $this->assertEquals(
630  $expected,
631  $this->getLang()->sprintfDate( $format, $newTS, null ),
632  "sprintfDate('$format', '$ts'): Missing TTL (output was different at $newTS)"
633  );
634  }
635  }
636 
642  public function testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg ) {
643  $oldTZ = date_default_timezone_get();
644  $res = date_default_timezone_set( 'Asia/Seoul' );
645  if ( !$res ) {
646  $this->markTestSkipped( "Error setting Timezone" );
647  }
648 
649  $this->assertEquals(
650  $expected,
651  $this->getLang()->sprintfDate( $format, $ts ),
652  "sprintfDate('$format', '$ts'): $msg"
653  );
654 
655  date_default_timezone_set( $oldTZ );
656  }
657 
663  public function testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg ) {
664  $tz = new DateTimeZone( 'Asia/Seoul' );
665  if ( !$tz ) {
666  $this->markTestSkipped( "Error getting Timezone" );
667  }
668 
669  $this->assertEquals(
670  $expected,
671  $this->getLang()->sprintfDate( $format, $ts, $tz ),
672  "sprintfDate('$format', '$ts', 'Asia/Seoul'): $msg"
673  );
674  }
675 
681  $noTtl = 'unused'; // Value used to represent that the caller didn't pass a variable in.
682  $ttl = null;
683  $this->getLang()->sprintfDate( 'YmdHis', wfTimestampNow(), null, $noTtl );
684  $this->getLang()->sprintfDate( 'YmdHis', wfTimestampNow(), null, $ttl );
685 
686  $this->assertSame(
687  'unused',
688  $noTtl,
689  'If the caller does not set the $ttl variable, do not compute it.'
690  );
691  $this->assertInternalType( 'int', $ttl, 'TTL should have been computed.' );
692  }
693 
694  public static function provideSprintfDateSamples() {
695  return [
696  [
697  'xiY',
698  '20111212000000',
699  '1390', // note because we're testing English locale we get Latin-standard digits
700  '1390',
701  'Iranian calendar full year'
702  ],
703  [
704  'xiy',
705  '20111212000000',
706  '90',
707  '90',
708  'Iranian calendar short year'
709  ],
710  [
711  'o',
712  '20120101235000',
713  '2011',
714  '2011',
715  'ISO 8601 (week) year'
716  ],
717  [
718  'W',
719  '20120101235000',
720  '52',
721  '52',
722  'Week number'
723  ],
724  [
725  'W',
726  '20120102235000',
727  '1',
728  '1',
729  'Week number'
730  ],
731  [
732  'o-\\WW-N',
733  '20091231235000',
734  '2009-W53-4',
735  '2009-W53-4',
736  'leap week'
737  ],
738  // What follows is mostly copied from
739  // https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions#.23time
740  [
741  'Y',
742  '20120102090705',
743  '2012',
744  '2012',
745  'Full year'
746  ],
747  [
748  'y',
749  '20120102090705',
750  '12',
751  '12',
752  '2 digit year'
753  ],
754  [
755  'L',
756  '20120102090705',
757  '1',
758  '1',
759  'Leap year'
760  ],
761  [
762  'n',
763  '20120102090705',
764  '1',
765  '1',
766  'Month index, not zero pad'
767  ],
768  [
769  'N',
770  '20120102090705',
771  '01',
772  '01',
773  'Month index. Zero pad'
774  ],
775  [
776  'M',
777  '20120102090705',
778  'Jan',
779  'Jan',
780  'Month abbrev'
781  ],
782  [
783  'F',
784  '20120102090705',
785  'January',
786  'January',
787  'Full month'
788  ],
789  [
790  'xg',
791  '20120102090705',
792  'January',
793  'January',
794  'Genitive month name (same in EN)'
795  ],
796  [
797  'j',
798  '20120102090705',
799  '2',
800  '2',
801  'Day of month (not zero pad)'
802  ],
803  [
804  'd',
805  '20120102090705',
806  '02',
807  '02',
808  'Day of month (zero-pad)'
809  ],
810  [
811  'z',
812  '20120102090705',
813  '1',
814  '1',
815  'Day of year (zero-indexed)'
816  ],
817  [
818  'D',
819  '20120102090705',
820  'Mon',
821  'Mon',
822  'Day of week (abbrev)'
823  ],
824  [
825  'l',
826  '20120102090705',
827  'Monday',
828  'Monday',
829  'Full day of week'
830  ],
831  [
832  'N',
833  '20120101090705',
834  '7',
835  '7',
836  'Day of week (Mon=1, Sun=7)'
837  ],
838  [
839  'w',
840  '20120101090705',
841  '0',
842  '0',
843  'Day of week (Sun=0, Sat=6)'
844  ],
845  [
846  'N',
847  '20120102090705',
848  '1',
849  '1',
850  'Day of week'
851  ],
852  [
853  'a',
854  '20120102090705',
855  'am',
856  'am',
857  'am vs pm'
858  ],
859  [
860  'A',
861  '20120102120000',
862  'PM',
863  'PM',
864  'AM vs PM'
865  ],
866  [
867  'a',
868  '20120102000000',
869  'am',
870  'am',
871  'AM vs PM'
872  ],
873  [
874  'g',
875  '20120102090705',
876  '9',
877  '9',
878  '12 hour, not Zero'
879  ],
880  [
881  'h',
882  '20120102090705',
883  '09',
884  '09',
885  '12 hour, zero padded'
886  ],
887  [
888  'G',
889  '20120102090705',
890  '9',
891  '9',
892  '24 hour, not zero'
893  ],
894  [
895  'H',
896  '20120102090705',
897  '09',
898  '09',
899  '24 hour, zero'
900  ],
901  [
902  'H',
903  '20120102110705',
904  '11',
905  '11',
906  '24 hour, zero'
907  ],
908  [
909  'i',
910  '20120102090705',
911  '07',
912  '07',
913  'Minutes'
914  ],
915  [
916  's',
917  '20120102090705',
918  '05',
919  '05',
920  'seconds'
921  ],
922  [
923  'U',
924  '20120102090705',
925  '1325495225',
926  '1325462825',
927  'unix time'
928  ],
929  [
930  't',
931  '20120102090705',
932  '31',
933  '31',
934  'Days in current month'
935  ],
936  [
937  'c',
938  '20120102090705',
939  '2012-01-02T09:07:05+00:00',
940  '2012-01-02T09:07:05+09:00',
941  'ISO 8601 timestamp'
942  ],
943  [
944  'r',
945  '20120102090705',
946  'Mon, 02 Jan 2012 09:07:05 +0000',
947  'Mon, 02 Jan 2012 09:07:05 +0900',
948  'RFC 5322'
949  ],
950  [
951  'e',
952  '20120102090705',
953  'UTC',
954  'Asia/Seoul',
955  'Timezone identifier'
956  ],
957  [
958  'I',
959  '19880602090705',
960  '0',
961  '1',
962  'DST indicator'
963  ],
964  [
965  'O',
966  '20120102090705',
967  '+0000',
968  '+0900',
969  'Timezone offset'
970  ],
971  [
972  'P',
973  '20120102090705',
974  '+00:00',
975  '+09:00',
976  'Timezone offset with colon'
977  ],
978  [
979  'T',
980  '20120102090705',
981  'UTC',
982  'KST',
983  'Timezone abbreviation'
984  ],
985  [
986  'Z',
987  '20120102090705',
988  '0',
989  '32400',
990  'Timezone offset in seconds'
991  ],
992  [
993  'xmj xmF xmn xmY',
994  '20120102090705',
995  '7 Safar 2 1433',
996  '7 Safar 2 1433',
997  'Islamic'
998  ],
999  [
1000  'xij xiF xin xiY',
1001  '20120102090705',
1002  '12 Dey 10 1390',
1003  '12 Dey 10 1390',
1004  'Iranian'
1005  ],
1006  [
1007  'xjj xjF xjn xjY',
1008  '20120102090705',
1009  '7 Tevet 4 5772',
1010  '7 Tevet 4 5772',
1011  'Hebrew'
1012  ],
1013  [
1014  'xjt',
1015  '20120102090705',
1016  '29',
1017  '29',
1018  'Hebrew number of days in month'
1019  ],
1020  [
1021  'xjx',
1022  '20120102090705',
1023  'Tevet',
1024  'Tevet',
1025  'Hebrew genitive month name (No difference in EN)'
1026  ],
1027  [
1028  'xkY',
1029  '20120102090705',
1030  '2555',
1031  '2555',
1032  'Thai year'
1033  ],
1034  [
1035  'xkY',
1036  '19410101090705',
1037  '2484',
1038  '2484',
1039  'Thai year'
1040  ],
1041  [
1042  'xoY',
1043  '20120102090705',
1044  '101',
1045  '101',
1046  'Minguo'
1047  ],
1048  [
1049  'xtY',
1050  '20120102090705',
1051  '平成24',
1052  '平成24',
1053  'nengo'
1054  ],
1055  [
1056  'xtY',
1057  '20190430235959',
1058  '平成31',
1059  '平成31',
1060  'nengo - last day of heisei'
1061  ],
1062  [
1063  'xtY',
1064  '20190501000000',
1065  '令和元',
1066  '令和元',
1067  'nengo - first day of reiwa'
1068  ],
1069  [
1070  'xtY',
1071  '20200501000000',
1072  '令和2',
1073  '令和2',
1074  'nengo - second year of reiwa'
1075  ],
1076  [
1077  'xrxkYY',
1078  '20120102090705',
1079  'MMDLV2012',
1080  'MMDLV2012',
1081  'Roman numerals'
1082  ],
1083  [
1084  'xhxjYY',
1085  '20120102090705',
1086  'ה\'תשע"ב2012',
1087  'ה\'תשע"ב2012',
1088  'Hebrew numberals'
1089  ],
1090  [
1091  'xnY',
1092  '20120102090705',
1093  '2012',
1094  '2012',
1095  'Raw numerals (doesn\'t mean much in EN)'
1096  ],
1097  [
1098  '[[Y "(yea"\\r)]] \\"xx\\"',
1099  '20120102090705',
1100  '[[2012 (year)]] "x"',
1101  '[[2012 (year)]] "x"',
1102  'Various escaping'
1103  ],
1104 
1105  ];
1106  }
1107 
1112  public function testFormatSize( $size, $expected, $msg ) {
1113  $this->assertEquals(
1114  $expected,
1115  $this->getLang()->formatSize( $size ),
1116  "formatSize('$size'): $msg"
1117  );
1118  }
1119 
1120  public static function provideFormatSizes() {
1121  return [
1122  [
1123  0,
1124  "0 bytes",
1125  "Zero bytes"
1126  ],
1127  [
1128  1024,
1129  "1 KB",
1130  "1 kilobyte"
1131  ],
1132  [
1133  1024 * 1024,
1134  "1 MB",
1135  "1,024 megabytes"
1136  ],
1137  [
1138  1024 * 1024 * 1024,
1139  "1 GB",
1140  "1 gigabyte"
1141  ],
1142  [
1143  1024 ** 4,
1144  "1 TB",
1145  "1 terabyte"
1146  ],
1147  [
1148  1024 ** 5,
1149  "1 PB",
1150  "1 petabyte"
1151  ],
1152  [
1153  1024 ** 6,
1154  "1 EB",
1155  "1,024 exabyte"
1156  ],
1157  [
1158  1024 ** 7,
1159  "1 ZB",
1160  "1 zetabyte"
1161  ],
1162  [
1163  1024 ** 8,
1164  "1 YB",
1165  "1 yottabyte"
1166  ],
1167  // How big!? THIS BIG!
1168  ];
1169  }
1170 
1175  public function testFormatBitrate( $bps, $expected, $msg ) {
1176  $this->assertEquals(
1177  $expected,
1178  $this->getLang()->formatBitrate( $bps ),
1179  "formatBitrate('$bps'): $msg"
1180  );
1181  }
1182 
1183  public static function provideFormatBitrate() {
1184  return [
1185  [
1186  0,
1187  "0 bps",
1188  "0 bits per second"
1189  ],
1190  [
1191  999,
1192  "999 bps",
1193  "999 bits per second"
1194  ],
1195  [
1196  1000,
1197  "1 kbps",
1198  "1 kilobit per second"
1199  ],
1200  [
1201  1000 * 1000,
1202  "1 Mbps",
1203  "1 megabit per second"
1204  ],
1205  [
1206  10 ** 9,
1207  "1 Gbps",
1208  "1 gigabit per second"
1209  ],
1210  [
1211  10 ** 12,
1212  "1 Tbps",
1213  "1 terabit per second"
1214  ],
1215  [
1216  10 ** 15,
1217  "1 Pbps",
1218  "1 petabit per second"
1219  ],
1220  [
1221  10 ** 18,
1222  "1 Ebps",
1223  "1 exabit per second"
1224  ],
1225  [
1226  10 ** 21,
1227  "1 Zbps",
1228  "1 zetabit per second"
1229  ],
1230  [
1231  10 ** 24,
1232  "1 Ybps",
1233  "1 yottabit per second"
1234  ],
1235  [
1236  10 ** 27,
1237  "1,000 Ybps",
1238  "1,000 yottabits per second"
1239  ],
1240  ];
1241  }
1242 
1247  public function testFormatDuration( $duration, $expected, $intervals = [] ) {
1248  $this->assertEquals(
1249  $expected,
1250  $this->getLang()->formatDuration( $duration, $intervals ),
1251  "formatDuration('$duration'): $expected"
1252  );
1253  }
1254 
1255  public static function provideFormatDuration() {
1256  return [
1257  [
1258  0,
1259  '0 seconds',
1260  ],
1261  [
1262  1,
1263  '1 second',
1264  ],
1265  [
1266  2,
1267  '2 seconds',
1268  ],
1269  [
1270  60,
1271  '1 minute',
1272  ],
1273  [
1274  2 * 60,
1275  '2 minutes',
1276  ],
1277  [
1278  3600,
1279  '1 hour',
1280  ],
1281  [
1282  2 * 3600,
1283  '2 hours',
1284  ],
1285  [
1286  24 * 3600,
1287  '1 day',
1288  ],
1289  [
1290  2 * 86400,
1291  '2 days',
1292  ],
1293  [
1294  // ( 365 + ( 24 * 3 + 25 ) / 400 ) * 86400 = 31556952
1295  ( 365 + ( 24 * 3 + 25 ) / 400.0 ) * 86400,
1296  '1 year',
1297  ],
1298  [
1299  2 * 31556952,
1300  '2 years',
1301  ],
1302  [
1303  10 * 31556952,
1304  '1 decade',
1305  ],
1306  [
1307  20 * 31556952,
1308  '2 decades',
1309  ],
1310  [
1311  100 * 31556952,
1312  '1 century',
1313  ],
1314  [
1315  200 * 31556952,
1316  '2 centuries',
1317  ],
1318  [
1319  1000 * 31556952,
1320  '1 millennium',
1321  ],
1322  [
1323  2000 * 31556952,
1324  '2 millennia',
1325  ],
1326  [
1327  9001,
1328  '2 hours, 30 minutes and 1 second'
1329  ],
1330  [
1331  3601,
1332  '1 hour and 1 second'
1333  ],
1334  [
1335  31556952 + 2 * 86400 + 9000,
1336  '1 year, 2 days, 2 hours and 30 minutes'
1337  ],
1338  [
1339  42 * 1000 * 31556952 + 42,
1340  '42 millennia and 42 seconds'
1341  ],
1342  [
1343  60,
1344  '60 seconds',
1345  [ 'seconds' ],
1346  ],
1347  [
1348  61,
1349  '61 seconds',
1350  [ 'seconds' ],
1351  ],
1352  [
1353  1,
1354  '1 second',
1355  [ 'seconds' ],
1356  ],
1357  [
1358  31556952 + 2 * 86400 + 9000,
1359  '1 year, 2 days and 150 minutes',
1360  [ 'years', 'days', 'minutes' ],
1361  ],
1362  [
1363  42,
1364  '0 days',
1365  [ 'years', 'days' ],
1366  ],
1367  [
1368  31556952 + 2 * 86400 + 9000,
1369  '1 year, 2 days and 150 minutes',
1370  [ 'minutes', 'days', 'years' ],
1371  ],
1372  [
1373  42,
1374  '0 days',
1375  [ 'days', 'years' ],
1376  ],
1377  ];
1378  }
1379 
1384  public function testCheckTitleEncoding( $s ) {
1385  $this->assertEquals(
1386  $s,
1387  $this->getLang()->checkTitleEncoding( $s ),
1388  "checkTitleEncoding('$s')"
1389  );
1390  }
1391 
1392  public static function provideCheckTitleEncodingData() {
1393  // phpcs:disable Generic.Files.LineLength
1394  return [
1395  [ "" ],
1396  [ "United States of America" ], // 7bit ASCII
1397  [ rawurldecode( "S%C3%A9rie%20t%C3%A9l%C3%A9vis%C3%A9e" ) ],
1398  [
1399  rawurldecode(
1400  "Acteur%7CAlbert%20Robbins%7CAnglais%7CAnn%20Donahue%7CAnthony%20E.%20Zuiker%7CCarol%20Mendelsohn"
1401  )
1402  ],
1403  // The following two data sets come from T38839. They fail if checkTitleEncoding uses a regexp to test for
1404  // valid UTF-8 encoding and the pcre.recursion_limit is low (like, say, 1024). They succeed if checkTitleEncoding
1405  // uses mb_check_encoding for its test.
1406  [
1407  rawurldecode(
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"
1422  ),
1423  ],
1424  [
1425  rawurldecode(
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"
1441  )
1442  ]
1443  ];
1444  // phpcs:enable
1445  }
1446 
1451  public function testRomanNumerals( $num, $numerals ) {
1452  $this->assertEquals(
1453  $numerals,
1454  Language::romanNumeral( $num ),
1455  "romanNumeral('$num')"
1456  );
1457  }
1458 
1459  public static function provideRomanNumeralsData() {
1460  return [
1461  [ 1, 'I' ],
1462  [ 2, 'II' ],
1463  [ 3, 'III' ],
1464  [ 4, 'IV' ],
1465  [ 5, 'V' ],
1466  [ 6, 'VI' ],
1467  [ 7, 'VII' ],
1468  [ 8, 'VIII' ],
1469  [ 9, 'IX' ],
1470  [ 10, 'X' ],
1471  [ 20, 'XX' ],
1472  [ 30, 'XXX' ],
1473  [ 40, 'XL' ],
1474  [ 49, 'XLIX' ],
1475  [ 50, 'L' ],
1476  [ 60, 'LX' ],
1477  [ 70, 'LXX' ],
1478  [ 80, 'LXXX' ],
1479  [ 90, 'XC' ],
1480  [ 99, 'XCIX' ],
1481  [ 100, 'C' ],
1482  [ 200, 'CC' ],
1483  [ 300, 'CCC' ],
1484  [ 400, 'CD' ],
1485  [ 500, 'D' ],
1486  [ 600, 'DC' ],
1487  [ 700, 'DCC' ],
1488  [ 800, 'DCCC' ],
1489  [ 900, 'CM' ],
1490  [ 999, 'CMXCIX' ],
1491  [ 1000, 'M' ],
1492  [ 1989, 'MCMLXXXIX' ],
1493  [ 2000, 'MM' ],
1494  [ 3000, 'MMM' ],
1495  [ 4000, 'MMMM' ],
1496  [ 5000, 'MMMMM' ],
1497  [ 6000, 'MMMMMM' ],
1498  [ 7000, 'MMMMMMM' ],
1499  [ 8000, 'MMMMMMMM' ],
1500  [ 9000, 'MMMMMMMMM' ],
1501  [ 9999, 'MMMMMMMMMCMXCIX' ],
1502  [ 10000, 'MMMMMMMMMM' ],
1503  ];
1504  }
1505 
1510  public function testHebrewNumeral( $num, $numerals ) {
1511  $this->assertEquals(
1512  $numerals,
1513  Language::hebrewNumeral( $num ),
1514  "hebrewNumeral('$num')"
1515  );
1516  }
1517 
1518  public static function provideHebrewNumeralsData() {
1519  return [
1520  [ -1, -1 ],
1521  [ 0, 0 ],
1522  [ 1, "א'" ],
1523  [ 2, "ב'" ],
1524  [ 3, "ג'" ],
1525  [ 4, "ד'" ],
1526  [ 5, "ה'" ],
1527  [ 6, "ו'" ],
1528  [ 7, "ז'" ],
1529  [ 8, "ח'" ],
1530  [ 9, "ט'" ],
1531  [ 10, "י'" ],
1532  [ 11, 'י"א' ],
1533  [ 14, 'י"ד' ],
1534  [ 15, 'ט"ו' ],
1535  [ 16, 'ט"ז' ],
1536  [ 17, 'י"ז' ],
1537  [ 20, "כ'" ],
1538  [ 21, 'כ"א' ],
1539  [ 30, "ל'" ],
1540  [ 40, "מ'" ],
1541  [ 50, "נ'" ],
1542  [ 60, "ס'" ],
1543  [ 70, "ע'" ],
1544  [ 80, "פ'" ],
1545  [ 90, "צ'" ],
1546  [ 99, 'צ"ט' ],
1547  [ 100, "ק'" ],
1548  [ 101, 'ק"א' ],
1549  [ 110, 'ק"י' ],
1550  [ 200, "ר'" ],
1551  [ 300, "ש'" ],
1552  [ 400, "ת'" ],
1553  [ 500, 'ת"ק' ],
1554  [ 800, 'ת"ת' ],
1555  [ 1000, "א' אלף" ],
1556  [ 1001, "א'א'" ],
1557  [ 1012, "א'י\"ב" ],
1558  [ 1020, "א'ך'" ],
1559  [ 1030, "א'ל'" ],
1560  [ 1081, "א'פ\"א" ],
1561  [ 2000, "ב' אלפים" ],
1562  [ 2016, "ב'ט\"ז" ],
1563  [ 3000, "ג' אלפים" ],
1564  [ 4000, "ד' אלפים" ],
1565  [ 4904, "ד'תתק\"ד" ],
1566  [ 5000, "ה' אלפים" ],
1567  [ 5680, "ה'תר\"ף" ],
1568  [ 5690, "ה'תר\"ץ" ],
1569  [ 5708, "ה'תש\"ח" ],
1570  [ 5720, "ה'תש\"ך" ],
1571  [ 5740, "ה'תש\"ם" ],
1572  [ 5750, "ה'תש\"ן" ],
1573  [ 5775, "ה'תשע\"ה" ],
1574  ];
1575  }
1576 
1581  public function testConvertPlural( $expected, $number, $forms ) {
1582  $chosen = $this->getLang()->convertPlural( $number, $forms );
1583  $this->assertEquals( $expected, $chosen );
1584  }
1585 
1586  public static function providePluralData() {
1587  // Params are: [expected text, number given, [the plural forms]]
1588  return [
1589  [ 'plural', 0, [
1590  'singular', 'plural'
1591  ] ],
1592  [ 'explicit zero', 0, [
1593  '0=explicit zero', 'singular', 'plural'
1594  ] ],
1595  [ 'explicit one', 1, [
1596  'singular', 'plural', '1=explicit one',
1597  ] ],
1598  [ 'singular', 1, [
1599  'singular', 'plural', '0=explicit zero',
1600  ] ],
1601  [ 'plural', 3, [
1602  '0=explicit zero', '1=explicit one', 'singular', 'plural'
1603  ] ],
1604  [ 'explicit eleven', 11, [
1605  'singular', 'plural', '11=explicit eleven',
1606  ] ],
1607  [ 'plural', 12, [
1608  'singular', 'plural', '11=explicit twelve',
1609  ] ],
1610  [ 'plural', 12, [
1611  'singular', 'plural', '=explicit form',
1612  ] ],
1613  [ 'other', 2, [
1614  'kissa=kala', '1=2=3', 'other',
1615  ] ],
1616  [ '', 2, [
1617  '0=explicit zero', '1=explicit one',
1618  ] ],
1619  ];
1620  }
1621 
1625  public function testEmbedBidi() {
1626  $lre = "\u{202A}"; // U+202A LEFT-TO-RIGHT EMBEDDING
1627  $rle = "\u{202B}"; // U+202B RIGHT-TO-LEFT EMBEDDING
1628  $pdf = "\u{202C}"; // U+202C POP DIRECTIONAL FORMATTING
1629  $lang = $this->getLang();
1630  $this->assertEquals(
1631  '123',
1632  $lang->embedBidi( '123' ),
1633  'embedBidi with neutral argument'
1634  );
1635  $this->assertEquals(
1636  $lre . 'Ben_(WMF)' . $pdf,
1637  $lang->embedBidi( 'Ben_(WMF)' ),
1638  'embedBidi with LTR argument'
1639  );
1640  $this->assertEquals(
1641  $rle . 'יהודי (מנוחין)' . $pdf,
1642  $lang->embedBidi( 'יהודי (מנוחין)' ),
1643  'embedBidi with RTL argument'
1644  );
1645  }
1646 
1651  public function testTranslateBlockExpiry( $expectedData, $str, $now, $desc ) {
1652  $lang = $this->getLang();
1653  if ( is_array( $expectedData ) ) {
1654  list( $func, $arg ) = $expectedData;
1655  $expected = $lang->$func( $arg );
1656  } else {
1657  $expected = $expectedData;
1658  }
1659  $this->assertEquals( $expected, $lang->translateBlockExpiry( $str, null, $now ), $desc );
1660  }
1661 
1662  public static function provideTranslateBlockExpiry() {
1663  return [
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' ],
1670  [
1671  [ 'formatDuration', 1023 * 60 * 60 ],
1672  '1023 hours',
1673  wfTimestamp( TS_UNIX, '19910203040506' ),
1674  'relative with initial timestamp'
1675  ],
1676  [ [ 'formatDuration', 0 ], 'now', 0, 'now' ],
1677  [
1678  [ 'timeanddate', '20120102070000' ],
1679  '2012-1-1 7:00 +1 day',
1680  0,
1681  'mixed, handled as absolute'
1682  ],
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' ],
1686  [
1687  [ 'timeanddate', '19910910000000' ],
1688  '10 september',
1689  wfTimestamp( TS_UNIX, '19910203040506' ),
1690  'partial'
1691  ],
1692  [ 'dummy', 'dummy', 0, 'return garbage as is' ],
1693  ];
1694  }
1695 
1700  public function testFormatNum(
1701  $translateNumerals, $langCode, $number, $nocommafy, $expected
1702  ) {
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 );
1708  }
1709 
1710  public function provideFormatNum() {
1711  return [
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' ],
1720  ];
1721  }
1722 
1727  public function testParseFormattedNumber( $langCode, $number ) {
1728  $lang = Language::factory( $langCode );
1729 
1730  $localisedNum = $lang->formatNum( $number );
1731  $normalisedNum = $lang->parseFormattedNumber( $localisedNum );
1732 
1733  $this->assertEquals( $number, $normalisedNum );
1734  }
1735 
1736  public function parseFormattedNumberProvider() {
1737  return [
1738  [ 'de', 377.01 ],
1739  [ 'fa', 334 ],
1740  [ 'fa', 382.772 ],
1741  [ 'ar', 1844 ],
1742  [ 'lzh', 3731 ],
1743  [ 'zh-classical', 7432 ]
1744  ];
1745  }
1746 
1751  public function testCommafy( $number, $numbersWithCommas ) {
1752  $this->assertEquals(
1753  $numbersWithCommas,
1754  $this->getLang()->commafy( $number ),
1755  "commafy('$number')"
1756  );
1757  }
1758 
1759  public static function provideCommafyData() {
1760  return [
1761  [ -1, '-1' ],
1762  [ 10, '10' ],
1763  [ 100, '100' ],
1764  [ 1000, '1,000' ],
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' ],
1778  ];
1779  }
1780 
1784  public function testListToText() {
1785  $lang = $this->getLang();
1786  $and = $lang->getMessageFromDB( 'and' );
1787  $s = $lang->getMessageFromDB( 'word-separator' );
1788  $c = $lang->getMessageFromDB( 'comma-separator' );
1789 
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' ] ) );
1795  }
1796 
1800  public function testClearCaches() {
1801  $languageClass = TestingAccessWrapper::newFromClass( Language::class );
1802 
1803  // Populate $dataCache
1804  Language::getLocalisationCache()->getItem( 'zh', 'mainpage' );
1805  $oldCacheObj = Language::$dataCache;
1806  $this->assertNotCount( 0,
1807  TestingAccessWrapper::newFromObject( Language::$dataCache )->loadedItems );
1808 
1809  // Populate $mLangObjCache
1810  $lang = Language::factory( 'en' );
1811  $this->assertNotCount( 0, Language::$mLangObjCache );
1812 
1813  // Populate $fallbackLanguageCache
1815  $this->assertNotCount( 0, $languageClass->fallbackLanguageCache );
1816 
1817  // Populate $grammarTransformations
1818  $lang->getGrammarTransformations();
1819  $this->assertNotNull( $languageClass->grammarTransformations );
1820 
1821  // Populate $languageNameCache
1823  $this->assertNotNull( $languageClass->languageNameCache );
1824 
1826 
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 );
1834  }
1835 
1840  public function testIsSupportedLanguage( $code, $expected, $comment ) {
1841  $this->assertEquals( $expected, Language::isSupportedLanguage( $code ), $comment );
1842  }
1843 
1844  public static function provideIsSupportedLanguage() {
1845  return [
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' ],
1850  ];
1851  }
1852 
1857  public function testGetParentLanguage( $code, $expected, $comment ) {
1859  if ( is_null( $expected ) ) {
1860  $this->assertNull( $lang->getParentLanguage(), $comment );
1861  } else {
1862  $this->assertEquals( $expected, $lang->getParentLanguage()->getCode(), $comment );
1863  }
1864  }
1865 
1866  public static function provideGetParentLanguage() {
1867  return [
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' ],
1874  ];
1875  }
1876 
1881  public function testGetNamespaceAliases( $languageCode, $subset ) {
1882  $language = Language::factory( $languageCode );
1883  $aliases = $language->getNamespaceAliases();
1884  foreach ( $subset as $alias => $nsId ) {
1885  $this->assertEquals( $nsId, $aliases[$alias] );
1886  }
1887  }
1888 
1889  public static function provideGetNamespaceAliases() {
1890  // TODO: Add tests for NS_PROJECT_TALK and GenderNamespaces
1891  return [
1892  [
1893  'zh',
1894  [
1895  '文件' => NS_FILE,
1896  '檔案' => NS_FILE,
1897  ],
1898  ],
1899  ];
1900  }
1901 
1905  public function testHasVariant() {
1906  // See LanguageSrTest::testHasVariant() for additional tests
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' );
1910 
1911  $bogus = Language::factory( 'bogus' );
1912  $this->assertTrue( $bogus->hasVariant( 'bogus' ), 'base is always a variant' );
1913  }
1914 
1918  public function testEquals() {
1919  $en1 = Language::factory( 'en' );
1920  $en2 = Language::factory( 'en' );
1921  $en3 = new Language();
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' );
1925 
1926  $fr = Language::factory( 'fr' );
1927  $this->assertFalse( $en1->equals( $fr ), 'en not equals fr' );
1928 
1929  $ar1 = Language::factory( 'ar' );
1930  $ar2 = new LanguageAr();
1931  $this->assertTrue( $ar1->equals( $ar2 ), 'ar equals ar' );
1932  }
1933 }
LanguageTest\testLanguageConvertDoubleWidthToSingleWidth
testLanguageConvertDoubleWidthToSingleWidth()
Language::convertDoubleWidth Language::normalizeForSearch.
Definition: LanguageTest.php:10
LanguageTest\provideCheckTitleEncodingData
static provideCheckTitleEncodingData()
Definition: LanguageTest.php:1392
LanguageTest\testMalformedLanguageTag
testMalformedLanguageTag( $code, $message='')
Negative test for Language::isWellFormedLanguageTag() provideMalformedLanguageTags Language::isWellFo...
Definition: LanguageTest.php:440
LanguageClassesTestCase
Helping class to run tests using a clean language instance.
Definition: LanguageClassesTestCase.php:21
LanguageTest
Definition: LanguageTest.php:5
Language\clearCaches
static clearCaches()
Intended for tests that may change configuration in a way that invalidates caches.
Definition: Language.php:284
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
LanguageClassesTestCase\getLang
getLang()
Definition: LanguageClassesTestCase.php:41
LanguageTest\testFormatTimePeriod
testFormatTimePeriod( $seconds, $format, $expected, $desc)
provideFormattableTimes Language::formatTimePeriod
Definition: LanguageTest.php:24
LanguageTest\testBuiltInCodeValidation
testBuiltInCodeValidation( $code, $expected, $message='')
Test Language::isValidBuiltInCode() provideLanguageCodes Language::isValidBuiltInCode.
Definition: LanguageTest.php:506
LanguageTest\provideWellFormedLanguageTags
static provideWellFormedLanguageTags()
The test cases are based on the tests in the GaBuZoMeu parser written by Stéphane Bortzmeyer bortzmey...
Definition: LanguageTest.php:401
LanguageTest\testSprintfDateNoTtlIfNotNeeded
testSprintfDateNoTtlIfNotNeeded()
sprintfDate should only calculate a TTL if the caller is going to use it.
Definition: LanguageTest.php:680
LanguageTest\testKnownCldrLanguageTag
testKnownCldrLanguageTag()
Language::isKnownLanguageTag.
Definition: LanguageTest.php:547
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1912
LanguageTest\provideCommafyData
static provideCommafyData()
Definition: LanguageTest.php:1759
LanguageTest\testUnknownLanguageTag
testUnknownLanguageTag( $code, $message='')
Negative tests for Language::isKnownLanguageTag() provideUnKnownLanguageTags Language::isKnownLanguag...
Definition: LanguageTest.php:565
LanguageTest\testFormatSize
testFormatSize( $size, $expected, $msg)
provideFormatSizes Language::formatSize
Definition: LanguageTest.php:1112
LanguageTest\testGetNamespaceAliases
testGetNamespaceAliases( $languageCode, $subset)
provideGetNamespaceAliases Language::getNamespaceAliases
Definition: LanguageTest.php:1881
LanguageTest\testTruncateForDatabase
testTruncateForDatabase()
Language::truncateForDatabase Language::truncateInternal.
Definition: LanguageTest.php:217
LanguageTest\testCheckTitleEncoding
testCheckTitleEncoding( $s)
provideCheckTitleEncodingData Language::checkTitleEncoding
Definition: LanguageTest.php:1384
NS_FILE
const NS_FILE
Definition: Defines.php:70
LanguageTest\providePluralData
static providePluralData()
Definition: LanguageTest.php:1586
$s
$s
Definition: mergeMessageFileList.php:186
LanguageTest\testSprintfDate
testSprintfDate( $format, $ts, $expected, $msg)
provideSprintfDateSamples Language::sprintfDate
Definition: LanguageTest.php:610
$res
$res
Definition: database.txt:21
LanguageTest\provideMalformedLanguageTags
static provideMalformedLanguageTags()
The test cases are based on the tests in the GaBuZoMeu parser written by Stéphane Bortzmeyer bortzmey...
Definition: LanguageTest.php:453
LanguageTest\testFormatBitrate
testFormatBitrate( $bps, $expected, $msg)
provideFormatBitrate Language::formatBitrate
Definition: LanguageTest.php:1175
LanguageTest\testEquals
testEquals()
Language::equals.
Definition: LanguageTest.php:1918
LanguageTest\provideHTMLTruncateData
static provideHTMLTruncateData()
Definition: LanguageTest.php:327
php
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
Definition: injection.txt:35
Language\isWellFormedLanguageTag
static isWellFormedLanguageTag( $code, $lenient=false)
Returns true if a language code string is a well-formed language tag according to RFC 5646.
Definition: Language.php:333
LanguageTest\provideFormatDuration
static provideFormatDuration()
Definition: LanguageTest.php:1255
LanguageTest\testSprintfDateNoZone
testSprintfDateNoZone( $format, $ts, $expected, $ignore, $msg)
sprintfDate should always use UTC when no zone is given.
Definition: LanguageTest.php:642
Language\isKnownLanguageTag
static isKnownLanguageTag( $tag)
Returns true if a language code is an IETF tag known to MediaWiki.
Definition: Language.php:426
LanguageTest\provideHebrewNumeralsData
static provideHebrewNumeralsData()
Definition: LanguageTest.php:1518
LanguageTest\testSprintfDateTooLongTimestamp
testSprintfDateTooLongTimestamp()
Test too long timestamp MWException Language::sprintfDate.
Definition: LanguageTest.php:593
Language\getLocalisationCache
static getLocalisationCache()
Get the LocalisationCache instance.
Definition: Language.php:447
LanguageTest\testParseFormattedNumber
testParseFormattedNumber( $langCode, $number)
Language::parseFormattedNumber parseFormattedNumberProvider.
Definition: LanguageTest.php:1727
LanguageTest\testKnownLanguageTag
testKnownLanguageTag( $code, $message='')
Test Language::isKnownLanguageTag() provideKnownLanguageTags Language::isKnownLanguageTag.
Definition: LanguageTest.php:529
LanguageTest\testLenientLanguageTag
testLenientLanguageTag()
Negative test for Language::isWellFormedLanguageTag() Language::isWellFormedLanguageTag.
Definition: LanguageTest.php:494
LanguageTest\testHebrewNumeral
testHebrewNumeral( $num, $numerals)
provideHebrewNumeralsData Language::hebrewNumeral
Definition: LanguageTest.php:1510
$input
if(is_array( $mode)) switch( $mode) $input
Definition: postprocess-phan.php:141
LanguageTest\testListToText
testListToText()
Language::listToText.
Definition: LanguageTest.php:1784
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Sets a global, maintaining a stashed version of the previous global to be restored in tearDown.
Definition: MediaWikiTestCase.php:709
LanguageTest\testRomanNumerals
testRomanNumerals( $num, $numerals)
provideRomanNumeralsData Language::romanNumeral
Definition: LanguageTest.php:1451
LanguageTest\testHasVariant
testHasVariant()
Language::hasVariant.
Definition: LanguageTest.php:1905
LanguageTest\parseFormattedNumberProvider
parseFormattedNumberProvider()
Definition: LanguageTest.php:1736
LanguageTest\testClearCaches
testClearCaches()
Language::clearCaches.
Definition: LanguageTest.php:1800
LanguageTest\provideTruncateData
static provideTruncateData()
Definition: LanguageTest.php:296
LanguageTest\testFormatNum
testFormatNum( $translateNumerals, $langCode, $number, $nocommafy, $expected)
provideFormatNum Language::formatNum
Definition: LanguageTest.php:1700
LanguageTest\testFormatDuration
testFormatDuration( $duration, $expected, $intervals=[])
provideFormatDuration Language::formatDuration
Definition: LanguageTest.php:1247
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
$code
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
Definition: hooks.txt:780
LanguageTest\provideKnownLanguageTags
static provideKnownLanguageTags()
Definition: LanguageTest.php:536
LanguageTest\provideTranslateBlockExpiry
static provideTranslateBlockExpiry()
Definition: LanguageTest.php:1662
LanguageTest\provideGetNamespaceAliases
static provideGetNamespaceAliases()
Definition: LanguageTest.php:1889
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1941
LanguageTest\provideIsSupportedLanguage
static provideIsSupportedLanguage()
Definition: LanguageTest.php:1844
list
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
Definition: deferred.txt:11
LanguageTest\provideSprintfDateSamples
static provideSprintfDateSamples()
Definition: LanguageTest.php:694
LanguageTest\testGetParentLanguage
testGetParentLanguage( $code, $expected, $comment)
provideGetParentLanguage Language::getParentLanguage
Definition: LanguageTest.php:1857
Language\isValidBuiltInCode
static isValidBuiltInCode( $code)
Returns true if a language code is of a valid form for the purposes of internal customisation of Medi...
Definition: Language.php:412
LanguageAr
Arabic (العربية)
Definition: LanguageAr.php:30
Language\hebrewNumeral
static hebrewNumeral( $num)
Hebrew Gematria number formatting up to 9999.
Definition: Language.php:2069
LanguageTest\testConvertPlural
testConvertPlural( $expected, $number, $forms)
providePluralData Language::convertPlural
Definition: LanguageTest.php:1581
LanguageTest\testTranslateBlockExpiry
testTranslateBlockExpiry( $expectedData, $str, $now, $desc)
Language::translateBlockExpiry() provideTranslateBlockExpiry.
Definition: LanguageTest.php:1651
LanguageTest\testCommafy
testCommafy( $number, $numbersWithCommas)
Language::commafy() provideCommafyData.
Definition: LanguageTest.php:1751
LanguageTest\provideFormattableTimes
static provideFormattableTimes()
Definition: LanguageTest.php:28
LanguageTest\testTruncateForVisual
testTruncateForVisual( $expected, $string, $length, $ellipsis='...', $adjustLength=true)
provideTruncateData Language::truncateForVisual Language::truncateInternal
Definition: LanguageTest.php:284
LanguageTest\provideFormatSizes
static provideFormatSizes()
Definition: LanguageTest.php:1120
LanguageTest\testSprintfDateNotAllDigitTimestamp
testSprintfDateNotAllDigitTimestamp()
Test too short timestamp MWException Language::sprintfDate.
Definition: LanguageTest.php:602
Language\$mLangObjCache
static $mLangObjCache
Definition: Language.php:82
LanguageTest\provideFormatBitrate
static provideFormatBitrate()
Definition: LanguageTest.php:1183
Language\getFallbacksIncludingSiteLanguage
static getFallbacksIncludingSiteLanguage( $code)
Get the ordered list of fallback languages, ending with the fallback language chain for the site lang...
Definition: Language.php:4556
as
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
Definition: distributors.txt:9
LanguageTest\provideRomanNumeralsData
static provideRomanNumeralsData()
Definition: LanguageTest.php:1459
LanguageTest\provideLanguageCodes
static provideLanguageCodes()
Definition: LanguageTest.php:513
true
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
Definition: hooks.txt:1985
Language\romanNumeral
static romanNumeral( $num)
Roman number formatting up to 10000.
Definition: Language.php:2038
LanguageTest\testEmbedBidi
testEmbedBidi()
Language::embedBidi()
Definition: LanguageTest.php:1625
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:215
LanguageTest\testWellFormedLanguageTag
testWellFormedLanguageTag( $code, $message='')
Test Language::isWellFormedLanguageTag() provideWellFormedLanguageTags Language::isWellFormedLanguage...
Definition: LanguageTest.php:388
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
LanguageTest\provideGetParentLanguage
static provideGetParentLanguage()
Definition: LanguageTest.php:1866
Language\isSupportedLanguage
static isSupportedLanguage( $code)
Checks whether any localisation is available for that language tag in MediaWiki (MessagesXx....
Definition: Language.php:305
Language\fetchLanguageNames
static fetchLanguageNames( $inLanguage=self::AS_AUTONYMS, $include='mw')
Get an array of language names, indexed by code.
Definition: Language.php:836
MediaWikiTestCase\assertType
assertType( $type, $actual, $message='')
Asserts the type of the provided value.
Definition: MediaWikiTestCase.php:2177
Language\$dataCache
static LocalisationCache $dataCache
Definition: Language.php:80
LanguageTest\provideFormatNum
provideFormatNum()
Definition: LanguageTest.php:1710
LanguageTest\testSprintfDateTZ
testSprintfDateTZ( $format, $ts, $ignore, $expected, $msg)
sprintfDate should use passed timezone provideSprintfDateSamples Language::sprintfDate
Definition: LanguageTest.php:663
LanguageTest\testSprintfDateTooShortTimestamp
testSprintfDateTooShortTimestamp()
Test too short timestamp MWException Language::sprintfDate.
Definition: LanguageTest.php:584
LanguageTest\testIsSupportedLanguage
testIsSupportedLanguage( $code, $expected, $comment)
provideIsSupportedLanguage Language::isSupportedLanguage
Definition: LanguageTest.php:1840
Language
Internationalisation code.
Definition: Language.php:36
LanguageTest\testTruncateHtml
testTruncateHtml( $len, $ellipsis, $input, $expected)
provideHTMLTruncateData Language::truncateHTML
Definition: LanguageTest.php:316
LanguageTest\provideUnknownLanguageTags
static provideUnknownLanguageTags()
Definition: LanguageTest.php:572