v0.248.0: i18n slice 1 release A — apps and settings in English, Hungarian byte-identical (R-556)
gates / gates (push) Successful in 20s
gates / gates (push) Successful in 20s
Ten pages converted against fixtures captured from unconverted templates (6be55a0); marker
coverage test; English page mask narrowed; English retrieval-promise stems; common keys;
title keys and infraMeta from the bundle; old wording tests read the Hungarian expansion.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -35,6 +35,7 @@ import (
|
||||
// TestI18nParity fails naming the page and the first differing line.
|
||||
|
||||
var updateI18nGolden = flag.Bool("update-i18n-golden", false, "write MISSING testdata/i18n_parity fixtures from the current templates (an existing fixture is never overwritten)")
|
||||
var i18nDumpDir = flag.String("i18n-dump-dir", "", "TestI18nEnglishPages: also write every case's hu and en render to this directory (evidence, per-page review)")
|
||||
var i18nGoldenOnly = flag.String("i18n-golden-only", "", "with -update-i18n-golden: only cases whose name matches this regexp")
|
||||
|
||||
var relativeAgeRe = regexp.MustCompile(`\d+ (napja|órája|perce)`)
|
||||
@@ -52,6 +53,12 @@ func i18nFixtureTime() time.Time { return time.Date(2026, 9, 14, 3, 12, 0, 0, ti
|
||||
var i18nTitleKeys = map[string]string{
|
||||
"Indítópult": "page.title.launcher",
|
||||
"Biztonsági mentés": "page.title.backups",
|
||||
"Vezérlőpult": "page.title.dashboard",
|
||||
"Alkalmazások": "page.title.stacks",
|
||||
"Rendszermonitor": "page.title.monitoring",
|
||||
"Beállítások": "page.title.settings",
|
||||
"Értesítések": "page.title.settings_notifications",
|
||||
"Biztonság és hozzáférés": "page.title.settings_security",
|
||||
}
|
||||
|
||||
func i18nLayoutData(page, title string) map[string]interface{} {
|
||||
@@ -376,7 +383,7 @@ func fixtureStrings(v reflect.Value, out map[string]bool) {
|
||||
}
|
||||
}
|
||||
|
||||
var i18nKeyLikeRe = regexp.MustCompile(`\b(launcher|backups|backups_shared|app_info|layout|func)\.[a-z0-9_]+\b`)
|
||||
var i18nKeyLikeRe = regexp.MustCompile(`\b[a-z][a-z_]*\.[a-z0-9_.]+\b`)
|
||||
var emptyElemRe = regexp.MustCompile(`<(h[1-6]|button|label|li|strong|option|p)(\s[^>]*)?>\s*</(h[1-6]|button|label|li|strong|option|p)>`)
|
||||
|
||||
// TestI18nEnglishPages — the three pages in English: no Hungarian letter from the TEMPLATE copy, no
|
||||
@@ -395,14 +402,22 @@ func TestI18nEnglishPages(t *testing.T) {
|
||||
for _, c := range i18nCases() {
|
||||
hu := renderI18nCase(t, s, "hu", c)
|
||||
en := renderI18nCase(t, s, "en", c)
|
||||
if *i18nDumpDir != "" {
|
||||
_ = os.MkdirAll(*i18nDumpDir, 0o755)
|
||||
_ = os.WriteFile(filepath.Join(*i18nDumpDir, c.name+".hu.html"), []byte(hu), 0o644)
|
||||
_ = os.WriteFile(filepath.Join(*i18nDumpDir, c.name+".en.html"), []byte(en), 0o644)
|
||||
}
|
||||
if !huLetter(hu) {
|
||||
t.Fatalf("%s: positive control failed — the Hungarian render carries no Hungarian letter", c.name)
|
||||
}
|
||||
if strings.Contains(en, `{{T `) {
|
||||
t.Errorf("%s: an unexpanded marker reached the English page", c.name)
|
||||
}
|
||||
if m := i18nKeyLikeRe.FindString(en); m != "" && s.i18n.Has(i18n.Default, m) {
|
||||
t.Errorf("%s: a raw bundle key reached the English page: %q", c.name, m)
|
||||
for _, m := range i18nKeyLikeRe.FindAllString(en, -1) {
|
||||
if s.i18n.Has(i18n.Default, m) {
|
||||
t.Errorf("%s: a raw bundle key reached the English page: %q", c.name, m)
|
||||
break
|
||||
}
|
||||
}
|
||||
if a, b := len(emptyElemRe.FindAllString(hu, -1)), len(emptyElemRe.FindAllString(en, -1)); b > a {
|
||||
t.Errorf("%s: English has %d empty elements, Hungarian %d — a translation rendered blank", c.name, b, a)
|
||||
|
||||
Reference in New Issue
Block a user