]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / qunit / suites / resources / mediawiki / mediawiki.language.test.js
1 ( function ( mw, $ ) {
2         'use strict';
3
4         var grammarTests, bcp47Tests;
5
6         QUnit.module( 'mediawiki.language', QUnit.newMwEnvironment( {
7                 setup: function () {
8                         this.liveLangData = mw.language.data;
9                         mw.language.data = {};
10                 },
11                 teardown: function () {
12                         mw.language.data = this.liveLangData;
13                 },
14                 messages: {
15                         // mw.language.listToText test
16                         and: ' and',
17                         'comma-separator': ', ',
18                         'word-separator': ' '
19                 }
20         } ) );
21
22         QUnit.test( 'mw.language getData and setData', function ( assert ) {
23                 mw.language.setData( 'en', 'testkey', 'testvalue' );
24                 assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
25                 assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
26                 mw.language.setData( 'en-us', 'testkey', 'testvalue' );
27                 assert.equal( mw.language.getData( 'en-US', 'testkey' ), 'testvalue', 'Case insensitive test for mw.language' );
28         } );
29
30         QUnit.test( 'mw.language.commafy test', function ( assert ) {
31                 mw.language.setData( 'en', 'digitGroupingPattern', null );
32                 mw.language.setData( 'en', 'digitTransformTable', null );
33                 mw.language.setData( 'en', 'separatorTransformTable', null );
34
35                 mw.config.set( 'wgUserLanguage', 'en' );
36                 // Number grouping patterns are as per http://cldr.unicode.org/translation/number-patterns
37                 assert.equal( mw.language.commafy( 1234.567, '###0.#####' ), '1234.567', 'Pattern with no digit grouping separator defined' );
38                 assert.equal( mw.language.commafy( 123456789.567, '###0.#####' ), '123456789.567', 'Pattern with no digit grouping separator defined, bigger decimal part' );
39                 assert.equal( mw.language.commafy( 0.567, '###0.#####' ), '0.567', 'Decimal part 0' );
40                 assert.equal( mw.language.commafy( '.567', '###0.#####' ), '0.567', 'Decimal part missing. replace with zero' );
41                 assert.equal( mw.language.commafy( 1234, '##,#0.#####' ), '12,34', 'Pattern with no fractional part' );
42                 assert.equal( mw.language.commafy( -1234.567, '###0.#####' ), '-1234.567', 'Negative number' );
43                 assert.equal( mw.language.commafy( -1234.567, '#,###.00' ), '-1,234.56', 'Fractional part bigger than pattern.' );
44                 assert.equal( mw.language.commafy( 123456789.567, '###,##0.00' ), '123,456,789.56', 'Decimal part as group of 3' );
45                 assert.equal( mw.language.commafy( 123456789.567, '###,###,#0.00' ), '1,234,567,89.56', 'Decimal part as group of 3 and last one 2' );
46         } );
47
48         QUnit.test( 'mw.language.convertNumber', function ( assert ) {
49                 mw.language.setData( 'en', 'digitGroupingPattern', null );
50                 mw.language.setData( 'en', 'digitTransformTable', null );
51                 mw.language.setData( 'en', 'separatorTransformTable', { ',': '.', '.': ',' } );
52                 mw.config.set( 'wgUserLanguage', 'en' );
53                 mw.config.set( 'wgTranslateNumerals', true );
54
55                 assert.equal( mw.language.convertNumber( 1800 ), '1.800', 'formatting' );
56                 assert.equal( mw.language.convertNumber( '1.800', true ), '1800', 'unformatting' );
57         } );
58
59         QUnit.test( 'mw.language.convertNumber - digitTransformTable', function ( assert ) {
60                 mw.config.set( 'wgUserLanguage', 'hi' );
61                 mw.config.set( 'wgTranslateNumerals', true );
62                 mw.language.setData( 'hi', 'digitGroupingPattern', null );
63                 mw.language.setData( 'hi', 'separatorTransformTable', { ',': '.', '.': ',' } );
64
65                 // Example from Hindi (MessagesHi.php)
66                 mw.language.setData( 'hi', 'digitTransformTable', {
67                         0: '०',
68                         1: '१',
69                         2: '२'
70                 } );
71
72                 assert.equal( mw.language.convertNumber( 1200 ), '१.२००', 'format' );
73                 assert.equal( mw.language.convertNumber( '१.२००', true ), '1200', 'unformat from digit transform' );
74                 assert.equal( mw.language.convertNumber( '1.200', true ), '1200', 'unformat plain' );
75
76                 mw.config.set( 'wgTranslateNumerals', false );
77
78                 assert.equal( mw.language.convertNumber( 1200 ), '1.200', 'format (digit transform disabled)' );
79                 assert.equal( mw.language.convertNumber( '१.२००', true ), '1200', 'unformat from digit transform (when disabled)' );
80                 assert.equal( mw.language.convertNumber( '1.200', true ), '1200', 'unformat plain (digit transform disabled)' );
81         } );
82
83         function grammarTest( langCode, test ) {
84                 // The test works only if the content language is opt.language
85                 // because it requires [lang].js to be loaded.
86                 QUnit.test( 'Grammar test for lang=' + langCode, function ( assert ) {
87                         var i;
88                         for ( i = 0; i < test.length; i++ ) {
89                                 assert.equal(
90                                         mw.language.convertGrammar( test[ i ].word, test[ i ].grammarForm ),
91                                         test[ i ].expected,
92                                         test[ i ].description
93                                 );
94                         }
95                 } );
96         }
97
98         // These tests run only for the current UI language.
99         grammarTests = {
100                 bs: [
101                         {
102                                 word: 'word',
103                                 grammarForm: 'instrumental',
104                                 expected: 's word',
105                                 description: 'Grammar test for instrumental case'
106                         },
107                         {
108                                 word: 'word',
109                                 grammarForm: 'lokativ',
110                                 expected: 'o word',
111                                 description: 'Grammar test for lokativ case'
112                         }
113                 ],
114
115                 he: [
116                         {
117                                 word: 'ויקיפדיה',
118                                 grammarForm: 'prefixed',
119                                 expected: 'וויקיפדיה',
120                                 description: 'Duplicate the "Waw" if prefixed'
121                         },
122                         {
123                                 word: 'וולפגנג',
124                                 grammarForm: 'prefixed',
125                                 expected: 'וולפגנג',
126                                 description: 'Duplicate the "Waw" if prefixed, but not if it is already duplicated.'
127                         },
128                         {
129                                 word: 'הקובץ',
130                                 grammarForm: 'prefixed',
131                                 expected: 'קובץ',
132                                 description: 'Remove the "He" if prefixed'
133                         },
134                         {
135                                 word: 'Wikipedia',
136                                 grammarForm: 'תחילית',
137                                 expected: '־Wikipedia',
138                                 description: 'Add a hyphen (maqaf) before non-Hebrew letters'
139                         },
140                         {
141                                 word: '1995',
142                                 grammarForm: 'תחילית',
143                                 expected: '־1995',
144                                 description: 'Add a hyphen (maqaf) before numbers'
145                         }
146                 ],
147
148                 hsb: [
149                         {
150                                 word: 'word',
151                                 grammarForm: 'instrumental',
152                                 expected: 'z word',
153                                 description: 'Grammar test for instrumental case'
154                         },
155                         {
156                                 word: 'word',
157                                 grammarForm: 'lokatiw',
158                                 expected: 'wo word',
159                                 description: 'Grammar test for lokatiw case'
160                         }
161                 ],
162
163                 dsb: [
164                         {
165                                 word: 'word',
166                                 grammarForm: 'instrumental',
167                                 expected: 'z word',
168                                 description: 'Grammar test for instrumental case'
169                         },
170                         {
171                                 word: 'word',
172                                 grammarForm: 'lokatiw',
173                                 expected: 'wo word',
174                                 description: 'Grammar test for lokatiw case'
175                         }
176                 ],
177
178                 hy: [
179                         {
180                                 word: 'Մաունա',
181                                 grammarForm: 'genitive',
182                                 expected: 'Մաունայի',
183                                 description: 'Grammar test for genitive case'
184                         },
185                         {
186                                 word: 'հետո',
187                                 grammarForm: 'genitive',
188                                 expected: 'հետոյի',
189                                 description: 'Grammar test for genitive case'
190                         },
191                         {
192                                 word: 'գիրք',
193                                 grammarForm: 'genitive',
194                                 expected: 'գրքի',
195                                 description: 'Grammar test for genitive case'
196                         },
197                         {
198                                 word: 'ժամանակի',
199                                 grammarForm: 'genitive',
200                                 expected: 'ժամանակիի',
201                                 description: 'Grammar test for genitive case'
202                         }
203                 ],
204
205                 fi: [
206                         {
207                                 word: 'talo',
208                                 grammarForm: 'genitive',
209                                 expected: 'talon',
210                                 description: 'Grammar test for genitive case'
211                         },
212                         {
213                                 word: 'linux',
214                                 grammarForm: 'genitive',
215                                 expected: 'linuxin',
216                                 description: 'Grammar test for genitive case'
217                         },
218                         {
219                                 word: 'talo',
220                                 grammarForm: 'elative',
221                                 expected: 'talosta',
222                                 description: 'Grammar test for elative case'
223                         },
224                         {
225                                 word: 'pastöroitu',
226                                 grammarForm: 'partitive',
227                                 expected: 'pastöroitua',
228                                 description: 'Grammar test for partitive case'
229                         },
230                         {
231                                 word: 'talo',
232                                 grammarForm: 'partitive',
233                                 expected: 'taloa',
234                                 description: 'Grammar test for partitive case'
235                         },
236                         {
237                                 word: 'talo',
238                                 grammarForm: 'illative',
239                                 expected: 'taloon',
240                                 description: 'Grammar test for illative case'
241                         },
242                         {
243                                 word: 'linux',
244                                 grammarForm: 'inessive',
245                                 expected: 'linuxissa',
246                                 description: 'Grammar test for inessive case'
247                         }
248                 ],
249
250                 ru: [
251                         {
252                                 word: 'тесть',
253                                 grammarForm: 'genitive',
254                                 expected: 'тестя',
255                                 description: 'Grammar test for genitive case, тесть -> тестя'
256                         },
257                         {
258                                 word: 'привилегия',
259                                 grammarForm: 'genitive',
260                                 expected: 'привилегии',
261                                 description: 'Grammar test for genitive case, привилегия -> привилегии'
262                         },
263                         {
264                                 word: 'установка',
265                                 grammarForm: 'genitive',
266                                 expected: 'установки',
267                                 description: 'Grammar test for genitive case, установка -> установки'
268                         },
269                         {
270                                 word: 'похоти',
271                                 grammarForm: 'genitive',
272                                 expected: 'похотей',
273                                 description: 'Grammar test for genitive case, похоти -> похотей'
274                         },
275                         {
276                                 word: 'доводы',
277                                 grammarForm: 'genitive',
278                                 expected: 'доводов',
279                                 description: 'Grammar test for genitive case, доводы -> доводов'
280                         },
281                         {
282                                 word: 'песчаник',
283                                 grammarForm: 'genitive',
284                                 expected: 'песчаника',
285                                 description: 'Grammar test for genitive case, песчаник -> песчаника'
286                         },
287                         {
288                                 word: 'данные',
289                                 grammarForm: 'genitive',
290                                 expected: 'данных',
291                                 description: 'Grammar test for genitive case, данные -> данных'
292                         },
293                         {
294                                 word: 'тесть',
295                                 grammarForm: 'prepositional',
296                                 expected: 'тесте',
297                                 description: 'Grammar test for prepositional case, тесть -> тесте'
298                         },
299                         {
300                                 word: 'привилегия',
301                                 grammarForm: 'prepositional',
302                                 expected: 'привилегии',
303                                 description: 'Grammar test for prepositional case, привилегия -> привилегии'
304                         },
305                         {
306                                 word: 'установка',
307                                 grammarForm: 'prepositional',
308                                 expected: 'установке',
309                                 description: 'Grammar test for prepositional case, установка -> установке'
310                         },
311                         {
312                                 word: 'похоти',
313                                 grammarForm: 'prepositional',
314                                 expected: 'похотях',
315                                 description: 'Grammar test for prepositional case, похоти -> похотях'
316                         },
317                         {
318                                 word: 'доводы',
319                                 grammarForm: 'prepositional',
320                                 expected: 'доводах',
321                                 description: 'Grammar test for prepositional case, доводы -> доводах'
322                         },
323                         {
324                                 word: 'Викисклад',
325                                 grammarForm: 'prepositional',
326                                 expected: 'Викискладе',
327                                 description: 'Grammar test for prepositional case, Викисклад -> Викискладе'
328                         },
329                         {
330                                 word: 'Викисклад',
331                                 grammarForm: 'genitive',
332                                 expected: 'Викисклада',
333                                 description: 'Grammar test for genitive case, Викисклад -> Викисклада'
334                         },
335                         {
336                                 word: 'песчаник',
337                                 grammarForm: 'prepositional',
338                                 expected: 'песчанике',
339                                 description: 'Grammar test for prepositional case, песчаник -> песчанике'
340                         },
341                         {
342                                 word: 'данные',
343                                 grammarForm: 'prepositional',
344                                 expected: 'данных',
345                                 description: 'Grammar test for prepositional case, данные -> данных'
346                         },
347                         {
348                                 word: 'русский',
349                                 grammarForm: 'languagegen',
350                                 expected: 'русского',
351                                 description: 'Grammar test for languagegen case, русский -> русского'
352                         },
353                         {
354                                 word: 'немецкий',
355                                 grammarForm: 'languagegen',
356                                 expected: 'немецкого',
357                                 description: 'Grammar test for languagegen case, немецкий -> немецкого'
358                         },
359                         {
360                                 word: 'иврит',
361                                 grammarForm: 'languagegen',
362                                 expected: 'иврита',
363                                 description: 'Grammar test for languagegen case, иврит -> иврита'
364                         },
365                         {
366                                 word: 'эсперанто',
367                                 grammarForm: 'languagegen',
368                                 expected: 'эсперанто',
369                                 description: 'Grammar test for languagegen case, эсперанто -> эсперанто'
370                         },
371                         {
372                                 word: 'русский',
373                                 grammarForm: 'languageprep',
374                                 expected: 'русском',
375                                 description: 'Grammar test for languageprep case, русский -> русском'
376                         },
377                         {
378                                 word: 'немецкий',
379                                 grammarForm: 'languageprep',
380                                 expected: 'немецком',
381                                 description: 'Grammar test for languageprep case, немецкий -> немецком'
382                         },
383                         {
384                                 word: 'идиш',
385                                 grammarForm: 'languageprep',
386                                 expected: 'идише',
387                                 description: 'Grammar test for languageprep case, идиш -> идише'
388                         },
389                         {
390                                 word: 'эсперанто',
391                                 grammarForm: 'languageprep',
392                                 expected: 'эсперанто',
393                                 description: 'Grammar test for languageprep case, эсперанто -> эсперанто'
394                         },
395                         {
396                                 word: 'русский',
397                                 grammarForm: 'languageadverb',
398                                 expected: 'по-русски',
399                                 description: 'Grammar test for languageadverb case, русский -> по-русски'
400                         },
401                         {
402                                 word: 'немецкий',
403                                 grammarForm: 'languageadverb',
404                                 expected: 'по-немецки',
405                                 description: 'Grammar test for languageadverb case, немецкий -> по-немецки'
406                         },
407                         {
408                                 word: 'иврит',
409                                 grammarForm: 'languageadverb',
410                                 expected: 'на иврите',
411                                 description: 'Grammar test for languageadverb case, иврит -> на иврите'
412                         },
413                         {
414                                 word: 'эсперанто',
415                                 grammarForm: 'languageadverb',
416                                 expected: 'на эсперанто',
417                                 description: 'Grammar test for languageadverb case, эсперанто -> на эсперанто'
418                         },
419                         {
420                                 word: 'гуарани',
421                                 grammarForm: 'languageadverb',
422                                 expected: 'на языке гуарани',
423                                 description: 'Grammar test for languageadverb case, гуарани -> на языке гуарани'
424                         }
425                 ],
426
427                 hu: [
428                         {
429                                 word: 'Wikipédiá',
430                                 grammarForm: 'rol',
431                                 expected: 'Wikipédiáról',
432                                 description: 'Grammar test for rol case'
433                         },
434                         {
435                                 word: 'Wikipédiá',
436                                 grammarForm: 'ba',
437                                 expected: 'Wikipédiába',
438                                 description: 'Grammar test for ba case'
439                         },
440                         {
441                                 word: 'Wikipédiá',
442                                 grammarForm: 'k',
443                                 expected: 'Wikipédiák',
444                                 description: 'Grammar test for k case'
445                         }
446                 ],
447
448                 ga: [
449                         {
450                                 word: 'an Domhnach',
451                                 grammarForm: 'ainmlae',
452                                 expected: 'Dé Domhnaigh',
453                                 description: 'Grammar test for ainmlae case'
454                         },
455                         {
456                                 word: 'an Luan',
457                                 grammarForm: 'ainmlae',
458                                 expected: 'Dé Luain',
459                                 description: 'Grammar test for ainmlae case'
460                         },
461                         {
462                                 word: 'an Satharn',
463                                 grammarForm: 'ainmlae',
464                                 expected: 'Dé Sathairn',
465                                 description: 'Grammar test for ainmlae case'
466                         }
467                 ],
468
469                 uk: [
470                         {
471                                 word: 'Вікіпедія',
472                                 grammarForm: 'genitive',
473                                 expected: 'Вікіпедії',
474                                 description: 'Grammar test for genitive case'
475                         },
476                         {
477                                 word: 'Віківиди',
478                                 grammarForm: 'genitive',
479                                 expected: 'Віківидів',
480                                 description: 'Grammar test for genitive case'
481                         },
482                         {
483                                 word: 'Вікіцитати',
484                                 grammarForm: 'genitive',
485                                 expected: 'Вікіцитат',
486                                 description: 'Grammar test for genitive case'
487                         },
488                         {
489                                 word: 'Вікіпідручник',
490                                 grammarForm: 'genitive',
491                                 expected: 'Вікіпідручника',
492                                 description: 'Grammar test for genitive case'
493                         },
494                         {
495                                 word: 'Вікіпедія',
496                                 grammarForm: 'accusative',
497                                 expected: 'Вікіпедію',
498                                 description: 'Grammar test for accusative case'
499                         }
500                 ],
501
502                 sl: [
503                         {
504                                 word: 'word',
505                                 grammarForm: 'orodnik',
506                                 expected: 'z word',
507                                 description: 'Grammar test for orodnik case'
508                         },
509                         {
510                                 word: 'word',
511                                 grammarForm: 'mestnik',
512                                 expected: 'o word',
513                                 description: 'Grammar test for mestnik case'
514                         }
515                 ],
516
517                 os: [
518                         {
519                                 word: 'бæстæ',
520                                 grammarForm: 'genitive',
521                                 expected: 'бæсты',
522                                 description: 'Grammar test for genitive case'
523                         },
524                         {
525                                 word: 'бæстæ',
526                                 grammarForm: 'allative',
527                                 expected: 'бæстæм',
528                                 description: 'Grammar test for allative case'
529                         },
530                         {
531                                 word: 'Тигр',
532                                 grammarForm: 'dative',
533                                 expected: 'Тигрæн',
534                                 description: 'Grammar test for dative case'
535                         },
536                         {
537                                 word: 'цъити',
538                                 grammarForm: 'dative',
539                                 expected: 'цъитийæн',
540                                 description: 'Grammar test for dative case'
541                         },
542                         {
543                                 word: 'лæппу',
544                                 grammarForm: 'genitive',
545                                 expected: 'лæппуйы',
546                                 description: 'Grammar test for genitive case'
547                         },
548                         {
549                                 word: '2011',
550                                 grammarForm: 'equative',
551                                 expected: '2011-ау',
552                                 description: 'Grammar test for equative case'
553                         }
554                 ],
555
556                 la: [
557                         {
558                                 word: 'Translatio',
559                                 grammarForm: 'genitive',
560                                 expected: 'Translationis',
561                                 description: 'Grammar test for genitive case'
562                         },
563                         {
564                                 word: 'Translatio',
565                                 grammarForm: 'accusative',
566                                 expected: 'Translationem',
567                                 description: 'Grammar test for accusative case'
568                         },
569                         {
570                                 word: 'Translatio',
571                                 grammarForm: 'ablative',
572                                 expected: 'Translatione',
573                                 description: 'Grammar test for ablative case'
574                         }
575                 ]
576         };
577
578         $.each( grammarTests, function ( langCode, test ) {
579                 if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
580                         grammarTest( langCode, test );
581                 }
582         } );
583
584         QUnit.test( 'List to text test', function ( assert ) {
585                 assert.equal( mw.language.listToText( [] ), '', 'Blank list' );
586                 assert.equal( mw.language.listToText( [ 'a' ] ), 'a', 'Single item' );
587                 assert.equal( mw.language.listToText( [ 'a', 'b' ] ), 'a and b', 'Two items' );
588                 assert.equal( mw.language.listToText( [ 'a', 'b', 'c' ] ), 'a, b and c', 'More than two items' );
589         } );
590
591         bcp47Tests = [
592                 // Extracted from BCP 47 (list not exhaustive)
593                 // # 2.1.1
594                 [ 'en-ca-x-ca', 'en-CA-x-ca' ],
595                 [ 'sgn-be-fr', 'sgn-BE-FR' ],
596                 [ 'az-latn-x-latn', 'az-Latn-x-latn' ],
597                 // # 2.2
598                 [ 'sr-Latn-RS', 'sr-Latn-RS' ],
599                 [ 'az-arab-ir', 'az-Arab-IR' ],
600
601                 // # 2.2.5
602                 [ 'sl-nedis', 'sl-nedis' ],
603                 [ 'de-ch-1996', 'de-CH-1996' ],
604
605                 // # 2.2.6
606                 [
607                         'en-latn-gb-boont-r-extended-sequence-x-private',
608                         'en-Latn-GB-boont-r-extended-sequence-x-private'
609                 ],
610
611                 // Examples from BCP 47 Appendix A
612                 // # Simple language subtag:
613                 [ 'DE', 'de' ],
614                 [ 'fR', 'fr' ],
615                 [ 'ja', 'ja' ],
616
617                 // # Language subtag plus script subtag:
618                 [ 'zh-hans', 'zh-Hans' ],
619                 [ 'sr-cyrl', 'sr-Cyrl' ],
620                 [ 'sr-latn', 'sr-Latn' ],
621
622                 // # Extended language subtags and their primary language subtag
623                 // # counterparts:
624                 [ 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ],
625                 [ 'cmn-hans-cn', 'cmn-Hans-CN' ],
626                 [ 'zh-yue-hk', 'zh-yue-HK' ],
627                 [ 'yue-hk', 'yue-HK' ],
628
629                 // # Language-Script-Region:
630                 [ 'zh-hans-cn', 'zh-Hans-CN' ],
631                 [ 'sr-latn-RS', 'sr-Latn-RS' ],
632
633                 // # Language-Variant:
634                 [ 'sl-rozaj', 'sl-rozaj' ],
635                 [ 'sl-rozaj-biske', 'sl-rozaj-biske' ],
636                 [ 'sl-nedis', 'sl-nedis' ],
637
638                 // # Language-Region-Variant:
639                 [ 'de-ch-1901', 'de-CH-1901' ],
640                 [ 'sl-it-nedis', 'sl-IT-nedis' ],
641
642                 // # Language-Script-Region-Variant:
643                 [ 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ],
644
645                 // # Language-Region:
646                 [ 'de-de', 'de-DE' ],
647                 [ 'en-us', 'en-US' ],
648                 [ 'es-419', 'es-419' ],
649
650                 // # Private use subtags:
651                 [ 'de-ch-x-phonebk', 'de-CH-x-phonebk' ],
652                 [ 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ],
653                 /**
654                  * Previous test does not reflect the BCP 47 which states:
655                  *  az-Arab-x-AZE-derbend
656                  * AZE being private, it should be lower case, hence the test above
657                  * should probably be:
658                  * [ 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ],
659                  */
660
661                 // # Private use registry values:
662                 [ 'x-whatever', 'x-whatever' ],
663                 [ 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ],
664                 [ 'de-qaaa', 'de-Qaaa' ],
665                 [ 'sr-latn-qm', 'sr-Latn-QM' ],
666                 [ 'sr-qaaa-rs', 'sr-Qaaa-RS' ],
667
668                 // # Tags that use extensions
669                 [ 'en-us-u-islamcal', 'en-US-u-islamcal' ],
670                 [ 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ],
671                 [ 'en-a-myext-b-another', 'en-a-myext-b-another' ]
672
673                 // # Invalid:
674                 // de-419-DE
675                 // a-DE
676                 // ar-a-aaa-b-bbb-a-ccc
677         ];
678
679         QUnit.test( 'mw.language.bcp47', function ( assert ) {
680                 bcp47Tests.forEach( function ( data ) {
681                         var input = data[ 0 ],
682                                 expected = data[ 1 ];
683                         assert.equal( mw.language.bcp47( input ), expected );
684                 } );
685         } );
686 }( mediaWiki, jQuery ) );