Skip to content

Commit

Permalink
Fix #60 (ordinal for 40), fix #59 (words ending with *ш)
Browse files Browse the repository at this point in the history
  • Loading branch information
wapmorgan committed Nov 18, 2019
1 parent de177b3 commit 5170282
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 29 deletions.
16 changes: 11 additions & 5 deletions src/Russian/NounDeclension.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,16 @@ public static function declinateSecondDeclension($word, $animateness = false)
{
$word = S::lower($word);
$last = S::slice($word, -1);
$soft_last = $last === 'й' || (in_array($last, ['ь', 'е', 'ё', 'ю', 'я'], true)
&& ((
static::isConsonant(S::slice($word, -2, -1)) && !static::isHissingConsonant(S::slice($word, -2, -1)))
|| S::slice($word, -2, -1) === 'и'));
$soft_last = $last === 'й'
|| (
in_array($last, ['ь', 'е', 'ё', 'ю', 'я'], true)
&& (
(
static::isConsonant(S::slice($word, -2, -1))
&& !static::isHissingConsonant(S::slice($word, -2, -1))
)
|| S::slice($word, -2, -1) === 'и')
);
$prefix = static::getPrefixOfSecondDeclension($word, $last);
$forms = [
Cases::IMENIT => $word,
Expand All @@ -286,7 +292,7 @@ public static function declinateSecondDeclension($word, $animateness = false)
// $forms[Cases::TVORIT] = $prefix.'ем';
// else
// $forms[Cases::TVORIT] = $prefix.'ом'; # http://morpher.ru/Russian/Spelling.aspx#sibilant
if (static::isHissingConsonant($last)
if ((static::isHissingConsonant($last) && $last !== 'ш')
|| (in_array($last, ['ь', 'е', 'ё', 'ю', 'я'], true) && static::isHissingConsonant(S::slice($word, -2, -1)))
|| ($last === 'ц' && S::slice($word, -2) !== 'ец')) {
$forms[Cases::TVORIT] = $prefix.'ем';
Expand Down
6 changes: 3 additions & 3 deletions src/Russian/OrdinalNumeralGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public static function getCases($number, $gender = self::MALE)
} else {
switch ($gender) {
case static::MALE:
$prefix = S::slice($word, 0, $number == 40 ? -1 : -2);
$prefix = S::slice($word, 0, -2);
return [
static::IMENIT => $word,
static::RODIT => $prefix.'ого',
Expand All @@ -133,7 +133,7 @@ public static function getCases($number, $gender = self::MALE)
];

case static::FEMALE:
$prefix = S::slice($word, 0, $number == 40 ? -1 : -2);
$prefix = S::slice($word, 0, -2);
return [
static::IMENIT => $prefix.'ая',
static::RODIT => $prefix.'ой',
Expand All @@ -144,7 +144,7 @@ public static function getCases($number, $gender = self::MALE)
];

case static::NEUTER:
$prefix = S::slice($word, 0, $number == 40 ? -1 : -2);
$prefix = S::slice($word, 0, -2);
return [
static::IMENIT => $prefix.'ое',
static::RODIT => $prefix.'ого',
Expand Down
2 changes: 1 addition & 1 deletion src/Russian/RussianLanguage.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ public static function choosePrepositionByFirstLetter($word, $prepositionWithVow
*/
public static function chooseVowelAfterConsonant($last, $softLast, $afterSoft, $afterHard)
{
if ((RussianLanguage::isHissingConsonant($last) && !in_array($last, ['ж', 'ч'], true)) || /*static::isVelarConsonant($last) ||*/ $softLast) {
if ($last === 'щ' || /*static::isVelarConsonant($last) ||*/ $softLast) {
return $afterSoft;
} else {
return $afterHard;
Expand Down
2 changes: 2 additions & 0 deletions tests/Russian/NounDeclensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public function wordsProvider()
['столбец', false, 2, ['столбец', 'столбца', 'столбцу', 'столбец', 'столбцом', 'столбце']],
['гений', true, 2, ['гений', 'гения', 'гению', 'гения', 'гением', 'гении']],
['ястреб', true, 2, ['ястреб', 'ястреба', 'ястребу', 'ястреба', 'ястребом', 'ястребе']],
['карандаш', false, 2, ['карандаш', 'карандаша', 'карандашу', 'карандаш', 'карандашом', 'карандаше']],
['вкладыш', false, 2, ['вкладыш', 'вкладыша', 'вкладышу', 'вкладыш', 'вкладышом', 'вкладыше']],
['руководитель', true, 2, ['руководитель', 'руководителя', 'руководителю', 'руководителя', 'руководителем', 'руководителе']],
['председатель', true, 2, ['председатель', 'председателя', 'председателю', 'председателя', 'председателем', 'председателе']],
['библиотекарь', true, 2, ['библиотекарь', 'библиотекаря', 'библиотекарю', 'библиотекаря', 'библиотекарем', 'библиотекаре']],
Expand Down
42 changes: 22 additions & 20 deletions tests/Russian/OrdinalNumeralTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,38 @@ public function testGetCases($number, $gender, $case, $case2, $case3, $case4, $c

public function numbersProvider()
{
return array(
array(1, NumeralGenerator::MALE, 'первый', 'первого', 'первому', 'первый', 'первым', 'первом'),
array(1, NumeralGenerator::FEMALE, 'первая', 'первой', 'первой', 'первую', 'первой', 'первой'),
array(3, NumeralGenerator::MALE, 'третий', 'третьего', 'третьему', 'третьего', 'третьим', 'третьем'),
array(13, NumeralGenerator::MALE, 'тринадцатый', 'тринадцатого', 'тринадцатому', 'тринадцатый', 'тринадцатым', 'тринадцатом'),
array(20, NumeralGenerator::NEUTER, 'двадцатое', 'двадцатого', 'двадцатому', 'двадцатое', 'двадцатым', 'двадцатом'),
array(113, NumeralGenerator::MALE, 'сто тринадцатый', 'сто тринадцатого', 'сто тринадцатому', 'сто тринадцатый', 'сто тринадцатым', 'сто тринадцатом'),
array(201, NumeralGenerator::MALE, 'двести первый', 'двести первого', 'двести первому', 'двести первый', 'двести первым', 'двести первом'),
array(344, NumeralGenerator::MALE, 'триста сорок четвертый', 'триста сорок четвертого', 'триста сорок четвертому', 'триста сорок четвертый', 'триста сорок четвертым', 'триста сорок четвертом'),
array(1007, NumeralGenerator::MALE, 'тысяча седьмой', 'тысяча седьмого', 'тысяча седьмому', 'тысяча седьмой', 'тысяча седьмым', 'тысяча седьмом'),
array(1013, NumeralGenerator::MALE, 'тысяча тринадцатый', 'тысяча тринадцатого', 'тысяча тринадцатому', 'тысяча тринадцатый', 'тысяча тринадцатым', 'тысяча тринадцатом'),
array(3651, NumeralGenerator::MALE, 'три тысячи шестьсот пятьдесят первый', 'три тысячи шестьсот пятьдесят первого', 'три тысячи шестьсот пятьдесят первому', 'три тысячи шестьсот пятьдесят первый', 'три тысячи шестьсот пятьдесят первым', 'три тысячи шестьсот пятьдесят первом'),
array(9999, NumeralGenerator::MALE, 'девять тысяч девятьсот девяносто девятый', 'девять тысяч девятьсот девяносто девятого', 'девять тысяч девятьсот девяносто девятому', 'девять тысяч девятьсот девяносто девятый', 'девять тысяч девятьсот девяносто девятым', 'девять тысяч девятьсот девяносто девятом'),
array(27013, NumeralGenerator::MALE, 'двадцать семь тысяч тринадцатый', 'двадцать семь тысяч тринадцатого', 'двадцать семь тысяч тринадцатому', 'двадцать семь тысяч тринадцатый', 'двадцать семь тысяч тринадцатым', 'двадцать семь тысяч тринадцатом'),
array(1234567890, NumeralGenerator::MALE,
return [
[1, NumeralGenerator::MALE, 'первый', 'первого', 'первому', 'первый', 'первым', 'первом'],
[1, NumeralGenerator::FEMALE, 'первая', 'первой', 'первой', 'первую', 'первой', 'первой'],
[3, NumeralGenerator::MALE, 'третий', 'третьего', 'третьему', 'третьего', 'третьим', 'третьем'],
[13, NumeralGenerator::MALE, 'тринадцатый', 'тринадцатого', 'тринадцатому', 'тринадцатый', 'тринадцатым', 'тринадцатом'],
[20, NumeralGenerator::NEUTER, 'двадцатое', 'двадцатого', 'двадцатому', 'двадцатое', 'двадцатым', 'двадцатом'],
[40, NumeralGenerator::NEUTER, 'сороковое', 'сорокового', 'сороковому', 'сороковое', 'сороковым', 'сороковом'],
[113, NumeralGenerator::MALE, 'сто тринадцатый', 'сто тринадцатого', 'сто тринадцатому', 'сто тринадцатый', 'сто тринадцатым', 'сто тринадцатом'],
[201, NumeralGenerator::MALE, 'двести первый', 'двести первого', 'двести первому', 'двести первый', 'двести первым', 'двести первом'],
[344, NumeralGenerator::MALE, 'триста сорок четвертый', 'триста сорок четвертого', 'триста сорок четвертому', 'триста сорок четвертый', 'триста сорок четвертым', 'триста сорок четвертом'],
[1007, NumeralGenerator::MALE, 'тысяча седьмой', 'тысяча седьмого', 'тысяча седьмому', 'тысяча седьмой', 'тысяча седьмым', 'тысяча седьмом'],
[1013, NumeralGenerator::MALE, 'тысяча тринадцатый', 'тысяча тринадцатого', 'тысяча тринадцатому', 'тысяча тринадцатый', 'тысяча тринадцатым', 'тысяча тринадцатом'],
[3651, NumeralGenerator::MALE, 'три тысячи шестьсот пятьдесят первый', 'три тысячи шестьсот пятьдесят первого', 'три тысячи шестьсот пятьдесят первому', 'три тысячи шестьсот пятьдесят первый', 'три тысячи шестьсот пятьдесят первым', 'три тысячи шестьсот пятьдесят первом'],
[9999, NumeralGenerator::MALE, 'девять тысяч девятьсот девяносто девятый', 'девять тысяч девятьсот девяносто девятого', 'девять тысяч девятьсот девяносто девятому', 'девять тысяч девятьсот девяносто девятый', 'девять тысяч девятьсот девяносто девятым', 'девять тысяч девятьсот девяносто девятом'],
[27013, NumeralGenerator::MALE, 'двадцать семь тысяч тринадцатый', 'двадцать семь тысяч тринадцатого', 'двадцать семь тысяч тринадцатому', 'двадцать семь тысяч тринадцатый', 'двадцать семь тысяч тринадцатым', 'двадцать семь тысяч тринадцатом'],
[1234567890, NumeralGenerator::MALE,
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностый',
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностого',
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностому',
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностый',
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностым',
'один миллиард двести тридцать четыре миллиона пятьсот шестьдесят семь тысяч восемьсот девяностом',
),
array(1000, NumeralGenerator::MALE, 'тысячный', 'тысячного', 'тысячному', 'тысячный', 'тысячным', 'тысячном'),
array(1000000000, NumeralGenerator::MALE, 'миллиардный', 'миллиардного', 'миллиардному', 'миллиардный', 'миллиардным', 'миллиардном'),
array(1000000090, NumeralGenerator::MALE, 'миллиард девяностый', 'миллиард девяностого', 'миллиард девяностому', 'миллиард девяностый', 'миллиард девяностым', 'миллиард девяностом'),
);
],
[1000, NumeralGenerator::MALE, 'тысячный', 'тысячного', 'тысячному', 'тысячный', 'тысячным', 'тысячном'],
[1000000000, NumeralGenerator::MALE, 'миллиардный', 'миллиардного', 'миллиардному', 'миллиардный', 'миллиардным', 'миллиардном'],
[1000000090, NumeralGenerator::MALE, 'миллиард девяностый', 'миллиард девяностого', 'миллиард девяностому', 'миллиард девяностый', 'миллиард девяностым', 'миллиард девяностом'],
];
}

/**
* @dataProvider numbersProvider()
* @throws \Exception
*/
public function testGetCase($number, $gender, $case, $case2)
{
Expand Down

0 comments on commit 5170282

Please sign in to comment.