package lang_test import ( "strings" "testing" "git.vakhrushev.me/av/convy/internal/lang" ) func TestLeadTakesLongestMatch(t *testing.T) { v, err := lang.Lookup(1, "ru") if err != nil { t.Fatal(err) } cases := []struct { text string want string }{ {"ДОЛЖЕН.", "ДОЛЖЕН"}, {"НЕ ДОЛЖЕН.", "НЕ ДОЛЖЕН"}, {"НЕ СЛЕДУЕТ.", "НЕ СЛЕДУЕТ"}, {"СЛЕДУЕТ.", "СЛЕДУЕТ"}, {"СНЯТО 2026-07-26.", "СНЯТО"}, {"ПОЧЕМУ.", "ПОЧЕМУ"}, {"", ""}, {"Заголовок правила", ""}, {"ДОЛЖЕНСТВОВАНИЕ", ""}, } for _, tc := range cases { got, ok := v.Lead(tc.text) if tc.want == "" { if ok { t.Errorf("Lead(%q) = %q, wanted no word to be found", tc.text, got) } continue } if !ok || got != tc.want { t.Errorf("Lead(%q) = %q, %v; wanted %q", tc.text, got, ok, tc.want) } } } func TestForeignExcludesOwnWords(t *testing.T) { foreign := lang.Foreign(1, "ru") if len(foreign) == 0 { t.Fatal("the Russian vocabulary yielded no foreign word at all") } if code, ok := foreign["MUST"]; !ok || code != "en" { t.Errorf("MUST should be recognized as a word of the en vocabulary, got %q, %v", code, ok) } v, err := lang.Lookup(1, "ru") if err != nil { t.Fatal(err) } for word := range foreign { if _, own := v.Modal(word); own { t.Errorf("the word %q is the suite's own, yet landed among the foreign ones", word) } if _, own := v.Mark(word); own { t.Errorf("the mark %q is the suite's own, yet landed among the foreign ones", word) } } } func TestUnknownVersionAndCode(t *testing.T) { if _, err := lang.Lookup(99, "ru"); err == nil { t.Error("an unknown language version was accepted without an error") } if _, err := lang.Lookup(1, "xx"); err == nil { t.Error("an unknown vocabulary was accepted without an error") } } // A copy in a consuming repository carries no manifest, so the only thing that // says which words of it are normative is the line it names the language by. func TestRecognizeReadsTheLanguageOffTheVersionLine(t *testing.T) { ru, err := lang.Lookup(1, "ru") if err != nil { t.Fatal(err) } en, err := lang.Lookup(1, "en") if err != nil { t.Fatal(err) } for _, want := range []lang.Vocabulary{ru, en} { got, ok := lang.Recognize(want.VersionLine()) if !ok { t.Fatalf("the version line of %q was not recognized", want.Code) } if got.Code != want.Code || got.Version != want.Version { t.Errorf("read as %q version %d, expected %q version %d", got.Code, got.Version, want.Code, want.Version) } } if _, ok := lang.Recognize("Обычная проза, ничего не объявляющая."); ok { t.Errorf("prose naming no words passed for a version line") } } // Words say which natural language, the number says which version. One without // the other names no vocabulary: two versions of the same language would be // told apart by nothing at all. func TestRecognizeNeedsTheVersionToAgree(t *testing.T) { ru, err := lang.Lookup(1, "ru") if err != nil { t.Fatal(err) } line := ru.VersionLine() if _, ok := lang.Recognize(line); !ok { t.Fatalf("the line the tool itself writes was not recognized") } wrong := strings.Replace(line, "версии 1", "версии 7", 1) if wrong == line { t.Fatal("the fixture did not change the version") } if v, ok := lang.Recognize(wrong); ok { t.Errorf("a line naming version 7 was read as version %d (%s)", v.Version, v.Code) } }