- документ самоуправления объявляется ключом governance, а не угадывается по «он один и без ключей оси»: конвенция, потерявшая topic, была от него неотличима и тихо теряла все проверки об отъезде к потребителю - проверка путей канона больше не ловит README.md и READING.md — эти два имени значат что-то и на стороне потребителя - lang.Recognize требует совпадения и слов, и номера версии; директории компонентов сверяются на вложенность, а не только на равенство - у обеих проверок появился --json, а convy sync называет ссылки на темы, которых компонент не взял
126 lines
3.4 KiB
Go
126 lines
3.4 KiB
Go
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)
|
|
}
|
|
}
|