Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Correctly apply inflection rules on multi-word strings. (Fixes #7132) #7134

Closed
wants to merge 2 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+35 −4
Split
@@ -312,12 +312,28 @@ def const_regexp(camel_cased_word) #:nodoc:
# apply_inflections("posts", inflections.singulars) # => "post"
def apply_inflections(word, rules)
result = word.to_s.dup
+ prefix, last_word = split_phrase(result)
- if word.empty? || inflections.uncountables.include?(result.downcase[/\b\w+\Z/])
+ if word.empty? || inflections.uncountables.include?(last_word.downcase)
result
else
- rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
- result
+ rules.each { |(rule, replacement)| break if last_word.sub!(rule, replacement) }
+ prefix + last_word
+ end
+ end
+
+ # Split a phrase into two chunks for +apply_inflections+:
+ # split_phrase('word') # => ['', 'word']
+ # split_phrase('two words') # => ['two ', 'words']
+ # split_phrase('two_words') # => ['two_', 'words']
+ # split_phrase('two-words') # => ['two-', 'words']
+ # split_phrase('myWord') # => ['my','Word']
+ # split_phrase('many many words') # => ['many many ','words']
+ def split_phrase(phrase)
+ if last_word = underscore(phrase)[/[a-z0-9]+\Z/i]
+ [phrase[0...-last_word.length], phrase[-last_word.length..-1]]
+ else
+ [phrase, '']
end
end
end
@@ -17,6 +17,18 @@ def test_pluralize_empty_string
assert_equal "", ActiveSupport::Inflector.pluralize("")
end
+ def test_pluralize_camel_case_string
+ assert_equal "camelCases", ActiveSupport::Inflector.pluralize("camelCase")
+ assert_equal "OpticalMice", ActiveSupport::Inflector.pluralize("OpticalMouse")
+ assert_equal "SawFish", ActiveSupport::Inflector.pluralize("SawFish")
+ end
+
+ def test_singularize_camel_case_string
+ assert_equal "camelCase", ActiveSupport::Inflector.singularize("camelCases")
+ assert_equal "OpticalMouse", ActiveSupport::Inflector.singularize("OpticalMice")
+ assert_equal "SawFish", ActiveSupport::Inflector.singularize("SawFish")
+ end
+
ActiveSupport::Inflector.inflections.uncountable.each do |word|
define_method "test_uncountability_of_#{word}" do
assert_equal word, ActiveSupport::Inflector.singularize(word)
@@ -15,6 +15,7 @@ module InflectorTestCases
"jeans" => "jeans",
"funky jeans" => "funky jeans",
"my money" => "my money",
+ "your mouse" => "your mice",
"category" => "categories",
"query" => "queries",
@@ -62,6 +63,9 @@ module InflectorTestCases
"old_news" => "old_news",
"news" => "news",
+ "funky_jeans" => "funky_jeans",
+ "stinky_fish" => "stinky_fish",
+
"series" => "series",
"species" => "species",
@@ -81,7 +85,6 @@ module InflectorTestCases
"status" => "statuses",
"status_code" => "status_codes",
"mouse" => "mice",
-
"louse" => "lice",
"house" => "houses",
"octopus" => "octopi",