Merge "docs: Fix typo"
[mediawiki.git] / tests / phpunit / includes / language / LanguageConverterFactoryTest.php
blobd94bfda19deda57cde590bf3ceb0beaf0dca1586
1 <?php
3 use MediaWiki\Config\HashConfig;
4 use MediaWiki\Config\ServiceOptions;
5 use MediaWiki\Language\LanguageConverter;
6 use MediaWiki\Languages\LanguageConverterFactory;
7 use MediaWiki\MainConfigNames;
8 use Wikimedia\TestingAccessWrapper;
10 /**
11 * @group large
12 * @group Language
13 * @covers \MediaWiki\Languages\LanguageConverterFactory
15 class LanguageConverterFactoryTest extends MediaWikiLangTestCase {
16 /**
17 * @dataProvider codeProvider
19 public function testLanguageConverters(
20 $langCode,
21 $staticDefaultVariant,
22 $type,
23 $variants,
24 $variantFallbacks,
25 $variantNames,
26 $flags,
27 $manualLevel
28 ) {
29 $lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( $langCode );
30 $factory = new LanguageConverterFactory(
31 new ServiceOptions( LanguageConverterFactory::CONSTRUCTOR_OPTIONS, new HashConfig( [
32 MainConfigNames::UsePigLatinVariant => false,
33 MainConfigNames::DisableLangConversion => false,
34 MainConfigNames::DisableTitleConversion => false,
35 ] ) ),
36 $this->getServiceContainer()->getObjectFactory(),
37 static function () use ( $lang ) {
38 return $lang;
41 $this->assertFalse( $factory->isConversionDisabled() );
42 $this->assertFalse( $factory->isLinkConversionDisabled() );
43 $converter = $factory->getLanguageConverter( $lang );
44 $this->verifyConverter(
45 $converter,
46 $lang,
47 $langCode,
48 $staticDefaultVariant,
49 $type,
50 $variants,
51 $variantFallbacks,
52 $variantNames,
53 $flags,
54 $manualLevel
58 public function testCreateFromCodeEnPigLatin() {
59 $lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' );
60 $factory = new LanguageConverterFactory(
61 new ServiceOptions( LanguageConverterFactory::CONSTRUCTOR_OPTIONS, new HashConfig( [
62 MainConfigNames::UsePigLatinVariant => true,
63 MainConfigNames::DisableLangConversion => false,
64 MainConfigNames::DisableTitleConversion => false,
65 ] ) ),
66 $this->getServiceContainer()->getObjectFactory(),
67 static function () use ( $lang ) {
68 return $lang;
71 $this->assertFalse( $factory->isConversionDisabled() );
72 $this->assertFalse( $factory->isLinkConversionDisabled() );
74 $converter = $factory->getLanguageConverter( $lang );
76 $this->verifyConverter(
77 $converter,
78 $lang,
79 'en',
80 'en',
81 EnConverter::class,
82 [ 'en', 'en-x-piglatin' ],
83 [],
84 [],
85 [],
86 [ 'en' => 'bidirectional', 'en-x-piglatin' => 'bidirectional' ]
90 /**
91 * @dataProvider booleanProvider
93 public function testDisabledBooleans( $pigLatinDisabled, $conversionDisabled, $titleDisabled ) {
94 $lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' );
95 $factory = new LanguageConverterFactory(
96 new ServiceOptions( LanguageConverterFactory::CONSTRUCTOR_OPTIONS, new HashConfig( [
97 MainConfigNames::UsePigLatinVariant => !$pigLatinDisabled,
98 MainConfigNames::DisableLangConversion => $conversionDisabled,
99 MainConfigNames::DisableTitleConversion => $titleDisabled,
100 ] ) ),
101 $this->getServiceContainer()->getObjectFactory(),
102 static function () use ( $lang ) {
103 return $lang;
106 $converter = $factory->getLanguageConverter( $lang );
108 $this->assertSame( $conversionDisabled, $factory->isConversionDisabled() );
109 $this->assertSame( $conversionDisabled || $titleDisabled, $factory->isLinkConversionDisabled() );
111 if ( $pigLatinDisabled ) {
112 $this->assertNotContains(
113 'en-x-piglatin', $converter->getVariants()
115 } else {
116 $this->assertContains(
117 'en-x-piglatin', $converter->getVariants()
122 public static function booleanProvider() {
123 return [
124 [ false, false, false ],
125 [ false, false, true ],
126 [ false, true, false ],
127 [ false, true, true ],
128 [ true, false, false ],
129 [ true, false, true ],
130 [ true, true, false ],
131 [ true, true, true ],
135 public function testDefaultContentLanguageFallback() {
136 $lang = $this->getServiceContainer()->getLanguageFactory()->getLanguage( 'en' );
137 $factory = new LanguageConverterFactory(
138 new ServiceOptions( LanguageConverterFactory::CONSTRUCTOR_OPTIONS, new HashConfig( [
139 MainConfigNames::UsePigLatinVariant => false,
140 MainConfigNames::DisableLangConversion => false,
141 MainConfigNames::DisableTitleConversion => false,
142 ] ) ),
143 $this->getServiceContainer()->getObjectFactory(),
144 static function () use ( $lang ) {
145 return $lang;
148 $this->assertFalse( $factory->isConversionDisabled() );
149 $this->assertFalse( $factory->isLinkConversionDisabled() );
151 $converter = $factory->getLanguageConverter();
153 $this->verifyConverter(
154 $converter,
155 $lang,
156 'en',
157 'en',
158 TrivialLanguageConverter::class,
159 [ 'en' ],
167 private function verifyConverter(
168 $converter,
169 $lang,
170 $langCode,
171 $staticDefaultVariant,
172 $type,
173 $variants,
174 $variantFallbacks,
175 $variantNames,
176 $flags,
177 $manualLevel
179 $this->assertInstanceOf( $type, $converter );
181 if ( $converter instanceof LanguageConverter ) {
182 $testConverter = TestingAccessWrapper::newFromObject( $converter );
183 $this->assertSame( $lang, $testConverter->mLangObj, "Language should be as provided" );
185 $this->assertEquals( $langCode, $testConverter->getMainCode(),
186 "getMainCode should be as $langCode" );
187 $this->assertEquals( $staticDefaultVariant, $testConverter->getStaticDefaultVariant(),
188 "getStaticDefaultVariant should be as $staticDefaultVariant" );
189 $this->assertEquals( $manualLevel, $testConverter->getManualLevel(), "Manual Level" );
191 $this->assertEquals( $variants, $testConverter->getVariants(), "Variants" );
192 $this->assertEquals( $variantFallbacks, $testConverter->getVariantsFallbacks(), "Variant Fallbacks" );
193 $defaultFlags = [
194 'A' => 'A',
195 'T' => 'T',
196 'R' => 'R',
197 'D' => 'D',
198 '-' => '-',
199 'H' => 'H',
200 'N' => 'N',
202 $this->assertArraySubmapSame(
203 array_merge( $defaultFlags, $flags ),
204 $converter->getFlags(),
205 "Flags"
210 public static function codeProvider() {
211 $trivialWithNothingElseCodes = [
212 'aa', 'ab', 'abs', 'ace', 'ady', 'ady-cyrl', 'aeb', 'aeb-arab', 'aeb-latn',
213 'af', 'aln', 'als', 'am', 'an', 'ang', 'anp', 'ar', 'arc', 'arn',
214 'arq', 'ary', 'arz', 'as', 'ase', 'ast', 'atj', 'av', 'avk', 'awa', 'ay',
215 'az', 'azb', 'ba', 'ban-bali', 'bar', 'bat-smg', 'bbc', 'bbc-latn', 'bcc',
216 'bcl', 'be', 'be-tarask', 'be-x-old', 'bg', 'bgn', 'bh', 'bho', 'bi', 'bjn',
217 'bm', 'bn', 'bo', 'bpy', 'bqi', 'br', 'brh', 'bs', 'btm', 'bto', 'bug', 'bxr',
218 'ca', 'cbk-zam', 'cdo', 'ce', 'ceb', 'ch', 'cho', 'chr', 'chy', 'ckb', 'co',
219 'cps', 'cr', 'crh-latn', 'crh-cyrl', 'cs', 'csb', 'cu', 'cv', 'cy', 'da',
220 'de', 'de-at', 'de-ch', 'de-formal', 'din', 'diq', 'dsb', 'dtp', 'dty',
221 'dv', 'dz', 'ee', 'egl', 'el', 'eml', 'en', 'en-ca', 'en-gb', 'eo', 'es',
222 'es-419', 'es-formal', 'et', 'eu', 'ext', 'fa', 'ff', 'fi', 'fit', 'fiu-vro',
223 'fj', 'fo', 'fr', 'frc', 'frp', 'frr', 'fur', 'fy', 'ga', 'gag', 'gan-hans',
224 'gan-hant', 'gcr', 'gd', 'gl', 'glk', 'gn', 'gom', 'gom-deva', 'gom-latn',
225 'gor', 'got', 'grc', 'gsw', 'gu', 'gv', 'ha', 'hak', 'haw', 'he', 'hi',
226 'hif', 'hif-latn', 'hil', 'ho', 'hr', 'hrx', 'hsb', 'ht', 'hu', 'hu-formal',
227 'hy', 'hyw', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'ike-cans',
228 'ike-latn', 'ilo', 'inh', 'io', 'is', 'it', 'ja', 'jam', 'jbo', 'jut',
229 'jv', 'ka', 'kaa', 'kab', 'kbd', 'kbd-cyrl', 'kbp', 'kg', 'khw', 'ki',
230 'kiu', 'kj', 'kjp', 'kl', 'km', 'kn', 'ko', 'ko-kp', 'koi', 'kr', 'krc', 'kri', 'krj',
231 'krl', 'ks', 'ks-arab', 'ks-deva', 'ksh', 'ku-latn', 'ku-arab', 'kum', 'kv',
232 'kw', 'ky', 'la', 'lad', 'lb', 'lbe', 'lez', 'lfn', 'lg', 'li', 'lij', 'liv',
233 'lki', 'lmo', 'ln', 'lo', 'lrc', 'loz', 'lt', 'ltg', 'lus', 'luz', 'lv',
234 'lzh', 'lzz', 'mai', 'map-bms', 'mdf', 'mg', 'mh', 'mhr', 'mi', 'min', 'mk',
235 'ml', 'mn', 'mnw', 'mo', 'mr', 'mrj', 'ms', 'mt', 'mus', 'mwl', 'my',
236 'myv', 'mzn', 'na', 'nah', 'nan', 'nap', 'nb', 'nds', 'nds-nl', 'ne', 'new',
237 'ng', 'niu', 'nl', 'nl-informal', 'nn', 'no', 'nov', 'nqo', 'nrm', 'nso',
238 'nv', 'ny', 'nys', 'oc', 'olo', 'om', 'or', 'os', 'pa', 'pag', 'pam', 'pap',
239 'pcd', 'pdc', 'pdt', 'pfl', 'pi', 'pih', 'pl', 'pms', 'pnb', 'pnt', 'prg',
240 'ps', 'pt', 'pt-br', 'qu', 'qug', 'rgn', 'rif', 'rm', 'rmy', 'rn', 'ro',
241 'roa-rup', 'roa-tara', 'ru', 'rue', 'rup', 'ruq', 'ruq-cyrl', 'ruq-latn',
242 'rw', 'sa', 'sah', 'sat', 'sc', 'scn', 'sco', 'sd', 'sdc', 'sdh', 'se',
243 'sei', 'ses', 'sg', 'sgs', 'sh-cyrl', 'sh-latn', 'shi-tfng', 'shi-latn', 'shn',
244 'shy-latn', 'si', 'simple', 'sk', 'skr', 'skr-arab', 'sl', 'sli', 'sm', 'sma', 'sn',
245 'so', 'sq', 'sr-ec', 'sr-el', 'srn', 'ss', 'st', 'sty', 'stq', 'su', 'sv',
246 'sw', 'szl', 'szy', 'ta', 'tay', 'tcy', 'te', 'tet', 'tg-cyrl', 'tg-latn',
247 'th', 'ti', 'tk', 'tl', 'tly-latn', 'tn', 'to', 'tpi', 'tr', 'tru', 'ts', 'tt',
248 'tt-cyrl', 'tt-latn', 'tum', 'tw', 'ty', 'tyv', 'tzm', 'udm', 'ug', 'ug-arab',
249 'ug-latn', 'uk', 'ur', 'uz-cyrl', 'uz-latn', 've', 'vec', 'vep', 'vi', 'vls',
250 'vmf', 'vo', 'vot', 'vro', 'wa', 'war', 'wo', 'wuu-hans', 'wuu-hant', 'xal',
251 'xh', 'xmf', 'xsy', 'yi', 'yo', 'yue', 'yue-hans', 'yue-hant', 'za', 'zea',
252 'zh-classical', 'zh-cn', 'zh-hans', 'zh-hant', 'zh-hk', 'zh-min-nan', 'zh-mo',
253 'zh-my', 'zh-sg', 'zh-tw', 'zu',
255 foreach ( $trivialWithNothingElseCodes as $code ) {
256 # $langCode, $mainVariantCode, $type, $variants, $variantFallbacks, $variantNames, $flags, $manualLevel
257 yield $code => [ $code, $code, TrivialLanguageConverter::class, [], [], [], [], [] ];
260 // Languages with a type of than TrivialLanguageConverter or with variants/flags/manual level
261 yield 'ban' => [
262 'ban', 'ban', BanConverter::class,
263 [ 'ban', 'ban-bali', 'ban-x-dharma', 'ban-x-palmleaf', 'ban-x-pku' ],
265 'ban-bali' => 'ban',
266 'ban-x-dharma' => 'ban',
267 'ban-x-palmleaf' => 'ban',
268 'ban-x-pku' => 'ban',
269 ], [], [], [
270 'ban' => 'bidirectional',
271 'ban-bali' => 'bidirectional',
272 'ban-x-dharma' => 'bidirectional',
273 'ban-x-palmleaf' => 'bidirectional',
274 'ban-x-pku' => 'bidirectional',
278 yield 'crh' => [
279 'crh', 'crh', CrhConverter::class,
280 [ 'crh', 'crh-cyrl', 'crh-latn' ],
282 'crh' => 'crh-latn',
283 'crh-cyrl' => 'crh-latn',
284 'crh-latn' => 'crh-cyrl',
285 ], [], [], [
286 'crh' => 'bidirectional',
287 'crh-cyrl' => 'bidirectional',
288 'crh-latn' => 'bidirectional'
292 yield 'gan' => [
293 'gan', 'gan', GanConverter::class,
294 [ 'gan', 'gan-hans', 'gan-hant' ],
296 'gan' => [ 'gan-hans', 'gan-hant' ],
297 'gan-hans' => [ 'gan' ],
298 'gan-hant' => [ 'gan' ],
299 ], [], [], [
300 'gan' => 'disable',
301 'gan-hans' => 'bidirectional',
302 'gan-hant' => 'bidirectional'
306 yield 'iu' => [
307 'iu', 'iu', IuConverter::class,
308 [ 'iu', 'ike-cans', 'ike-latn' ],
310 'iu' => 'ike-cans',
311 'ike-cans' => 'iu',
312 'ike-latn' => 'iu',
313 ], [], [], [
314 'iu' => 'bidirectional',
315 'ike-cans' => 'bidirectional',
316 'ike-latn' => 'bidirectional'
320 yield 'ku' => [
321 'ku', 'ku', KuConverter::class,
322 [ 'ku', 'ku-arab', 'ku-latn' ],
324 'ku' => 'ku-latn',
325 'ku-arab' => 'ku-latn',
326 'ku-latn' => 'ku-arab'
327 ], [], [], [
328 'ku' => 'bidirectional',
329 'ku-arab' => 'bidirectional',
330 'ku-latn' => 'bidirectional'
334 yield 'mni' => [
335 'mni', 'mni', MniConverter::class,
336 [ 'mni', 'mni-beng' ],
338 'mni-beng' => 'mni'
339 ], [], [], [
340 'mni' => 'bidirectional',
341 'mni-beng' => 'bidirectional'
345 yield 'sh' => [
346 'sh', 'sh-latn', ShConverter::class,
347 [ 'sh-latn', 'sh-cyrl' ],
348 [ 'sh-cyrl' => 'sh-latn' ],
349 [], [], [
350 'sh-latn' => 'bidirectional',
351 'sh-cyrl' => 'bidirectional'
355 yield 'shi' => [
356 'shi', 'shi', ShiConverter::class,
357 [ 'shi', 'shi-tfng', 'shi-latn' ],
359 'shi' => [ 'shi-latn', 'shi-tfng' ],
360 'shi-tfng' => 'shi',
361 'shi-latn' => 'shi'
362 ], [], [], [
363 'shi' => 'bidirectional',
364 'shi-tfng' => 'bidirectional',
365 'shi-latn' => 'bidirectional'
369 yield 'sr' => [
370 'sr', 'sr', SrConverter::class,
371 [ 'sr', 'sr-ec', 'sr-el' ],
373 'sr' => 'sr-ec',
374 'sr-ec' => 'sr',
375 'sr-el' => 'sr'
376 ], [], [
377 'S' => 'S',
378 'писмо' => 'S',
379 'pismo' => 'S',
380 'W' => 'W',
381 'реч' => 'W',
382 'reč' => 'W',
383 'ријеч' => 'W',
384 'riječ' => 'W'
385 ], [
386 'sr' => 'bidirectional',
387 'sr-ec' => 'bidirectional',
388 'sr-el' => 'bidirectional'
392 yield 'tg' => [
393 'tg', 'tg', TgConverter::class,
394 [ 'tg', 'tg-latn' ],
395 [], [], [], [
396 'tg' => 'bidirectional',
397 'tg-latn' => 'bidirectional'
401 yield 'tly' => [
402 'tly', 'tly', TlyConverter::class,
403 [ 'tly', 'tly-cyrl' ],
404 [ 'tly-cyrl' => 'tly' ],
407 'tly' => 'tly',
408 'tly-cyrl' => 'tly-cyrl'
411 'tly' => 'bidirectional',
412 'tly-cyrl' => 'bidirectional',
416 yield 'uz' => [
417 'uz', 'uz', UzConverter::class,
418 [ 'uz', 'uz-latn', 'uz-cyrl' ],
420 'uz' => 'uz-latn',
421 'uz-cyrl' => 'uz',
422 'uz-latn' => 'uz',
423 ], [], [
424 'uz' => 'uz',
425 'uz-latn' => 'uz-latn',
426 'uz-cyrl' => 'uz-cyrl'
427 ], [
428 'uz' => 'bidirectional',
429 'uz-latn' => 'bidirectional',
430 'uz-cyrl' => 'bidirectional',
434 yield 'wuu' => [
435 'wuu', 'wuu', WuuConverter::class,
436 [ 'wuu', 'wuu-hans', 'wuu-hant' ],
438 'wuu' => [ 'wuu-hans', 'wuu-hant' ],
439 'wuu-hans' => [ 'wuu' ],
440 'wuu-hant' => [ 'wuu' ],
441 ], [], [], [
442 'wuu' => 'disable',
443 'wuu-hans' => 'bidirectional',
444 'wuu-hant' => 'bidirectional'
448 yield 'zgh' => [
449 'zgh', 'zgh', ZghConverter::class,
450 [ 'zgh', 'zgh-latn' ],
451 [], [], [], [
452 'zgh' => 'bidirectional',
453 'zgh-latn' => 'bidirectional'
457 $zh_variants = [
458 'zh',
459 'zh-hans',
460 'zh-hant',
461 'zh-cn',
462 'zh-hk',
463 'zh-mo',
464 'zh-my',
465 'zh-sg',
466 'zh-tw'
469 $zh_variantfallbacks = [
470 'zh' => [ 'zh-hans', 'zh-hant', 'zh-cn', 'zh-tw', 'zh-hk', 'zh-sg', 'zh-mo', 'zh-my' ],
471 'zh-hans' => [ 'zh-cn', 'zh-sg', 'zh-my' ],
472 'zh-hant' => [ 'zh-tw', 'zh-hk', 'zh-mo' ],
473 'zh-cn' => [ 'zh-hans', 'zh-sg', 'zh-my' ],
474 'zh-sg' => [ 'zh-my', 'zh-hans', 'zh-cn' ],
475 'zh-my' => [ 'zh-sg', 'zh-hans', 'zh-cn' ],
476 'zh-tw' => [ 'zh-hant', 'zh-hk', 'zh-mo' ],
477 'zh-hk' => [ 'zh-mo', 'zh-hant', 'zh-tw' ],
478 'zh-mo' => [ 'zh-hk', 'zh-hant', 'zh-tw' ],
480 $zh_ml = [
481 'zh' => 'disable',
482 'zh-hans' => 'unidirectional',
483 'zh-hant' => 'unidirectional',
484 'zh-cn' => 'bidirectional',
485 'zh-hk' => 'bidirectional',
486 'zh-mo' => 'bidirectional',
487 'zh-my' => 'bidirectional',
488 'zh-sg' => 'bidirectional',
489 'zh-tw' => 'bidirectional',
492 $zh_flags = [
493 'A' => 'A',
494 'T' => 'T',
495 'R' => 'R',
496 'D' => 'D',
497 '-' => '-',
498 'H' => 'H',
499 'N' => 'N',
500 'zh' => 'zh',
501 'zh-hans' => 'zh-hans',
502 'zh-hant' => 'zh-hant',
503 'zh-cn' => 'zh-cn',
504 'zh-hk' => 'zh-hk',
505 'zh-mo' => 'zh-mo',
506 'zh-my' => 'zh-my',
507 'zh-sg' => 'zh-sg',
508 'zh-tw' => 'zh-tw'
510 yield 'zh' => [ 'zh', 'zh', ZhConverter::class, $zh_variants, $zh_variantfallbacks, [], $zh_flags, $zh_ml ];