NounDeclensionTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. <?php
  2. namespace morphos\test\Russian;
  3. use morphos\Gender;
  4. use morphos\Russian\NounDeclension;
  5. use PHPUnit\Framework\TestCase;
  6. class NounDeclensionTest extends TestCase
  7. {
  8. /**
  9. * @dataProvider wordsProvider
  10. */
  11. public function testDeclensionDetect($word, $animateness, $declension)
  12. {
  13. // skip word if it does not have declension
  14. if ($declension === null) {
  15. static::markTestSkipped('skip word if it does not have declension');
  16. }
  17. $this->assertEquals($declension, NounDeclension::getDeclension($word));
  18. }
  19. /**
  20. * @dataProvider wordsProvider
  21. */
  22. public function testInflection($word, $animateness, $declension, $inflected)
  23. {
  24. $this->assertEquals($inflected, array_values(NounDeclension::getCases($word, $animateness)));
  25. }
  26. public function wordsProvider()
  27. {
  28. return [
  29. // 1 - Женский, мужской род с окончанием [а, я].
  30. // 2 - Мужской рода с нулевым или окончанием [о, е],
  31. // 2 - Среднего рода с окончанием [о, е].
  32. // 3 - Женский род на мягкий и щипящий согласный.
  33. ['молния', false, 1, ['молния', 'молнии', 'молние', 'молнию', 'молнией', 'молние']],
  34. ['папа', true, 1, ['папа', 'папы', 'папе', 'папу', 'папой', 'папе']],
  35. ['слава', false, 1, ['слава', 'славы', 'славе', 'славу', 'славой', 'славе']],
  36. ['пустыня', false, 1, ['пустыня', 'пустыни', 'пустыне', 'пустыню', 'пустыней', 'пустыне']],
  37. ['вилка', false, 1, ['вилка', 'вилки', 'вилке', 'вилку', 'вилкой', 'вилке']],
  38. ['тысяча', false, 1, ['тысяча', 'тысячи', 'тысяче', 'тысячу', 'тысячей', 'тысяче']],
  39. ['копейка', false, 1, ['копейка', 'копейки', 'копейке', 'копейку', 'копейкой', 'копейке']],
  40. ['батарейка', false, 1, ['батарейка', 'батарейки', 'батарейке', 'батарейку', 'батарейкой', 'батарейке']],
  41. ['гривна', false, 1, ['гривна', 'гривны', 'гривне', 'гривну', 'гривной', 'гривне']],
  42. ['фабрика', false, 1, ['фабрика', 'фабрики', 'фабрике', 'фабрику', 'фабрикой', 'фабрике']],
  43. ['дом', false, 2, ['дом', 'дома', 'дому', 'дом', 'домом', 'доме']],
  44. ['поле', false, 2, ['поле', 'поля', 'полю', 'поле', 'полем', 'поле']],
  45. ['кирпич', false, 2, ['кирпич', 'кирпича', 'кирпичу', 'кирпич', 'кирпичем', 'кирпиче']],
  46. ['дерево', false, 2, ['дерево', 'дерева', 'дереву', 'дерево', 'деревом', 'дереве']],
  47. ['склон', false, 2, ['склон', 'склона', 'склону', 'склон', 'склоном', 'склоне']],
  48. ['сообщение', false, 2, ['сообщение', 'сообщения', 'сообщению', 'сообщение', 'сообщением', 'сообщении']],
  49. ['общение', false, 2, ['общение', 'общения', 'общению', 'общение', 'общением', 'общении']],
  50. [
  51. 'воскрешение',
  52. false,
  53. 2,
  54. ['воскрешение', 'воскрешения', 'воскрешению', 'воскрешение', 'воскрешением', 'воскрешении'],
  55. ],
  56. ['доллар', false, 2, ['доллар', 'доллара', 'доллару', 'доллар', 'долларом', 'долларе']],
  57. ['евро', false, 2, ['евро', 'евро', 'евро', 'евро', 'евро', 'евро']],
  58. ['колье', false, 2, ['колье', 'колье', 'колье', 'колье', 'колье', 'колье']],
  59. ['фунт', false, 2, ['фунт', 'фунта', 'фунту', 'фунт', 'фунтом', 'фунте']],
  60. ['человек', true, 2, ['человек', 'человека', 'человеку', 'человека', 'человеком', 'человеке']],
  61. ['год', false, 2, ['год', 'года', 'году', 'год', 'годом', 'годе']],
  62. ['месяц', false, 2, ['месяц', 'месяца', 'месяцу', 'месяц', 'месяцем', 'месяце']],
  63. ['бремя', false, 2, ['бремя', 'бремени', 'бремени', 'бремя', 'бременем', 'бремени']],
  64. ['дитя', false, 2, ['дитя', 'дитяти', 'дитяти', 'дитя', 'дитятей', 'дитяти']],
  65. ['путь', false, 2, ['путь', 'пути', 'пути', 'путь', 'путем', 'пути']],
  66. ['поселок', false, 2, ['поселок', 'поселка', 'поселку', 'поселок', 'поселком', 'поселке']],
  67. ['пирсинг', false, 2, ['пирсинг', 'пирсинга', 'пирсингу', 'пирсинг', 'пирсингом', 'пирсинге']],
  68. ['столбец', false, 2, ['столбец', 'столбца', 'столбцу', 'столбец', 'столбцом', 'столбце']],
  69. ['гений', true, 2, ['гений', 'гения', 'гению', 'гения', 'гением', 'гении']],
  70. ['ястреб', true, 2, ['ястреб', 'ястреба', 'ястребу', 'ястреба', 'ястребом', 'ястребе']],
  71. ['карандаш', false, 2, ['карандаш', 'карандаша', 'карандашу', 'карандаш', 'карандашом', 'карандаше']],
  72. ['вкладыш', false, 2, ['вкладыш', 'вкладыша', 'вкладышу', 'вкладыш', 'вкладышом', 'вкладыше']],
  73. ['товарищ', false, 2, ['товарищ', 'товарища', 'товарищу', 'товарищ', 'товарищем', 'товарище']],
  74. [
  75. 'руководитель',
  76. true,
  77. 2,
  78. ['руководитель', 'руководителя', 'руководителю', 'руководителя', 'руководителем', 'руководителе'],
  79. ],
  80. [
  81. 'председатель',
  82. true,
  83. 2,
  84. ['председатель', 'председателя', 'председателю', 'председателя', 'председателем', 'председателе'],
  85. ],
  86. [
  87. 'библиотекарь',
  88. true,
  89. 2,
  90. ['библиотекарь', 'библиотекаря', 'библиотекарю', 'библиотекаря', 'библиотекарем', 'библиотекаре'],
  91. ],
  92. ['санузел', false, 2, ['санузел', 'санузла', 'санузлу', 'санузел', 'санузлом', 'санузле']],
  93. ['урок', false, 2, ['урок', 'урока', 'уроку', 'урок', 'уроком', 'уроке']],
  94. // сущ мужского рода с мягким окончанием
  95. ['гвоздь', false, 2, ['гвоздь', 'гвоздя', 'гвоздю', 'гвоздь', 'гвоздем', 'гвозде']],
  96. ['день', false, 2, ['день', 'дня', 'дню', 'день', 'днем', 'дне']],
  97. ['камень', false, 2, ['камень', 'камня', 'камню', 'камень', 'камнем', 'камне']],
  98. ['рубль', false, 2, ['рубль', 'рубля', 'рублю', 'рубль', 'рублем', 'рубле']],
  99. ['любитель', true, 2, ['любитель', 'любителя', 'любителю', 'любителя', 'любителем', 'любителе']],
  100. // увеличительная форма
  101. ['волчище', true, 2, ['волчище', 'волчища', 'волчищу', 'волчище', 'волчищем', 'волчище']],
  102. ['полотнище', false, 2, ['полотнище', 'полотнища', 'полотнищу', 'полотнище', 'полотнищем', 'полотнище']],
  103. // уменьшительная форма
  104. ['волчок', false, 2, ['волчок', 'волчка', 'волчку', 'волчок', 'волчком', 'волчке']],
  105. ['котёнок', true, 2, ['котёнок', 'котёнка', 'котёнку', 'котёнка', 'котёнком', 'котёнке']],
  106. ['станок', false, 2, ['станок', 'станка', 'станку', 'станок', 'станком', 'станке']],
  107. [
  108. 'комментарий',
  109. false,
  110. 2,
  111. ['комментарий', 'комментария', 'комментарию', 'комментарий', 'комментарием', 'комментарии'],
  112. ],
  113. ['ночь', false, 3, ['ночь', 'ночи', 'ночи', 'ночь', 'ночью', 'ночи']],
  114. ['новость', false, 3, ['новость', 'новости', 'новости', 'новость', 'новостью', 'новости']],
  115. // Адъективное склонение (от прилагательных и причастий)
  116. // мужской род
  117. ['выходной', false, null, ['выходной', 'выходного', 'выходному', 'выходной', 'выходным', 'выходном']],
  118. [
  119. 'двугривенный',
  120. false,
  121. null,
  122. ['двугривенный', 'двугривенного', 'двугривенному', 'двугривенный', 'двугривенным', 'двугривенном'],
  123. ],
  124. ['рабочий', false, null, ['рабочий', 'рабочего', 'рабочему', 'рабочего', 'рабочим', 'рабочем']],
  125. // средний род
  126. ['животное', true, null, ['животное', 'животного', 'животному', 'животное', 'животным', 'животном']],
  127. [
  128. 'подлежащее',
  129. false,
  130. null,
  131. ['подлежащее', 'подлежащего', 'подлежащему', 'подлежащее', 'подлежащим', 'подлежащем'],
  132. ],
  133. // женский род
  134. ['запятая', false, null, ['запятая', 'запятой', 'запятой', 'запятую', 'запятой', 'запятой']],
  135. ['горничная', true, null, ['горничная', 'горничной', 'горничной', 'горничную', 'горничной', 'горничной']],
  136. [
  137. 'заведующая',
  138. true,
  139. null,
  140. ['заведующая', 'заведующей', 'заведующей', 'заведующую', 'заведующей', 'заведующей'],
  141. ],
  142. // Отглагольные существительные среднего рода (варенье, печенье и т.д.)
  143. ['варенье', true, null, ['варенье', 'варенья', 'варенью', 'варенье', 'вареньем', 'варенье']],
  144. ];
  145. }
  146. /**
  147. * @dataProvider immutableWordsProvider
  148. */
  149. public function testImmutableWords($word)
  150. {
  151. $this->assertFalse(NounDeclension::isMutable($word, false));
  152. }
  153. public function immutableWordsProvider()
  154. {
  155. return [
  156. ['авеню'],
  157. ['атташе'],
  158. ['бюро'],
  159. ['вето'],
  160. ['денди'],
  161. ['депо'],
  162. ['жалюзи'],
  163. ['желе'],
  164. ['жюри'],
  165. ['интервью'],
  166. ['какаду'],
  167. ['какао'],
  168. ['кафе'],
  169. ['кашне'],
  170. ['кенгуру'],
  171. ['кино'],
  172. ['клише'],
  173. ['кольраби'],
  174. ['колье'],
  175. ['коммюнике'],
  176. ['конферансье'],
  177. ['кофе'],
  178. ['купе'],
  179. ['леди'],
  180. ['меню'],
  181. ['метро'],
  182. ['пальто'],
  183. ['пенсне'],
  184. ['пианино'],
  185. ['плато'],
  186. ['портмоне'],
  187. ['рагу'],
  188. ['радио'],
  189. ['самбо'],
  190. ['табло'],
  191. ['такси'],
  192. ['трюмо'],
  193. ['фортепиано'],
  194. ['шимпанзе'],
  195. ['шоссе'],
  196. ['эскимо'],
  197. ['галифе'],
  198. ['монпансье'],
  199. ];
  200. }
  201. /**
  202. * @dataProvider gendersProvider()
  203. */
  204. public function testGenderDetection($word, $gender)
  205. {
  206. $this->assertEquals($gender, NounDeclension::detectGender($word));
  207. }
  208. public function gendersProvider()
  209. {
  210. return [
  211. ['вилка', Gender::FEMALE],
  212. ['копейка', Gender::FEMALE],
  213. ['кирпич', Gender::MALE],
  214. ['рубль', Gender::MALE],
  215. ['волчище', Gender::NEUTER],
  216. ['бремя', Gender::NEUTER],
  217. ['человек', Gender::MALE],
  218. ['новость', Gender::FEMALE],
  219. ];
  220. }
  221. }