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
;
13 * @covers \MediaWiki\Languages\LanguageConverterFactory
15 class LanguageConverterFactoryTest
extends MediaWikiLangTestCase
{
17 * @dataProvider codeProvider
19 public function testLanguageConverters(
21 $staticDefaultVariant,
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,
36 $this->getServiceContainer()->getObjectFactory(),
37 static function () use ( $lang ) {
41 $this->assertFalse( $factory->isConversionDisabled() );
42 $this->assertFalse( $factory->isLinkConversionDisabled() );
43 $converter = $factory->getLanguageConverter( $lang );
44 $this->verifyConverter(
48 $staticDefaultVariant,
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,
66 $this->getServiceContainer()->getObjectFactory(),
67 static function () use ( $lang ) {
71 $this->assertFalse( $factory->isConversionDisabled() );
72 $this->assertFalse( $factory->isLinkConversionDisabled() );
74 $converter = $factory->getLanguageConverter( $lang );
76 $this->verifyConverter(
82 [ 'en', 'en-x-piglatin' ],
86 [ 'en' => 'bidirectional', 'en-x-piglatin' => 'bidirectional' ]
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,
101 $this->getServiceContainer()->getObjectFactory(),
102 static function () use ( $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()
116 $this->assertContains(
117 'en-x-piglatin', $converter->getVariants()
122 public static function booleanProvider() {
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,
143 $this->getServiceContainer()->getObjectFactory(),
144 static function () use ( $lang ) {
148 $this->assertFalse( $factory->isConversionDisabled() );
149 $this->assertFalse( $factory->isLinkConversionDisabled() );
151 $converter = $factory->getLanguageConverter();
153 $this->verifyConverter(
158 TrivialLanguageConverter
::class,
167 private function verifyConverter(
171 $staticDefaultVariant,
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" );
202 $this->assertArraySubmapSame(
203 array_merge( $defaultFlags, $flags ),
204 $converter->getFlags(),
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
262 'ban', 'ban', BanConverter
::class,
263 [ 'ban', 'ban-bali', 'ban-x-dharma', 'ban-x-palmleaf', 'ban-x-pku' ],
266 'ban-x-dharma' => 'ban',
267 'ban-x-palmleaf' => 'ban',
268 'ban-x-pku' => 'ban',
270 'ban' => 'bidirectional',
271 'ban-bali' => 'bidirectional',
272 'ban-x-dharma' => 'bidirectional',
273 'ban-x-palmleaf' => 'bidirectional',
274 'ban-x-pku' => 'bidirectional',
279 'crh', 'crh', CrhConverter
::class,
280 [ 'crh', 'crh-cyrl', 'crh-latn' ],
283 'crh-cyrl' => 'crh-latn',
284 'crh-latn' => 'crh-cyrl',
286 'crh' => 'bidirectional',
287 'crh-cyrl' => 'bidirectional',
288 'crh-latn' => 'bidirectional'
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' ],
301 'gan-hans' => 'bidirectional',
302 'gan-hant' => 'bidirectional'
307 'iu', 'iu', IuConverter
::class,
308 [ 'iu', 'ike-cans', 'ike-latn' ],
314 'iu' => 'bidirectional',
315 'ike-cans' => 'bidirectional',
316 'ike-latn' => 'bidirectional'
321 'ku', 'ku', KuConverter
::class,
322 [ 'ku', 'ku-arab', 'ku-latn' ],
325 'ku-arab' => 'ku-latn',
326 'ku-latn' => 'ku-arab'
328 'ku' => 'bidirectional',
329 'ku-arab' => 'bidirectional',
330 'ku-latn' => 'bidirectional'
335 'mni', 'mni', MniConverter
::class,
336 [ 'mni', 'mni-beng' ],
340 'mni' => 'bidirectional',
341 'mni-beng' => 'bidirectional'
346 'sh', 'sh-latn', ShConverter
::class,
347 [ 'sh-latn', 'sh-cyrl' ],
348 [ 'sh-cyrl' => 'sh-latn' ],
350 'sh-latn' => 'bidirectional',
351 'sh-cyrl' => 'bidirectional'
356 'shi', 'shi', ShiConverter
::class,
357 [ 'shi', 'shi-tfng', 'shi-latn' ],
359 'shi' => [ 'shi-latn', 'shi-tfng' ],
363 'shi' => 'bidirectional',
364 'shi-tfng' => 'bidirectional',
365 'shi-latn' => 'bidirectional'
370 'sr', 'sr', SrConverter
::class,
371 [ 'sr', 'sr-ec', 'sr-el' ],
386 'sr' => 'bidirectional',
387 'sr-ec' => 'bidirectional',
388 'sr-el' => 'bidirectional'
393 'tg', 'tg', TgConverter
::class,
396 'tg' => 'bidirectional',
397 'tg-latn' => 'bidirectional'
402 'tly', 'tly', TlyConverter
::class,
403 [ 'tly', 'tly-cyrl' ],
404 [ 'tly-cyrl' => 'tly' ],
408 'tly-cyrl' => 'tly-cyrl'
411 'tly' => 'bidirectional',
412 'tly-cyrl' => 'bidirectional',
417 'uz', 'uz', UzConverter
::class,
418 [ 'uz', 'uz-latn', 'uz-cyrl' ],
425 'uz-latn' => 'uz-latn',
426 'uz-cyrl' => 'uz-cyrl'
428 'uz' => 'bidirectional',
429 'uz-latn' => 'bidirectional',
430 'uz-cyrl' => 'bidirectional',
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' ],
443 'wuu-hans' => 'bidirectional',
444 'wuu-hant' => 'bidirectional'
449 'zgh', 'zgh', ZghConverter
::class,
450 [ 'zgh', 'zgh-latn' ],
452 'zgh' => 'bidirectional',
453 'zgh-latn' => 'bidirectional'
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' ],
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',
501 'zh-hans' => 'zh-hans',
502 'zh-hant' => 'zh-hant',
510 yield
'zh' => [ 'zh', 'zh', ZhConverter
::class, $zh_variants, $zh_variantfallbacks, [], $zh_flags, $zh_ml ];