From 01bb75947c49520078c2e24e6b841388f0998b45 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 02:22:10 +0000 Subject: [PATCH] feat(handler): pluralise locale noun phrases Co-Authored-By: Virgil --- handler.go | 16 ++++++++++++++++ handler_test.go | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/handler.go b/handler.go index 5ce8b8a..50e46ca 100644 --- a/handler.go +++ b/handler.go @@ -134,6 +134,10 @@ func DefaultHandlers() []KeyHandler { } func countWordForm(lang, noun string, count int) string { + if hasGrammarCountForms(lang, noun) { + return Pluralize(noun, count) + } + display := renderWord(lang, noun) if display == "" { return Pluralize(noun, count) @@ -150,6 +154,18 @@ func countWordForm(lang, noun string, count int) string { return Pluralize(display, count) } +func hasGrammarCountForms(lang, noun string) bool { + data := GetGrammarData(lang) + if data == nil || len(data.Nouns) == 0 { + return false + } + forms, ok := data.Nouns[core.Lower(noun)] + if !ok { + return false + } + return forms.One != "" || forms.Other != "" +} + func isPluralisableWordDisplay(s string) bool { hasLetter := false for _, r := range s { diff --git a/handler_test.go b/handler_test.go index 5b2db91..acac1f1 100644 --- a/handler_test.go +++ b/handler_test.go @@ -287,6 +287,28 @@ func TestCountHandler_PreservesPhraseDisplay(t *testing.T) { } } +func TestCountHandler_PluralisesLocaleNounPhrases(t *testing.T) { + prev := Default() + svc, err := New() + if err != nil { + t.Fatalf("New() failed: %v", err) + } + SetDefault(svc) + t.Cleanup(func() { + SetDefault(prev) + }) + + if err := SetLanguage("fr"); err != nil { + t.Fatalf("SetLanguage(fr) failed: %v", err) + } + + h := CountHandler{} + got := h.Handle("i18n.count.mise à jour", []any{2}, nil) + if got != "2 mises à jour" { + t.Fatalf("CountHandler.Handle(mise à jour, 2) = %q, want %q", got, "2 mises à jour") + } +} + func TestRunHandlerChain(t *testing.T) { handlers := DefaultHandlers() fallback := func() string { return "missed" } -- 2.45.3