v0.247.0: i18n spike — the dashboard can speak English, Hungarian byte-identical
gates / gates (push) Successful in 19s

Message bundles (internal/i18n) expanded into templates before parsing, one
template set per language. Launcher, /backups, /apps/<slug> and the layout
converted; household language setting, POST /settings/language, ?lang= override,
report field. Parity test against fixtures captured from unconverted templates;
copy gates read templates expanded; new i18n_missing_gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-17 14:50:57 +02:00
parent 89dd3e94b1
commit 612c417024
49 changed files with 11734 additions and 248 deletions
@@ -13,11 +13,11 @@ import (
"sort"
"strings"
"testing"
"text/template"
"time"
"gitea.dooplex.hu/admin/felhom-controller/internal/agentapi"
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
"gitea.dooplex.hu/admin/felhom-controller/internal/i18n"
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
"gitea.dooplex.hu/admin/felhom-controller/internal/stacks"
)
@@ -26,8 +26,20 @@ import (
// cleanups) to parse — they are otherwise only parsed at server startup (template.Must).
func TestTemplatesParse(t *testing.T) {
s := &Server{}
if _, err := template.New("").Funcs(s.templateFuncMap()).ParseFS(templateFS, "templates/*.html"); err != nil {
t.Fatalf("templates parse: %v", err)
// v0.247.0: templates carry {{T}} markers and are parsed per language after i18n expansion — the
// production path is parseTemplateSet, so parse exactly that, for every supported language.
b, err := i18n.Shared()
if err != nil {
t.Fatal(err)
}
for _, lang := range i18n.Supported {
funcs := s.templateFuncMap()
for n, fn := range s.localeFuncs(lang) {
funcs[n] = fn
}
if _, _, err := parseTemplateSet(b, lang, funcs); err != nil {
t.Fatalf("templates (%s) parse: %v", lang, err)
}
}
}