From c9a262236db47513dafeb8b73f5c9b76bf0fd6d8 Mon Sep 17 00:00:00 2001 From: Evan O'Brien Date: Sat, 22 Nov 2025 13:50:27 +0000 Subject: [PATCH] Handle exceptions in plural? and singular? --- lib/exflect.ex | 4 ++-- lib/exflect/detect.ex | 21 +++++++++++++++++++-- test/exflect_test.exs | 12 ++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/exflect.ex b/lib/exflect.ex index e625303..ee0dea5 100644 --- a/lib/exflect.ex +++ b/lib/exflect.ex @@ -49,7 +49,7 @@ defmodule Exflect do match_style = Keyword.get(opts, :match_style, false) cond do - check && Exflect.Detect.singular?(text) -> text + check && (Exflect.Shared.uncountable?(text) || Exflect.Detect.singular?(text)) -> text true -> unchecked_singularize(text, match_style) end end @@ -104,7 +104,7 @@ defmodule Exflect do match_style = Keyword.get(opts, :match_style, false) cond do - check && Exflect.Detect.plural?(text) -> text + check && (Exflect.Shared.uncountable?(text) || Exflect.Detect.plural?(text)) -> text true -> unchecked_pluralize(text, match_style) end end diff --git a/lib/exflect/detect.ex b/lib/exflect/detect.ex index 08d1fb0..64337a8 100644 --- a/lib/exflect/detect.ex +++ b/lib/exflect/detect.ex @@ -64,6 +64,23 @@ defmodule Exflect.Detect do ~r/[^aouie]s$/ ] - def singular?(word), do: Enum.any?(@sg, &Regex.match?(&1, word)) || !plural?(word) - def plural?(word), do: Enum.any?(@pl, &Regex.match?(&1, word)) + @singular_exceptions Exflect.Shared.exceptions(:singularize) + @plural_exceptions Exflect.Shared.exceptions(:pluralize) + + for {word, _} <- @plural_exceptions do + def singular?(unquote(word)), do: true + end + + def singular?(word) do + Enum.any?(@sg, &Regex.match?(&1, word)) || + !plural?(word) + end + + for {word, _} <- @singular_exceptions do + def plural?(unquote(word)), do: true + end + + def plural?(word) do + Enum.any?(@pl, &Regex.match?(&1, word)) + end end diff --git a/test/exflect_test.exs b/test/exflect_test.exs index 0a4205b..02a4218 100644 --- a/test/exflect_test.exs +++ b/test/exflect_test.exs @@ -44,6 +44,18 @@ defmodule ExflectTest do assert(equal?(Exflect.singularize("bus", check: true), "bus")) end + test "exceptions" do + assert(Exflect.singular?("child")) + refute(Exflect.singular?("children")) + assert(Exflect.plural?("children")) + refute(Exflect.plural?("child")) + + assert(equal?(Exflect.pluralize("children", check: true), "children")) + assert(equal?(Exflect.singularize("children", check: true), "child")) + assert(equal?(Exflect.singularize("child", check: true), "child")) + assert(equal?(Exflect.pluralize("child", check: true), "children")) + end + @tag :benchmark test "benchmark" do %{