package i18n import ( "net/http" "strings" "testing" ) func TestTKnownMessage(t *testing.T) { got := T(EN, "сервер не запущен") if got != "the server is not running" { t.Fatalf("T(EN, ...) = %q", got) } if got := T(RU, "сервер не запущен"); got != "сервер не запущен" { t.Fatalf("русский язык не должен трогать сообщение: %q", got) } } // Вывод игрового сервера проходит через перевод как есть: словарь его не знает. func TestTKeepsUnknown(t *testing.T) { line := "LOG : General f:1 Zombies spawned: 1000" if got := T(EN, line); got != line { t.Fatalf("незнакомая строка изменена: %q", got) } } func TestTFormat(t *testing.T) { got := T(EN, `профиль "modded" не найден`) if got != `profile "modded" not found` { t.Fatalf("T = %q", got) } } // Вложенная ошибка переводится вместе с обёрткой, а более конкретный шаблон // («прочитать конфиг») должен выиграть у общего («прочитать»). func TestTNestedError(t *testing.T) { msg := "конфиг сервера недоступен: прочитать конфиг /srv/servertest.ini: open: no such file" want := "the server config is unavailable: read the config /srv/servertest.ini: open: no such file" if got := T(EN, msg); got != want { t.Fatalf("T = %q, ожидалось %q", got, want) } } func TestTTaskName(t *testing.T) { if got := T(EN, "Резервное копирование мира: modded"); got != "World backup: modded" { t.Fatalf("T = %q", got) } } // В переводе должно быть столько же подстановок, сколько в оригинале, иначе // Sprintf выведет %!s(MISSING) прямо в панель. func TestCatalogPlaceholders(t *testing.T) { for _, f := range formats { ru := strings.Count(f[0], "%s") en := strings.Count(f[1], "%s") if ru == 0 { t.Errorf("шаблон без подстановки: %q", f[0]) } if ru != en { t.Errorf("%q: подстановок %d, в переводе %d", f[0], ru, en) } if strings.ContainsAny(strings.ReplaceAll(f[0], "%s", ""), "%") { t.Errorf("в шаблоне остался другой глагол форматирования: %q", f[0]) } } for ru, en := range messages { if strings.Contains(ru, "%") || strings.Contains(en, "%") { t.Errorf("сообщение с подстановкой должно лежать в formats: %q", ru) } } } func TestFromRequest(t *testing.T) { cases := []struct { name string cookie string header string want Lang }{ {"по умолчанию", "", "", Default}, {"выбор человека", "en", "ru-RU,ru;q=0.9", EN}, {"мусор в куке", "klingon", "en-US,en;q=0.9", EN}, {"язык браузера", "", "en-GB,en;q=0.9", EN}, {"неизвестный язык браузера", "", "de-DE,de;q=0.9", Default}, {"первый понятный из списка", "", "de-DE;q=0.9,en;q=0.8", EN}, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { r, err := http.NewRequest(http.MethodGet, "/api/status", nil) if err != nil { t.Fatal(err) } if c.cookie != "" { r.AddCookie(&http.Cookie{Name: CookieName, Value: c.cookie}) } if c.header != "" { r.Header.Set("Accept-Language", c.header) } if got := FromRequest(r); got != c.want { t.Fatalf("FromRequest = %q, ожидалось %q", got, c.want) } }) } }