package morph import "testing" // TestVerbFormsAreVerbs — the question internal/router/singletoken.go asks. Every // one of these is a whole sentence in Russian, because the verb carries its own // subject, tense and gender. func TestVerbFormsAreVerbs(t *testing.T) { if !Available() { t.Skip("russian dictionary unavailable") } for _, w := range []string{ "поужинал", "сходил", "выпил", "напомнил", "поняла", "сделала", "пришёл", "начал", "работаешь", "занимаюсь", // Reflexive: the lemma keeps its particle, so "тренироваться" ends in // "ся" and not "ть". That is why the ending list carries both. "тренировался", "проснулся", } { if !IsVerbForm(w) { t.Errorf("IsVerbForm(%q) = false, want true (lemma %q)", w, Lemma(w)) } } } // TestNounsEndingInLAreNotVerbs — the list this package deleted. Nineteen nouns // lived in internal/phraser/eval/checks.go as exceptions to "ends in л means // masculine past tense", plus the ones internal/router/singletoken.go named as // its own known errors. A list of exceptions to a pattern is the pattern // conceding it is wrong, so all of them are here and none may be a verb. func TestNounsEndingInLAreNotVerbs(t *testing.T) { if !Available() { t.Skip("russian dictionary unavailable") } for _, w := range []string{ "стол", "стул", "пол", "зал", "гол", "узел", "отдел", "файл", "канал", "угол", "футбол", "вокзал", "металл", "интервал", "уровень", "мускул", "апрель", "июль", "рубль", // singletoken.go named these: "канал" read as past tense, and short // nouns needed a length exemption to survive a two-letter suffix test. "нос", "лес", "газ", "вода", "бэкап", } { if IsVerbForm(w) { t.Errorf("IsVerbForm(%q) = true, want false (lemma %q)", w, Lemma(w)) } } } // TestSameWordDrawsTheLineTheEndingListCouldNot — the question // cmd/mavend/quiet_toggle.go asks. Its comment describes exactly this: "тихий", // "тихом" and "тихо" are one word inflected, while "тихонько" and "потихоньку" // are different words. The dictionary says so; a list of 36 endings approximated // it. func TestSameWordDrawsTheLineTheEndingListCouldNot(t *testing.T) { if !Available() { t.Skip("russian dictionary unavailable") } for _, w := range []string{"тихий", "тихом", "тихо", "тише"} { if !SameWord(w, "тихий") { t.Errorf("SameWord(%q, тихий) = false, want true (lemma %q)", w, Lemma(w)) } } for _, w := range []string{"тихонько", "потихоньку"} { if SameWord(w, "тихий") { t.Errorf("SameWord(%q, тихий) = true, want false", w) } } for _, w := range []string{"режим", "режима", "режиме", "режимы"} { if !SameWord(w, "режим") { t.Errorf("SameWord(%q, режим) = false, want true (lemma %q)", w, Lemma(w)) } } if SameWord("режим", "тихий") { t.Error("SameWord matched two unrelated words") } } // TestUnknownWordIsItsOwnLemma — "бэкап" is not in the dictionary, and there is // nothing better to say about it than what he said. Two spellings of an unknown // word still compare equal, which is what the exact-equality fallback rests on. func TestUnknownWordIsItsOwnLemma(t *testing.T) { if got := Lemma("бэкап"); got != "бэкап" { t.Errorf("Lemma(бэкап) = %q, want бэкап", got) } if got := Lemma(" БЭКАП "); got != "бэкап" { t.Errorf("Lemma trims and lowercases: got %q", got) } if !SameWord("бэкап", "БЭКАП") { t.Error("SameWord must still compare an unknown word with itself") } if got := Lemma(""); got != "" { t.Errorf("Lemma(empty) = %q, want empty", got) } if SameWord("", "") { t.Error("two empty tokens are not a word") } }