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