fix(i18n): preserve exact word displays in counts
All checks were successful
Security Scan / security (push) Successful in 11s
Test / test (push) Successful in 1m26s

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 23:49:34 +00:00
parent 5511aba529
commit 2f0f4c3f75
2 changed files with 46 additions and 0 deletions

View file

@ -140,12 +140,30 @@ func countWordForm(lang, noun string, count int) string {
if count == 1 {
return display
}
if !isPluralisableWordDisplay(display) {
return display
}
if isUpperAcronymPlural(display) {
return display
}
return Pluralize(display, count)
}
func isPluralisableWordDisplay(s string) bool {
hasLetter := false
for _, r := range s {
switch {
case unicode.IsLetter(r):
hasLetter = true
case unicode.IsSpace(r):
continue
default:
return false
}
}
return hasLetter
}
func isUpperAcronymPlural(s string) bool {
if len(s) < 2 || !strings.HasSuffix(s, "s") {
return false

View file

@ -196,6 +196,34 @@ func TestCountHandler_UsesLocaleNumberFormat(t *testing.T) {
}
}
func TestCountHandler_PreservesExactWordDisplay(t *testing.T) {
svc, err := New()
if err != nil {
t.Fatalf("New() failed: %v", err)
}
SetDefault(svc)
data := GetGrammarData("en")
if data == nil {
t.Fatal("GetGrammarData(\"en\") returned nil")
}
original, existed := data.Words["go_mod"]
data.Words["go_mod"] = "go.mod"
t.Cleanup(func() {
if existed {
data.Words["go_mod"] = original
return
}
delete(data.Words, "go_mod")
})
h := CountHandler{}
got := h.Handle("i18n.count.go_mod", []any{2}, nil)
if got != "2 go.mod" {
t.Fatalf("CountHandler.Handle(go_mod, 2) = %q, want %q", got, "2 go.mod")
}
}
func TestRunHandlerChain(t *testing.T) {
handlers := DefaultHandlers()
fallback := func() string { return "missed" }