diff --git a/grammar.go b/grammar.go index fad5b7f..aeabf22 100644 --- a/grammar.go +++ b/grammar.go @@ -334,6 +334,18 @@ func applyRegularGerund(verb string) string { // Pluralize("child", 3) // "children" func Pluralize(noun string, count int) string { if count == 1 { + // Honour locale-provided singular forms before falling back to the input. + noun = core.Trim(noun) + if noun == "" { + return "" + } + lower := core.Lower(noun) + if form := getNounForm(currentLangForGrammar(), lower, "one"); form != "" { + if unicode.IsUpper(rune(noun[0])) && len(form) > 0 { + return core.Upper(string(form[0])) + form[1:] + } + return form + } return noun } return PluralForm(noun) diff --git a/grammar_test.go b/grammar_test.go index 14afdc2..5dfbac1 100644 --- a/grammar_test.go +++ b/grammar_test.go @@ -223,6 +223,35 @@ func TestPluralize(t *testing.T) { } } +func TestPluralize_UsesLocaleSingularOverride(t *testing.T) { + const lang = "en-x-singular" + prev := Default() + t.Cleanup(func() { + SetDefault(prev) + SetGrammarData(lang, nil) + }) + + svc, err := NewWithLoader(pluralizeOverrideLoader{}) + if err != nil { + t.Fatalf("NewWithLoader() failed: %v", err) + } + SetDefault(svc) + + if err := SetLanguage(lang); err != nil { + t.Fatalf("SetLanguage(%s) failed: %v", lang, err) + } + + if got, want := Pluralize("person", 1), "human"; got != want { + t.Fatalf("Pluralize(%q, 1) = %q, want %q", "person", got, want) + } + if got, want := Pluralize("Person", 1), "Human"; got != want { + t.Fatalf("Pluralize(%q, 1) = %q, want %q", "Person", got, want) + } + if got, want := Pluralize("person", 2), "people"; got != want { + t.Fatalf("Pluralize(%q, 2) = %q, want %q", "person", got, want) + } +} + func TestPluralForm(t *testing.T) { svc, err := New() if err != nil { @@ -320,6 +349,22 @@ func TestArticleFrenchLocale(t *testing.T) { } } +type pluralizeOverrideLoader struct{} + +func (pluralizeOverrideLoader) Languages() []string { + return []string{"en-x-singular"} +} + +func (pluralizeOverrideLoader) Load(lang string) (map[string]Message, *GrammarData, error) { + grammar := &GrammarData{ + Nouns: map[string]NounForms{ + "person": {One: "human", Other: "people"}, + }, + } + SetGrammarData(lang, grammar) + return map[string]Message{}, grammar, nil +} + func TestTitle(t *testing.T) { tests := []struct { input string