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")
	}
}
