From 669d1ed19221d92a3d6be9e45e6f8c8591e708e5 Mon Sep 17 00:00:00 2001 From: tjones Date: Tue, 29 May 2018 13:08:45 -0400 Subject: [PATCH] (y)etsin fixes, test refactoring, and misc fixes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * Fix etsin/етсин/этсин as noted in If933fc67845ac994d9ddfdf8349aff445ec9b13a ** only convert tsin to тсин and let the other rules sort out the e * Refactor most tests to be word-specific, which uncovered a couple of bugs in corner cases ** rol/üst prefix matches should match whole words (original [^ü] regex assumed word could not be end of string * Fixed incidental bugs I noticed while looking into the items above ** куркчи => kürkçi was in the wrong section ** cönk => джонк was in the right section, but reversed * Added additional tests cases for all of the above. Change-Id: Ia96be488a7b41c3ddba623b5c9262703b1c82687 --- languages/data/CrhExceptions.php | 35 ++- .../languages/classes/LanguageCrhTest.php | 244 +++++++----------- 2 files changed, 118 insertions(+), 161 deletions(-) diff --git a/languages/data/CrhExceptions.php b/languages/data/CrhExceptions.php index c7592205a0..fcba6dc1dc 100644 --- a/languages/data/CrhExceptions.php +++ b/languages/data/CrhExceptions.php @@ -126,7 +126,6 @@ class CrhExceptions { 'beyude' => 'бейуде', 'beyüde' => 'бейуде', 'curat' => 'джурьат', 'cürat' => 'джурьат', 'mesul' => 'месуль', 'mesül' => 'месуль', - 'yetsin' => 'етсин', 'etsin' => 'етсин', ]; # map Cyrillic to Latin and back, simple string match only (no regex) @@ -367,7 +366,7 @@ class CrhExceptions { 'козь' => 'köz', '-юнджи' => '-ünci', '-юнджиде' => '-üncide', '-юнджиден' => '-ünciden', # originally L2C, here swapped - 'етсин' => 'etsin', 'льная' => 'lnaya', 'льное' => 'lnoye', 'льный' => 'lnıy', 'льний' => 'lniy', + 'льная' => 'lnaya', 'льное' => 'lnoye', 'льный' => 'lnıy', 'льний' => 'lniy', 'льская' => 'lskaya', 'льский' => 'lskiy', 'льское' => 'lskoye', 'ополь' => 'opol', 'щее' => 'şçeye', 'щий' => 'şçiy', 'щая' => 'şçaya', 'цепс' => 'tseps', @@ -389,8 +388,8 @@ class CrhExceptions { 'му([иэИЭ])' => 'mü$1', # originally L2C, here swapped - 'роль$1' => 'rol([^ü])', - 'усть$1' => 'üst([^ü])', + 'роль$1' => 'rol([^ü]|'.self::WB.')', + 'усть$1' => 'üst([^ü]|'.self::WB.')', # more prefixes 'ком-кок' => 'köm-kök', @@ -460,6 +459,10 @@ class CrhExceptions { '/'.self::WB.'Джонкю'.self::WB.'/u' => 'Cönkü', '/'.self::WB.'ДЖОНКЮ'.self::WB.'/u' => 'CÖNKÜ', + '/'.self::WB.'куркчи/u' => 'kürkçi', + '/'.self::WB.'Куркчи/u' => 'Kürkçi', + '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI', + '/'.self::WB.'устке'.self::WB.'/u' => 'üstke', '/'.self::WB.'Устке'.self::WB.'/u' => 'Üstke', '/'.self::WB.'УСТКЕ'.self::WB.'/u' => 'ÜSTKE', @@ -615,13 +618,21 @@ class CrhExceptions { '/'.self::WB.'Mer'.self::WB.'/u' => 'Мэр', '/'.self::WB.'MER'.self::WB.'/u' => 'МЭР', - '/'.self::WB.'джонк/u' => 'cönk', - '/'.self::WB.'Джонк/u' => 'Cönk', - '/'.self::WB.'ДЖОНК/u' => 'CÖNK', + '/'.self::WB.'cönk/u' => 'джонк', + '/'.self::WB.'Cönk/u' => 'Джонк', + '/'.self::WB.'CÖNK/u' => 'ДЖОНК', - '/'.self::WB.'куркчи/u' => 'kürkçi', - '/'.self::WB.'Куркчи/u' => 'Kürkçi', - '/'.self::WB.'КУРКЧИ/u' => 'KÜRKÇI', + # (y)etsin -> етсин/этсин + # note that target starts with CYRILLIC е/Е! + '/yetsin/u' => 'етсин', + '/Yetsin/u' => 'Етсин', + '/YETSİN/u' => 'ЕТСИН', + + # note that target starts with LATIN e/E! + # (other transformations will determine CYRILLIC е/э as needed) + '/etsin/u' => 'eтсин', + '/Etsin/u' => 'Eтсин', + '/ETSİN/u' => 'EТСИН', # буква Ё - первый заход # расставляем Ь после согласных @@ -666,10 +677,6 @@ class CrhExceptions { '/(['.Crh::L_F.'])l(['.Crh::L_CONS_LC.']|'.self::WB.')/u' => '$1ль$2', '/(['.Crh::L_F_UC.'])L(['.Crh::L_CONS.']|'.self::WB.')/u' => '$1ЛЬ$2', - '/etsin'.self::WB.'/u' => 'етсин', - '/Etsin'.self::WB.'/u' => 'Етсин', - '/ETSİN'.self::WB.'/u' => 'ЕТСИН', - # относятся к началу слова '/'.self::WB.'ts/u' => 'ц', '/'.self::WB.'T[sS]/u' => 'Ц', diff --git a/tests/phpunit/languages/classes/LanguageCrhTest.php b/tests/phpunit/languages/classes/LanguageCrhTest.php index 11c109737d..84a4c46757 100644 --- a/tests/phpunit/languages/classes/LanguageCrhTest.php +++ b/tests/phpunit/languages/classes/LanguageCrhTest.php @@ -7,135 +7,109 @@ */ class LanguageCrhTest extends LanguageClassesTestCase { /** - * @dataProvider provideAutoConvertToAllVariants + * @dataProvider provideAutoConvertToAllVariantsByWord * @covers Language::autoConvertToAllVariants + * + * Test individual words and test minimal contextual transforms + * by creating test strings " " and + * " " and then converting to all variants. */ - public function testAutoConvertToAllVariants( $result, $value ) { + public function testAutoConvertToAllVariantsByWord( $cyrl, $lat ) { + $value = $lat; + $result = [ + 'crh' => $value, + 'crh-cyrl' => $cyrl, + 'crh-latn' => $lat, + ]; + $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) ); + + $value = $cyrl; + $result = [ + 'crh' => $value, + 'crh-cyrl' => $cyrl, + 'crh-latn' => $lat, + ]; + $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) ); + + $value = $cyrl . ' ' . $lat; + $result = [ + 'crh' => $value, + 'crh-cyrl' => $cyrl . ' ' . $cyrl, + 'crh-latn' => $lat . ' ' . $lat, + ]; + $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) ); + + $value = $lat . ' ' . $cyrl; + $result = [ + 'crh' => $value, + 'crh-cyrl' => $cyrl . ' ' . $cyrl, + 'crh-latn' => $lat . ' ' . $lat, + ]; $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) ); } - public static function provideAutoConvertToAllVariants() { + public static function provideAutoConvertToAllVariantsByWord() { + return [ + // general words, covering more of the alphabet + [ 'рузгярнынъ', 'ruzgârnıñ' ], [ 'Париж', 'Parij' ], [ 'чёкюч', 'çöküç' ], + [ 'элифбени', 'elifbeni' ], [ 'полициясы', 'politsiyası' ], [ 'хусусында', 'hususında' ], + [ 'акъшамларны', 'aqşamlarnı' ], [ 'опькеленюв', 'öpkelenüv' ], + [ 'кулюмсиреди', 'külümsiredi' ], [ 'айтмайджагъым', 'aytmaycağım' ], + [ 'козьяшсыз', 'közyaşsız' ], + + // exception words + [ 'инструменталь', 'instrumental' ], [ 'гургуль', 'gürgül' ], [ 'тюшюнмемек', 'tüşünmemek' ], + + // specific problem words + [ 'куню', 'künü' ], [ 'сюргюнлиги', 'sürgünligi' ], [ 'озю', 'özü' ], [ 'этти', 'etti' ], + [ 'эсас', 'esas' ], [ 'дёрт', 'dört' ], [ 'кельди', 'keldi' ], [ 'км²', 'km²' ], + [ 'юзь', 'yüz' ], [ 'АКъШ', 'AQŞ' ], [ 'ШСДжБнен', 'ŞSCBnen' ], [ 'июль', 'iyül' ], + [ 'ишгъаль', 'işğal' ], [ 'ишгъальджилерине', 'işğalcilerine' ], [ 'район', 'rayon' ], + [ 'районынынъ', 'rayonınıñ' ], [ 'Ногъай', 'Noğay' ], [ 'Юрьтю', 'Yürtü' ], + [ 'ватандан', 'vatandan' ], [ 'ком-кок', 'köm-kök' ], [ 'АКЪКЪЫ', 'AQQI' ], + [ 'ДАГЪГЪА', 'DAĞĞA' ], [ '13-юнджи', '13-ünci' ], [ 'ДЖУРЬМЕК', 'CÜRMEK' ], + [ 'джумлеси', 'cümlesi' ], [ 'ильи', 'ilyi' ], [ 'Ильи', 'İlyi' ], [ 'бруцел', 'brutsel' ], + [ 'коцюб', 'kotsüb' ], [ 'плацен', 'platsen' ], [ 'эпицентр', 'epitsentr' ], + + // -tsin- words + [ 'кетсин', 'ketsin' ], [ 'кирлетсин', 'kirletsin' ], [ 'этсин', 'etsin' ], + [ 'етсин', 'yetsin' ], [ 'этсинлерми', 'etsinlermi' ], [ 'принцини', 'printsini' ], + [ 'медицина', 'meditsina' ], [ 'Щетсин', 'Şçetsin' ], [ 'Щекоцины', 'Şçekotsinı' ], + + // regex pattern words + [ 'коюнден', 'köyünden' ], [ 'аньге', 'ange' ], + + // multi part words + [ 'эки юз', 'eki yüz' ], + + // affix patterns + [ 'койнинъ', 'köyniñ' ], [ 'Авджыкойде', 'Avcıköyde' ], [ 'экваториаль', 'ekvatorial' ], + [ 'Джанкой', 'Canköy' ], [ 'усть', 'üst' ], [ 'роль', 'rol' ], [ 'буюк', 'büyük' ], + [ 'джонк', 'cönk' ], + + // Roman numerals vs Initials, part 1 - Roman numeral initials without spaces + [ 'А.Б.Дж.Д.М. Къадырова XII', 'A.B.C.D.M. Qadırova XII' ], + // Roman numerals vs Initials, part 2 - Roman numeral initials with spaces + [ 'Г. Х. Ы. В. X. Л. Меметов III', 'G. H. I. V. X. L. Memetov III' ], + + // ALL CAPS, made up acronyms + [ 'НЪАБ', 'ÑAB' ], [ 'КЪЫДЖ', 'QIC' ], [ 'ГЪУК', 'ĞUK' ], [ 'ДЖОТ', 'COT' ], [ 'ДЖА', 'CA' ], + ]; + } + + /** + * @dataProvider provideAutoConvertToAllVariantsByString + * @covers Language::autoConvertToAllVariants + * + * Run tests that require some context (like Roman numerals) or with + * many-to-one mappings, or other asymmetric results (like smart quotes) + */ + public function testAutoConvertToAllVariantsByString( $result, $value ) { + $this->assertEquals( $result, $this->getLang()->autoConvertToAllVariants( $value ) ); + } + + public static function provideAutoConvertToAllVariantsByString() { return [ - [ // general words, covering more of the alphabet - [ - 'crh' => 'рузгярнынъ ruzgârnıñ Париж Parij', - 'crh-cyrl' => 'рузгярнынъ рузгярнынъ Париж Париж', - 'crh-latn' => 'ruzgârnıñ ruzgârnıñ Parij Parij', - ], - 'рузгярнынъ ruzgârnıñ Париж Parij' - ], - [ // general words, covering more of the alphabet - [ - 'crh' => 'чёкюч çöküç элифбени elifbeni полициясы politsiyası', - 'crh-cyrl' => 'чёкюч чёкюч элифбени элифбени полициясы полициясы', - 'crh-latn' => 'çöküç çöküç elifbeni elifbeni politsiyası politsiyası', - ], - 'чёкюч çöküç элифбени elifbeni полициясы politsiyası' - ], - [ // general words, covering more of the alphabet - [ - 'crh' => 'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv', - 'crh-cyrl' => 'хусусында хусусында акъшамларны акъшамларны опькеленюв опькеленюв', - 'crh-latn' => 'hususında hususında aqşamlarnı aqşamlarnı öpkelenüv öpkelenüv', - ], - 'хусусында hususında акъшамларны aqşamlarnı опькеленюв öpkelenüv' - ], - [ // general words, covering more of the alphabet - [ - 'crh' => 'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız', - 'crh-cyrl' => 'кулюмсиреди кулюмсиреди айтмайджагъым айтмайджагъым козьяшсыз козьяшсыз', - 'crh-latn' => 'külümsiredi külümsiredi aytmaycağım aytmaycağım közyaşsız közyaşsız', - ], - 'кулюмсиреди külümsiredi айтмайджагъым aytmaycağım козьяшсыз közyaşsız' - ], - [ // exception words - [ - 'crh' => 'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek', - 'crh-cyrl' => 'инструменталь инструменталь гургуль гургуль тюшюнмемек тюшюнмемек', - 'crh-latn' => 'instrumental instrumental gürgül gürgül tüşünmemek tüşünmemek', - ], - 'инструменталь instrumental гургуль gürgül тюшюнмемек tüşünmemek' - ], - [ // recent problem words, part 1 - [ - 'crh' => 'künü куню sürgünligi сюргюнлиги özü озю etti этти esas эсас dört дёрт', - 'crh-cyrl' => 'куню куню сюргюнлиги сюргюнлиги озю озю этти этти эсас эсас дёрт дёрт', - 'crh-latn' => 'künü künü sürgünligi sürgünligi özü özü etti etti esas esas dört dört', - ], - 'künü куню sürgünligi сюргюнлиги özü озю etti этти esas эсас dört дёрт' - ], - [ // recent problem words, part 2 - [ - 'crh' => 'keldi кельди km² км² yüz юзь AQŞ АКъШ ŞSCBnen ШСДжБнен iyül июль', - 'crh-cyrl' => 'кельди кельди км² км² юзь юзь АКъШ АКъШ ШСДжБнен ШСДжБнен июль июль', - 'crh-latn' => 'keldi keldi km² km² yüz yüz AQŞ AQŞ ŞSCBnen ŞSCBnen iyül iyül', - ], - 'keldi кельди km² км² yüz юзь AQŞ АКъШ ŞSCBnen ШСДжБнен iyül июль' - ], - [ // recent problem words, part 3 - [ - 'crh' => 'işğal ишгъаль işğalcilerine ишгъальджилерине rayon район üst усть', - 'crh-cyrl' => 'ишгъаль ишгъаль ишгъальджилерине ишгъальджилерине район район усть усть', - 'crh-latn' => 'işğal işğal işğalcilerine işğalcilerine rayon rayon üst üst', - ], - 'işğal ишгъаль işğalcilerine ишгъальджилерине rayon район üst усть' - ], - [ // recent problem words, part 4 - [ - 'crh' => 'rayonınıñ районынынъ Noğay Ногъай Yürtü Юрьтю vatandan ватандан', - 'crh-cyrl' => 'районынынъ районынынъ Ногъай Ногъай Юрьтю Юрьтю ватандан ватандан', - 'crh-latn' => 'rayonınıñ rayonınıñ Noğay Noğay Yürtü Yürtü vatandan vatandan', - ], - 'rayonınıñ районынынъ Noğay Ногъай Yürtü Юрьтю vatandan ватандан' - ], - [ // recent problem words, part 5 - [ - 'crh' => 'ком-кок köm-kök rol роль AQQI АКЪКЪЫ DAĞĞA ДАГЪГЪА 13-ünci 13-юнджи', - 'crh-cyrl' => 'ком-кок ком-кок роль роль АКЪКЪЫ АКЪКЪЫ ДАГЪГЪА ДАГЪГЪА 13-юнджи 13-юнджи', - 'crh-latn' => 'köm-kök köm-kök rol rol AQQI AQQI DAĞĞA DAĞĞA 13-ünci 13-ünci', - ], - 'ком-кок köm-kök rol роль AQQI АКЪКЪЫ DAĞĞA ДАГЪГЪА 13-ünci 13-юнджи' - ], - [ // recent problem words, part 6 - [ - 'crh' => 'ДЖУРЬМЕК CÜRMEK кетсин ketsin джумлеси cümlesi ильи ilyi Ильи İlyi', - 'crh-cyrl' => 'ДЖУРЬМЕК ДЖУРЬМЕК кетсин кетсин джумлеси джумлеси ильи ильи Ильи Ильи', - 'crh-latn' => 'CÜRMEK CÜRMEK ketsin ketsin cümlesi cümlesi ilyi ilyi İlyi İlyi', - ], - 'ДЖУРЬМЕК CÜRMEK кетсин ketsin джумлеси cümlesi ильи ilyi Ильи İlyi' - ], - [ // recent problem words, part 7 - [ - 'crh' => 'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr', - 'crh-cyrl' => 'бруцел бруцел коцюб коцюб плацен плацен эпицентр эпицентр', - 'crh-latn' => 'brutsel brutsel kotsüb kotsüb platsen platsen epitsentr epitsentr', - ], - 'бруцел brutsel коцюб kotsüb плацен platsen эпицентр epitsentr' - ], - [ // regex pattern words - [ - 'crh' => 'köyünden коюнден ange аньге', - 'crh-cyrl' => 'коюнден коюнден аньге аньге', - 'crh-latn' => 'köyünden köyünden ange ange', - ], - 'köyünden коюнден ange аньге' - ], - [ // multi part words - [ - 'crh' => 'эки юз eki yüz', - 'crh-cyrl' => 'эки юз эки юз', - 'crh-latn' => 'eki yüz eki yüz', - ], - 'эки юз eki yüz' - ], - [ // affix patterns - [ - 'crh' => 'köyniñ койнинъ Avcıköyde Авджыкойде ekvatorial экваториаль Canköy Джанкой', - 'crh-cyrl' => 'койнинъ койнинъ Авджыкойде Авджыкойде экваториаль экваториаль Джанкой Джанкой', - 'crh-latn' => 'köyniñ köyniñ Avcıköyde Avcıköyde ekvatorial ekvatorial Canköy Canköy', - ], - 'köyniñ койнинъ Avcıköyde Авджыкойде ekvatorial экваториаль Canköy Джанкой' - ], [ // Roman numerals and quotes, esp. single-letter Roman numerals at the end of a string [ 'crh' => 'VI,VII IX “dört” «дёрт» XI XII I V X L C D M', @@ -144,30 +118,6 @@ class LanguageCrhTest extends LanguageClassesTestCase { ], 'VI,VII IX “dört” «дёрт» XI XII I V X L C D M' ], - [ // Roman numerals vs Initials, part 1 - Roman numeral initials without spaces - [ - 'crh' => 'A.B.C.D.M. Qadırova XII, А.Б.Дж.Д.М. Къадырова XII', - 'crh-cyrl' => 'А.Б.Дж.Д.М. Къадырова XII, А.Б.Дж.Д.М. Къадырова XII', - 'crh-latn' => 'A.B.C.D.M. Qadırova XII, A.B.C.D.M. Qadırova XII', - ], - 'A.B.C.D.M. Qadırova XII, А.Б.Дж.Д.М. Къадырова XII' - ], - [ // Roman numerals vs Initials, part 2 - Roman numeral initials with spaces - [ - 'crh' => 'G. H. I. V. X. L. Memetov III, Г. Х. Ы. В. X. Л. Меметов III', - 'crh-cyrl' => 'Г. Х. Ы. В. X. Л. Меметов III, Г. Х. Ы. В. X. Л. Меметов III', - 'crh-latn' => 'G. H. I. V. X. L. Memetov III, G. H. I. V. X. L. Memetov III', - ], - 'G. H. I. V. X. L. Memetov III, Г. Х. Ы. В. X. Л. Меметов III' - ], - [ // ALL CAPS, made up acronyms - [ - 'crh' => 'ÑAB QIC ĞUK COT НЪАБ КЪЫДЖ ГЪУК ДЖОТ CA ДЖА', - 'crh-cyrl' => 'НЪАБ КЪЫДЖ ГЪУК ДЖОТ НЪАБ КЪЫДЖ ГЪУК ДЖОТ ДЖА ДЖА', - 'crh-latn' => 'ÑAB QIC ĞUK COT ÑAB QIC ĞUK COT CA CA', - ], - 'ÑAB QIC ĞUK COT НЪАБ КЪЫДЖ ГЪУК ДЖОТ CA ДЖА' - ], [ // Many-to-one mappings: many Cyrillic to one Latin [ 'crh' => 'шофер шофёр şoför корбекул корьбекул корьбекуль körbekül', -- 2.20.1