mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add acronym support to Inflector; Issue #1366
This commit is contained in:
parent
51cd6bb829
commit
d38ca78dbd
4 changed files with 105 additions and 11 deletions
|
@ -20,10 +20,10 @@ module ActiveSupport
|
|||
@__instance__ ||= new
|
||||
end
|
||||
|
||||
attr_reader :plurals, :singulars, :uncountables, :humans
|
||||
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
|
||||
|
||||
def initialize
|
||||
@plurals, @singulars, @uncountables, @humans, @acronyms = [], [], [], [], []
|
||||
@plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
|
||||
end
|
||||
|
||||
# Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore
|
||||
|
@ -73,7 +73,8 @@ module ActiveSupport
|
|||
# underscore 'McDonald' #=> 'mcdonald'
|
||||
# camelize 'mcdonald' #=> 'McDonald'
|
||||
def acronym(word)
|
||||
@acronyms.unshift(word)
|
||||
@acronyms[word.downcase] = word
|
||||
@acronym_regex = /#{@acronyms.values.join("|")}/
|
||||
end
|
||||
|
||||
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
||||
|
|
|
@ -65,12 +65,14 @@ module ActiveSupport
|
|||
# though there are cases where that does not hold:
|
||||
#
|
||||
# "SSLError".underscore.camelize # => "SslError"
|
||||
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
||||
if first_letter_in_uppercase
|
||||
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
||||
def camelize(term, uppercase_first_letter = true)
|
||||
string = term.to_s
|
||||
if uppercase_first_letter
|
||||
string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
|
||||
else
|
||||
lower_case_and_underscored_word.to_s[0].chr.downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
||||
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
||||
end
|
||||
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
|
||||
end
|
||||
|
||||
# Makes an underscored, lowercase form from the expression in the string.
|
||||
|
@ -88,7 +90,8 @@ module ActiveSupport
|
|||
def underscore(camel_cased_word)
|
||||
word = camel_cased_word.to_s.dup
|
||||
word.gsub!(/::/, '/')
|
||||
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
||||
word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
|
||||
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
||||
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
||||
word.tr!("-", "_")
|
||||
word.downcase!
|
||||
|
@ -103,9 +106,9 @@ module ActiveSupport
|
|||
# "author_id" # => "Author"
|
||||
def humanize(lower_case_and_underscored_word)
|
||||
result = lower_case_and_underscored_word.to_s.dup
|
||||
|
||||
inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
||||
result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
|
||||
result.gsub!(/_id$/, "")
|
||||
result.gsub(/(_)?([a-z\d]*)/i) { "#{$1 && ' '}#{inflections.acronyms[$2] || $2.downcase}" }.gsub(/^\w/) { $&.upcase }
|
||||
end
|
||||
|
||||
# Capitalizes all the words and replaces some characters in the string to create
|
||||
|
|
|
@ -94,6 +94,88 @@ class InflectorTest < Test::Unit::TestCase
|
|||
assert_equal('capital', ActiveSupport::Inflector.camelize('Capital', false))
|
||||
end
|
||||
|
||||
def test_camelize_with_underscores
|
||||
assert_equal("CamelCase", ActiveSupport::Inflector.camelize('Camel_Case'))
|
||||
end
|
||||
|
||||
def test_acronyms
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.acronym("API")
|
||||
inflect.acronym("HTML")
|
||||
inflect.acronym("HTTP")
|
||||
inflect.acronym("RESTful")
|
||||
inflect.acronym("W3C")
|
||||
inflect.acronym("PhD")
|
||||
inflect.acronym("RoR")
|
||||
inflect.acronym("SSL")
|
||||
end
|
||||
|
||||
# camelize underscore humanize titleize
|
||||
[
|
||||
["API", "api", "API", "API"],
|
||||
["APIController", "api_controller", "API controller", "API Controller"],
|
||||
["Nokogiri::HTML", "nokogiri/html", "Nokogiri/HTML", "Nokogiri/HTML"],
|
||||
["HTTPAPI", "http_api", "HTTP API", "HTTP API"],
|
||||
["HTTP::Get", "http/get", "HTTP/get", "HTTP/Get"],
|
||||
["SSLError", "ssl_error", "SSL error", "SSL Error"],
|
||||
["RESTful", "restful", "RESTful", "RESTful"],
|
||||
["RESTfulController", "restful_controller", "RESTful controller", "RESTful Controller"],
|
||||
["IHeartW3C", "i_heart_w3c", "I heart W3C", "I Heart W3C"],
|
||||
["PhDRequired", "phd_required", "PhD required", "PhD Required"],
|
||||
["IRoRU", "i_ror_u", "I RoR u", "I RoR U"],
|
||||
["RESTfulHTTPAPI", "restful_http_api", "RESTful HTTP API", "RESTful HTTP API"],
|
||||
|
||||
# misdirection
|
||||
["Capistrano", "capistrano", "Capistrano", "Capistrano"],
|
||||
["CapiController", "capi_controller", "Capi controller", "Capi Controller"],
|
||||
["HttpsApis", "https_apis", "Https apis", "Https Apis"],
|
||||
["Html5", "html5", "Html5", "Html5"],
|
||||
["Restfully", "restfully", "Restfully", "Restfully"],
|
||||
["RoRails", "ro_rails", "Ro rails", "Ro Rails"]
|
||||
].each do |camel, under, human, title|
|
||||
assert_equal(camel, ActiveSupport::Inflector.camelize(under))
|
||||
assert_equal(camel, ActiveSupport::Inflector.camelize(camel))
|
||||
assert_equal(under, ActiveSupport::Inflector.underscore(under))
|
||||
assert_equal(under, ActiveSupport::Inflector.underscore(camel))
|
||||
assert_equal(title, ActiveSupport::Inflector.titleize(under))
|
||||
assert_equal(title, ActiveSupport::Inflector.titleize(camel))
|
||||
assert_equal(human, ActiveSupport::Inflector.humanize(under))
|
||||
end
|
||||
end
|
||||
|
||||
def test_acronym_override
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.acronym("API")
|
||||
inflect.acronym("LegacyApi")
|
||||
end
|
||||
|
||||
assert_equal("LegacyApi", ActiveSupport::Inflector.camelize("legacyapi"))
|
||||
assert_equal("LegacyAPI", ActiveSupport::Inflector.camelize("legacy_api"))
|
||||
assert_equal("SomeLegacyApi", ActiveSupport::Inflector.camelize("some_legacyapi"))
|
||||
assert_equal("Nonlegacyapi", ActiveSupport::Inflector.camelize("nonlegacyapi"))
|
||||
end
|
||||
|
||||
def test_acronyms_camelize_lower
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.acronym("API")
|
||||
inflect.acronym("HTML")
|
||||
end
|
||||
|
||||
assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("html_api", false))
|
||||
assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("htmlAPI", false))
|
||||
assert_equal("htmlAPI", ActiveSupport::Inflector.camelize("HTMLAPI", false))
|
||||
end
|
||||
|
||||
def test_underscore_acronym_sequence
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.acronym("API")
|
||||
inflect.acronym("HTML5")
|
||||
inflect.acronym("HTML")
|
||||
end
|
||||
|
||||
assert_equal("html5_html_api", ActiveSupport::Inflector.underscore("HTML5HTMLAPI"))
|
||||
end
|
||||
|
||||
def test_underscore
|
||||
CamelToUnderscore.each do |camel, underscore|
|
||||
assert_equal(underscore, ActiveSupport::Inflector.underscore(camel))
|
||||
|
|
|
@ -1460,7 +1460,15 @@ end
|
|||
|
||||
That may be handy to compute method names in a language that follows that convention, for example JavaScript.
|
||||
|
||||
INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>.
|
||||
INFO: As a rule of thumb you can think of +camelize+ as the inverse of +underscore+, though there are cases where that does not hold: <tt>"SSLError".underscore.camelize</tt> gives back <tt>"SslError"</tt>. To support cases such as this, Active Support allows you to specify acronyms in +config/initializers/inflections.rb+:
|
||||
|
||||
<ruby>
|
||||
ActiveSupport::Inflector.inflections do |inflect|
|
||||
inflect.acronym 'SSL'
|
||||
end
|
||||
|
||||
"SSLError".underscore.camelize #=> "SSLError"
|
||||
</ruby>
|
||||
|
||||
+camelize+ is aliased to +camelcase+.
|
||||
|
||||
|
|
Loading…
Reference in a new issue