From c0dafc927dc2631aeed995ff06281bb08f1e8f8c Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 09:03:26 +0000 Subject: [PATCH] fix(i18n): preserve fallback translations in empty handlers Co-Authored-By: Virgil --- handler.go | 50 ++++++++++++++++++++++++++++++++++++++++++------- handler_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/handler.go b/handler.go index e244edc..f209692 100644 --- a/handler.go +++ b/handler.go @@ -16,7 +16,13 @@ func (h LabelHandler) Match(key string) bool { func (h LabelHandler) Handle(key string, args []any, next func() string) string { word := core.TrimPrefix(key, "i18n.label.") - return Label(word) + if got := Label(word); got != "" { + return got + } + if next != nil { + return next() + } + return "" } // ProgressHandler handles i18n.progress.{verb} -> "Building..." patterns. @@ -30,10 +36,18 @@ func (h ProgressHandler) Handle(key string, args []any, next func() string) stri verb := core.TrimPrefix(key, "i18n.progress.") if len(args) > 0 { if subj := subjectArgText(args[0]); subj != "" { - return ProgressSubject(verb, subj) + if got := ProgressSubject(verb, subj); got != "" { + return got + } } } - return Progress(verb) + if got := Progress(verb); got != "" { + return got + } + if next != nil { + return next() + } + return "" } // CountHandler handles i18n.count.{noun} -> "5 files" patterns. @@ -46,6 +60,12 @@ func (h CountHandler) Match(key string) bool { func (h CountHandler) Handle(key string, args []any, next func() string) string { noun := core.TrimPrefix(key, "i18n.count.") lang := currentLangForGrammar() + if core.Trim(noun) == "" { + if next != nil { + return next() + } + return "" + } if len(args) > 0 { count := getCount(args[0]) return core.Sprintf("%s %s", FormatNumber(int64(count)), countWordForm(lang, noun, count)) @@ -64,10 +84,18 @@ func (h DoneHandler) Handle(key string, args []any, next func() string) string { verb := core.TrimPrefix(key, "i18n.done.") if len(args) > 0 { if subj := subjectArgText(args[0]); subj != "" { - return ActionResult(verb, subj) + if got := ActionResult(verb, subj); got != "" { + return got + } } } - return Title(PastTense(verb)) + if got := Title(PastTense(verb)); got != "" { + return got + } + if next != nil { + return next() + } + return "" } // FailHandler handles i18n.fail.{verb} -> "Failed to delete file" patterns. @@ -81,10 +109,18 @@ func (h FailHandler) Handle(key string, args []any, next func() string) string { verb := core.TrimPrefix(key, "i18n.fail.") if len(args) > 0 { if subj := subjectArgText(args[0]); subj != "" { - return ActionFailed(verb, subj) + if got := ActionFailed(verb, subj); got != "" { + return got + } } } - return ActionFailed(verb, "") + if got := ActionFailed(verb, ""); got != "" { + return got + } + if next != nil { + return next() + } + return "" } // NumericHandler handles i18n.numeric.{format} -> formatted numbers. diff --git a/handler_test.go b/handler_test.go index 2b7b473..286dbb0 100644 --- a/handler_test.go +++ b/handler_test.go @@ -22,6 +22,11 @@ func TestLabelHandler(t *testing.T) { if got != "Status:" { t.Errorf("LabelHandler.Handle(status) = %q, want %q", got, "Status:") } + + got = h.Handle("i18n.label.", nil, func() string { return "fallback" }) + if got != "fallback" { + t.Errorf("LabelHandler.Handle(empty) = %q, want %q", got, "fallback") + } } func TestProgressHandler(t *testing.T) { @@ -68,6 +73,11 @@ func TestProgressHandler(t *testing.T) { if got != "Building project..." { t.Errorf("ProgressHandler.Handle(build, map[string]string[Subject:project]) = %q, want %q", got, "Building project...") } + + got = h.Handle("i18n.progress.", nil, func() string { return "fallback" }) + if got != "fallback" { + t.Errorf("ProgressHandler.Handle(empty) = %q, want %q", got, "fallback") + } } func TestCountHandler(t *testing.T) { @@ -117,6 +127,11 @@ func TestCountHandler(t *testing.T) { if got != "3 files" { t.Errorf("CountHandler.Handle(file, TranslationContext.Count=3) = %q, want %q", got, "3 files") } + + got = h.Handle("i18n.count.", nil, func() string { return "fallback" }) + if got != "fallback" { + t.Errorf("CountHandler.Handle(empty) = %q, want %q", got, "fallback") + } } func TestDoneHandler(t *testing.T) { @@ -163,6 +178,11 @@ func TestDoneHandler(t *testing.T) { if got != "Deleted" { t.Errorf("DoneHandler.Handle(delete) = %q, want %q", got, "Deleted") } + + got = h.Handle("i18n.done.", nil, func() string { return "fallback" }) + if got != "fallback" { + t.Errorf("DoneHandler.Handle(empty) = %q, want %q", got, "fallback") + } } func TestFailHandler(t *testing.T) { @@ -201,6 +221,11 @@ func TestFailHandler(t *testing.T) { if got != "Failed to push" { t.Errorf("FailHandler.Handle(push) = %q, want %q", got, "Failed to push") } + + got = h.Handle("i18n.fail.", nil, func() string { return "fallback" }) + if got != "fallback" { + t.Errorf("FailHandler.Handle(empty) = %q, want %q", got, "fallback") + } } func TestNumericHandler(t *testing.T) { -- 2.45.3