Merge "Selenium: Upgrade WebdriverIO to 4.12.0"
[lhc/web/wiklou.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: 'genitive',
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: 'prepositional',
332 expected: 'доводах',
333 description: 'Grammar test for prepositional case, доводы -> доводах'
334 },
335 {
336 word: 'Викисклад',
337 grammarForm: 'prepositional',
338 expected: 'Викискладе',
339 description: 'Grammar test for prepositional case, Викисклад -> Викискладе'
340 },
341 {
342 word: 'Викисклад',
343 grammarForm: 'genitive',
344 expected: 'Викисклада',
345 description: 'Grammar test for genitive case, Викисклад -> Викисклада'
346 },
347 {
348 word: 'песчаник',
349 grammarForm: 'prepositional',
350 expected: 'песчанике',
351 description: 'Grammar test for prepositional case, песчаник -> песчанике'
352 },
353 {
354 word: 'данные',
355 grammarForm: 'prepositional',
356 expected: 'данных',
357 description: 'Grammar test for prepositional 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: 'languagegen',
374 expected: 'иврита',
375 description: 'Grammar test for languagegen case, иврит -> иврита'
376 },
377 {
378 word: 'эсперанто',
379 grammarForm: 'languagegen',
380 expected: 'эсперанто',
381 description: 'Grammar test for languagegen 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: 'languageprep',
398 expected: 'идише',
399 description: 'Grammar test for languageprep case, идиш -> идише'
400 },
401 {
402 word: 'эсперанто',
403 grammarForm: 'languageprep',
404 expected: 'эсперанто',
405 description: 'Grammar test for languageprep 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 word: 'эсперанто',
427 grammarForm: 'languageadverb',
428 expected: 'на эсперанто',
429 description: 'Grammar test for languageadverb case, эсперанто -> на эсперанто'
430 },
431 {
432 word: 'гуарани',
433 grammarForm: 'languageadverb',
434 expected: 'на языке гуарани',
435 description: 'Grammar test for languageadverb case, гуарани -> на языке гуарани'
436 }
437 ],
438
439 hu: [
440 {
441 word: 'Wikipédiá',
442 grammarForm: 'rol',
443 expected: 'Wikipédiáról',
444 description: 'Grammar test for rol case'
445 },
446 {
447 word: 'Wikipédiá',
448 grammarForm: 'ba',
449 expected: 'Wikipédiába',
450 description: 'Grammar test for ba case'
451 },
452 {
453 word: 'Wikipédiá',
454 grammarForm: 'k',
455 expected: 'Wikipédiák',
456 description: 'Grammar test for k case'
457 }
458 ],
459
460 ga: [
461 {
462 word: 'an Domhnach',
463 grammarForm: 'ainmlae',
464 expected: 'Dé Domhnaigh',
465 description: 'Grammar test for ainmlae case'
466 },
467 {
468 word: 'an Luan',
469 grammarForm: 'ainmlae',
470 expected: 'Dé Luain',
471 description: 'Grammar test for ainmlae case'
472 },
473 {
474 word: 'an Satharn',
475 grammarForm: 'ainmlae',
476 expected: 'Dé Sathairn',
477 description: 'Grammar test for ainmlae case'
478 }
479 ],
480
481 uk: [
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: 'genitive',
497 expected: 'Вікіцитат',
498 description: 'Grammar test for genitive case'
499 },
500 {
501 word: 'Вікіпідручник',
502 grammarForm: 'genitive',
503 expected: 'Вікіпідручника',
504 description: 'Grammar test for genitive case'
505 },
506 {
507 word: 'Вікіпедія',
508 grammarForm: 'accusative',
509 expected: 'Вікіпедію',
510 description: 'Grammar test for accusative case'
511 }
512 ],
513
514 sl: [
515 {
516 word: 'word',
517 grammarForm: 'orodnik',
518 expected: 'z word',
519 description: 'Grammar test for orodnik case'
520 },
521 {
522 word: 'word',
523 grammarForm: 'mestnik',
524 expected: 'o word',
525 description: 'Grammar test for mestnik case'
526 }
527 ],
528
529 os: [
530 {
531 word: 'бæстæ',
532 grammarForm: 'genitive',
533 expected: 'бæсты',
534 description: 'Grammar test for genitive case'
535 },
536 {
537 word: 'бæстæ',
538 grammarForm: 'allative',
539 expected: 'бæстæм',
540 description: 'Grammar test for allative case'
541 },
542 {
543 word: 'Тигр',
544 grammarForm: 'dative',
545 expected: 'Тигрæн',
546 description: 'Grammar test for dative case'
547 },
548 {
549 word: 'цъити',
550 grammarForm: 'dative',
551 expected: 'цъитийæн',
552 description: 'Grammar test for dative case'
553 },
554 {
555 word: 'лæппу',
556 grammarForm: 'genitive',
557 expected: 'лæппуйы',
558 description: 'Grammar test for genitive case'
559 },
560 {
561 word: '2011',
562 grammarForm: 'equative',
563 expected: '2011-ау',
564 description: 'Grammar test for equative case'
565 }
566 ],
567
568 la: [
569 {
570 word: 'Translatio',
571 grammarForm: 'genitive',
572 expected: 'Translationis',
573 description: 'Grammar test for genitive case'
574 },
575 {
576 word: 'Translatio',
577 grammarForm: 'accusative',
578 expected: 'Translationem',
579 description: 'Grammar test for accusative case'
580 },
581 {
582 word: 'Translatio',
583 grammarForm: 'ablative',
584 expected: 'Translatione',
585 description: 'Grammar test for ablative case'
586 }
587 ]
588 };
589
590 $.each( grammarTests, function ( langCode, test ) {
591 if ( langCode === mw.config.get( 'wgUserLanguage' ) ) {
592 grammarTest( langCode, test );
593 }
594 } );
595
596 QUnit.test( 'List to text test', function ( assert ) {
597 assert.equal( mw.language.listToText( [] ), '', 'Blank list' );
598 assert.equal( mw.language.listToText( [ 'a' ] ), 'a', 'Single item' );
599 assert.equal( mw.language.listToText( [ 'a', 'b' ] ), 'a and b', 'Two items' );
600 assert.equal( mw.language.listToText( [ 'a', 'b', 'c' ] ), 'a, b and c', 'More than two items' );
601 } );
602
603 bcp47Tests = [
604 // Extracted from BCP 47 (list not exhaustive)
605 // # 2.1.1
606 [ 'en-ca-x-ca', 'en-CA-x-ca' ],
607 [ 'sgn-be-fr', 'sgn-BE-FR' ],
608 [ 'az-latn-x-latn', 'az-Latn-x-latn' ],
609 // # 2.2
610 [ 'sr-Latn-RS', 'sr-Latn-RS' ],
611 [ 'az-arab-ir', 'az-Arab-IR' ],
612
613 // # 2.2.5
614 [ 'sl-nedis', 'sl-nedis' ],
615 [ 'de-ch-1996', 'de-CH-1996' ],
616
617 // # 2.2.6
618 [
619 'en-latn-gb-boont-r-extended-sequence-x-private',
620 'en-Latn-GB-boont-r-extended-sequence-x-private'
621 ],
622
623 // Examples from BCP 47 Appendix A
624 // # Simple language subtag:
625 [ 'DE', 'de' ],
626 [ 'fR', 'fr' ],
627 [ 'ja', 'ja' ],
628
629 // # Language subtag plus script subtag:
630 [ 'zh-hans', 'zh-Hans' ],
631 [ 'sr-cyrl', 'sr-Cyrl' ],
632 [ 'sr-latn', 'sr-Latn' ],
633
634 // # Extended language subtags and their primary language subtag
635 // # counterparts:
636 [ 'zh-cmn-hans-cn', 'zh-cmn-Hans-CN' ],
637 [ 'cmn-hans-cn', 'cmn-Hans-CN' ],
638 [ 'zh-yue-hk', 'zh-yue-HK' ],
639 [ 'yue-hk', 'yue-HK' ],
640
641 // # Language-Script-Region:
642 [ 'zh-hans-cn', 'zh-Hans-CN' ],
643 [ 'sr-latn-RS', 'sr-Latn-RS' ],
644
645 // # Language-Variant:
646 [ 'sl-rozaj', 'sl-rozaj' ],
647 [ 'sl-rozaj-biske', 'sl-rozaj-biske' ],
648 [ 'sl-nedis', 'sl-nedis' ],
649
650 // # Language-Region-Variant:
651 [ 'de-ch-1901', 'de-CH-1901' ],
652 [ 'sl-it-nedis', 'sl-IT-nedis' ],
653
654 // # Language-Script-Region-Variant:
655 [ 'hy-latn-it-arevela', 'hy-Latn-IT-arevela' ],
656
657 // # Language-Region:
658 [ 'de-de', 'de-DE' ],
659 [ 'en-us', 'en-US' ],
660 [ 'es-419', 'es-419' ],
661
662 // # Private use subtags:
663 [ 'de-ch-x-phonebk', 'de-CH-x-phonebk' ],
664 [ 'az-arab-x-aze-derbend', 'az-Arab-x-aze-derbend' ],
665 /**
666 * Previous test does not reflect the BCP 47 which states:
667 * az-Arab-x-AZE-derbend
668 * AZE being private, it should be lower case, hence the test above
669 * should probably be:
670 * [ 'az-arab-x-aze-derbend', 'az-Arab-x-AZE-derbend' ],
671 */
672
673 // # Private use registry values:
674 [ 'x-whatever', 'x-whatever' ],
675 [ 'qaa-qaaa-qm-x-southern', 'qaa-Qaaa-QM-x-southern' ],
676 [ 'de-qaaa', 'de-Qaaa' ],
677 [ 'sr-latn-qm', 'sr-Latn-QM' ],
678 [ 'sr-qaaa-rs', 'sr-Qaaa-RS' ],
679
680 // # Tags that use extensions
681 [ 'en-us-u-islamcal', 'en-US-u-islamcal' ],
682 [ 'zh-cn-a-myext-x-private', 'zh-CN-a-myext-x-private' ],
683 [ 'en-a-myext-b-another', 'en-a-myext-b-another' ]
684
685 // # Invalid:
686 // de-419-DE
687 // a-DE
688 // ar-a-aaa-b-bbb-a-ccc
689 ];
690
691 QUnit.test( 'mw.language.bcp47', function ( assert ) {
692 bcp47Tests.forEach( function ( data ) {
693 var input = data[ 0 ],
694 expected = data[ 1 ];
695 assert.equal( mw.language.bcp47( input ), expected );
696 } );
697 } );
698 }( mediaWiki, jQuery ) );